mirror of
https://github.com/DCFApixels/DragonECS.git
synced 2025-09-18 18:14:37 +08:00
Impl Thread Safety for static methods in EcsWorld
This commit is contained in:
parent
44a8894d65
commit
effa02e660
@ -133,6 +133,8 @@ namespace DCFApixels.DragonECS
|
||||
#region Constructors/Destroy
|
||||
public EcsWorld(EcsWorldConfig config, short worldID = -1) : this(config == null ? ConfigContainer.Empty : new ConfigContainer().Set(config), worldID) { }
|
||||
public EcsWorld(IConfigContainer configs = null, short worldID = -1)
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
if (configs == null) { configs = ConfigContainer.Empty; }
|
||||
bool nullWorld = this is NullWorld;
|
||||
@ -175,7 +177,10 @@ namespace DCFApixels.DragonECS
|
||||
|
||||
GetComponentTypeID<NullComponent>();
|
||||
}
|
||||
}
|
||||
public void Destroy()
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
if (_isDestroyed)
|
||||
{
|
||||
@ -206,6 +211,7 @@ namespace DCFApixels.DragonECS
|
||||
}
|
||||
//_entities - не обнуляется для работы entlong.IsAlive
|
||||
}
|
||||
}
|
||||
//public void Clear() { }
|
||||
#endregion
|
||||
|
||||
|
@ -26,29 +26,30 @@ namespace DCFApixels.DragonECS
|
||||
private const int DEL_ENT_BUFFER_MIN_SIZE = 64;
|
||||
|
||||
private static EcsWorld[] _worlds = Array.Empty<EcsWorld>();
|
||||
private static IdDispenser _worldIdDispenser = new IdDispenser(4, 0, OnWorldIdDispenser);
|
||||
private static IdDispenser _worldIdDispenser = new IdDispenser(4, 0, n => Array.Resize(ref _worlds, n));
|
||||
|
||||
private static List<DataReleaser> _dataReleaseres = new List<DataReleaser>();
|
||||
//public static int Copacity => Worlds.Length;
|
||||
|
||||
private static readonly object _lock = new object();
|
||||
|
||||
static EcsWorld()
|
||||
{
|
||||
_worlds[NULL_WORLD_ID] = new NullWorld();
|
||||
}
|
||||
private static void ReleaseData(int worldID)
|
||||
{// ts
|
||||
lock (_lock)
|
||||
{
|
||||
for (int i = 0, iMax = _dataReleaseres.Count; i < iMax; i++)
|
||||
{
|
||||
_dataReleaseres[i].Release(worldID);
|
||||
}
|
||||
}
|
||||
public static void OnWorldIdDispenser(int newSize)
|
||||
{
|
||||
Array.Resize(ref _worlds, newSize);
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static EcsWorld GetWorld(short worldID)
|
||||
{
|
||||
{// ts
|
||||
return _worlds[worldID];
|
||||
}
|
||||
|
||||
@ -63,6 +64,7 @@ namespace DCFApixels.DragonECS
|
||||
return ref WorldComponentPool<T>.GetForWorldUnchecked(worldID);
|
||||
}
|
||||
|
||||
|
||||
private abstract class DataReleaser
|
||||
{
|
||||
public abstract void Release(int worldID);
|
||||
@ -76,32 +78,45 @@ namespace DCFApixels.DragonECS
|
||||
private static short _recycledItemsCount;
|
||||
private static IEcsWorldComponent<T> _interface = EcsWorldComponentHandler<T>.instance;
|
||||
|
||||
private static readonly object _lock = new object();
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static ref T Get(int itemIndex)
|
||||
{
|
||||
{// ts
|
||||
return ref _items[itemIndex];
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static ref T GetForWorld(int worldID)
|
||||
{
|
||||
int index = GetItemIndex(worldID);
|
||||
return ref _items[index];
|
||||
{// зависит от GetItemIndex
|
||||
return ref Get(GetItemIndex(worldID));
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static ref T GetForWorldUnchecked(int worldID)
|
||||
{
|
||||
#if (DEBUG && !DISABLE_DEBUG)
|
||||
{// ts
|
||||
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
|
||||
if (_mapping[worldID] <= 0) { Throw.UndefinedException(); }
|
||||
#endif
|
||||
return ref _items[_mapping[worldID]];
|
||||
}
|
||||
public static int GetItemIndex(int worldID)
|
||||
{// ts
|
||||
if (_mapping.Length < _worlds.Length)
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
if (_mapping.Length < _worlds.Length)
|
||||
{
|
||||
Array.Resize(ref _mapping, _worlds.Length);
|
||||
}
|
||||
ref short itemIndex = ref _mapping[worldID];
|
||||
}
|
||||
}
|
||||
short itemIndex = _mapping[worldID];
|
||||
|
||||
if (itemIndex == 0)
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
itemIndex = _mapping[worldID];
|
||||
if (itemIndex <= 0)
|
||||
{
|
||||
if (_recycledItemsCount > 0)
|
||||
@ -113,6 +128,8 @@ namespace DCFApixels.DragonECS
|
||||
{
|
||||
itemIndex = ++_count;
|
||||
}
|
||||
_mapping[worldID] = itemIndex;
|
||||
|
||||
if (_items.Length <= itemIndex)
|
||||
{
|
||||
Array.Resize(ref _items, _items.Length << 1);
|
||||
@ -120,9 +137,13 @@ namespace DCFApixels.DragonECS
|
||||
_interface.Init(ref _items[itemIndex], _worlds[worldID]);
|
||||
_dataReleaseres.Add(new Releaser());
|
||||
}
|
||||
}
|
||||
}
|
||||
return itemIndex;
|
||||
}
|
||||
private static void Release(int worldID)
|
||||
{// ts
|
||||
lock (_lock)
|
||||
{
|
||||
if (_mapping.Length < _worlds.Length)
|
||||
{
|
||||
@ -136,6 +157,7 @@ namespace DCFApixels.DragonECS
|
||||
itemIndex = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
private sealed class Releaser : DataReleaser
|
||||
{
|
||||
public sealed override void Release(int worldID)
|
||||
|
Loading…
Reference in New Issue
Block a user