Make collections thread-safe for AI and character systems

Refactored various collections (lists, dictionaries, queues, and caches) in AI, character, animation, and item component systems to use thread-safe patterns and concurrent data structures. This includes introducing copy-on-write wrappers, ConcurrentDictionary, ConcurrentQueue, and ThreadLocal where appropriate to ensure safe concurrent access and mutation, improving stability in multi-threaded scenarios.
This commit is contained in:
Eero
2025-12-28 12:53:10 +08:00
parent 46595b1399
commit 31812d524d
12 changed files with 281 additions and 122 deletions
@@ -1,13 +1,67 @@
using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Xml.Linq;
namespace Barotrauma
{
/// <summary>
/// Thread-safe wrapper for AITarget list operations.
/// Uses copy-on-write pattern for lock-free reads.
/// </summary>
class ThreadSafeAITargetList : IEnumerable<AITarget>
{
private volatile List<AITarget> _list = new List<AITarget>();
private readonly object _writeLock = new object();
public int Count => _list.Count;
public void Add(AITarget target)
{
lock (_writeLock)
{
var newList = new List<AITarget>(_list) { target };
Interlocked.Exchange(ref _list, newList);
}
}
public bool Remove(AITarget target)
{
lock (_writeLock)
{
var newList = new List<AITarget>(_list);
bool removed = newList.Remove(target);
if (removed)
{
Interlocked.Exchange(ref _list, newList);
}
return removed;
}
}
public void Clear()
{
Interlocked.Exchange(ref _list, new List<AITarget>());
}
public bool Contains(AITarget target) => _list.Contains(target);
public AITarget this[int index] => _list[index];
public IEnumerator<AITarget> GetEnumerator() => _list.GetEnumerator();
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => GetEnumerator();
public List<AITarget> ToList() => new List<AITarget>(_list);
public AITarget FirstOrDefault(Func<AITarget, bool> predicate) => _list.FirstOrDefault(predicate);
public IEnumerable<AITarget> Where(Func<AITarget, bool> predicate) => _list.Where(predicate);
public bool Any(Func<AITarget, bool> predicate) => _list.Any(predicate);
}
partial class AITarget
{
public static List<AITarget> List = new List<AITarget>();
public static ThreadSafeAITargetList List = new ThreadSafeAITargetList();
private Entity entity;
public Entity Entity