mirror of
https://github.com/DCFApixels/DragonECS.git
synced 2025-09-18 18:14:37 +08:00
update world components
This commit is contained in:
parent
4f98009256
commit
aea6c75ad6
@ -8,6 +8,7 @@ namespace DCFApixels.DragonECS
|
|||||||
public interface IEcsWorldComponent<T>
|
public interface IEcsWorldComponent<T>
|
||||||
{
|
{
|
||||||
void Init(ref T component, EcsWorld world);
|
void Init(ref T component, EcsWorld world);
|
||||||
|
void OnDestroy(ref T component, EcsWorld world);
|
||||||
}
|
}
|
||||||
public static class EcsWorldComponentHandler<T>
|
public static class EcsWorldComponentHandler<T>
|
||||||
{
|
{
|
||||||
@ -30,6 +31,7 @@ namespace DCFApixels.DragonECS
|
|||||||
{
|
{
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public void Init(ref T component, EcsWorld world) { }
|
public void Init(ref T component, EcsWorld world) { }
|
||||||
|
public void OnDestroy(ref T component, EcsWorld world) { }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
internal class WorldComponentHandler<T> : IEcsWorldComponent<T>
|
internal class WorldComponentHandler<T> : IEcsWorldComponent<T>
|
||||||
@ -38,6 +40,7 @@ namespace DCFApixels.DragonECS
|
|||||||
private T _fakeInstnace;
|
private T _fakeInstnace;
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public void Init(ref T component, EcsWorld world) => _fakeInstnace.Init(ref component, world);
|
public void Init(ref T component, EcsWorld world) => _fakeInstnace.Init(ref component, world);
|
||||||
|
public void OnDestroy(ref T component, EcsWorld world) => _fakeInstnace.OnDestroy(ref component, world);
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
@ -4,9 +4,18 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace DCFApixels.DragonECS
|
namespace DCFApixels.DragonECS
|
||||||
{
|
{
|
||||||
|
[StructLayout(LayoutKind.Sequential, Pack = 4, Size = 4)]
|
||||||
|
public struct EcsWorldDataRef<T> where T : struct
|
||||||
|
{
|
||||||
|
private int _worldID;
|
||||||
|
public EcsWorldDataRef(int worldID) => _worldID = worldID;
|
||||||
|
public EcsWorld World => EcsWorld.GetWorld(_worldID);
|
||||||
|
public ref T Inst => ref EcsWorld.GetData<T>(_worldID);
|
||||||
|
}
|
||||||
public abstract partial class EcsWorld
|
public abstract partial class EcsWorld
|
||||||
{
|
{
|
||||||
private const short GEN_BITS = 0x7fff;
|
private const short GEN_BITS = 0x7fff;
|
||||||
@ -16,21 +25,41 @@ namespace DCFApixels.DragonECS
|
|||||||
internal static EcsWorld[] Worlds = new EcsWorld[4];
|
internal static EcsWorld[] Worlds = new EcsWorld[4];
|
||||||
private static IntDispenser _worldIdDispenser = new IntDispenser(0);
|
private static IntDispenser _worldIdDispenser = new IntDispenser(0);
|
||||||
|
|
||||||
|
private static List<DataReleaser> _dataReleaseres = new List<DataReleaser>();
|
||||||
|
|
||||||
|
|
||||||
static EcsWorld()
|
static EcsWorld()
|
||||||
{
|
{
|
||||||
Worlds[0] = new EcsNullWorld();
|
Worlds[0] = new EcsNullWorld();
|
||||||
}
|
}
|
||||||
|
private static void ReleaseData(int worldID)
|
||||||
|
{
|
||||||
|
for (int i = 0, iMax = _dataReleaseres.Count; i < iMax; i++)
|
||||||
|
_dataReleaseres[i].Release(worldID);
|
||||||
|
}
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static EcsWorld GetWorld(int worldID) => Worlds[worldID];
|
public static EcsWorld GetWorld(int worldID) => Worlds[worldID];
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static ref T GetData<T>(int worldID) => ref WorldComponentPool<T>.GetForWorld(worldID);
|
||||||
|
|
||||||
|
private abstract class DataReleaser
|
||||||
|
{
|
||||||
|
public abstract void Release(int worldID);
|
||||||
|
}
|
||||||
private static class WorldComponentPool<T>
|
private static class WorldComponentPool<T>
|
||||||
{
|
{
|
||||||
private static T[] _items = new T[4];
|
private static T[] _items = new T[4];
|
||||||
private static int[] _mapping = new int[4];
|
private static int[] _mapping = new int[4];
|
||||||
private static int _count;
|
private static int _count;
|
||||||
|
private static int[] _recycledItems = new int[4];
|
||||||
|
private static int _recycledItemsCount;
|
||||||
private static IEcsWorldComponent<T> _interface = EcsWorldComponentHandler<T>.instance;
|
private static IEcsWorldComponent<T> _interface = EcsWorldComponentHandler<T>.instance;
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static ref T Get(int itemIndex) => ref _items[itemIndex];
|
public static ref T Get(int itemIndex) => ref _items[itemIndex];
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static ref T GetForWorld(int worldID) => ref _items[GetItemIndex(worldID)];
|
||||||
public static int GetItemIndex(int worldID)
|
public static int GetItemIndex(int worldID)
|
||||||
{
|
{
|
||||||
if (_mapping.Length < Worlds.Length)
|
if (_mapping.Length < Worlds.Length)
|
||||||
@ -39,13 +68,36 @@ namespace DCFApixels.DragonECS
|
|||||||
ref int itemIndex = ref _mapping[worldID];
|
ref int itemIndex = ref _mapping[worldID];
|
||||||
if (itemIndex <= 0)
|
if (itemIndex <= 0)
|
||||||
{
|
{
|
||||||
itemIndex = ++_count;
|
if(_recycledItemsCount > 0)
|
||||||
|
{
|
||||||
|
_count++;
|
||||||
|
itemIndex = _recycledItems[--_recycledItemsCount];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
itemIndex = ++_count;
|
||||||
|
}
|
||||||
_interface.Init(ref _items[itemIndex], Worlds[worldID]);
|
_interface.Init(ref _items[itemIndex], Worlds[worldID]);
|
||||||
|
_dataReleaseres.Add(new Releaser());
|
||||||
}
|
}
|
||||||
return itemIndex;
|
return itemIndex;
|
||||||
}
|
}
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
private static void Release(int worldID)
|
||||||
public static ref T GetForWorld(int worldID) => ref _items[GetItemIndex(worldID)];
|
{
|
||||||
|
ref int itemIndex = ref _mapping[worldID];
|
||||||
|
if(itemIndex != 0)
|
||||||
|
{
|
||||||
|
_interface.OnDestroy(ref _items[itemIndex], Worlds[worldID]);
|
||||||
|
_recycledItems[_recycledItemsCount++] = itemIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private sealed class Releaser : DataReleaser
|
||||||
|
{
|
||||||
|
public sealed override void Release(int worldID)
|
||||||
|
{
|
||||||
|
WorldComponentPool<T>.Release(worldID);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public abstract partial class EcsWorld
|
public abstract partial class EcsWorld
|
||||||
@ -127,6 +179,7 @@ namespace DCFApixels.DragonECS
|
|||||||
_subjects = null;
|
_subjects = null;
|
||||||
_executors = null;
|
_executors = null;
|
||||||
Worlds[id] = null;
|
Worlds[id] = null;
|
||||||
|
ReleaseData(id);
|
||||||
_worldIdDispenser.Release(id);
|
_worldIdDispenser.Release(id);
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
@ -183,7 +236,7 @@ namespace DCFApixels.DragonECS
|
|||||||
}
|
}
|
||||||
return (TExecutor)result;
|
return (TExecutor)result;
|
||||||
}
|
}
|
||||||
public ref T GetComponent<T>() where T : struct => ref WorldComponentPool<T>.GetForWorld(id);
|
public ref T Get<T>() where T : struct => ref WorldComponentPool<T>.GetForWorld(id);
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Where Query
|
#region Where Query
|
||||||
|
Loading…
Reference in New Issue
Block a user