From 3fa030e95df30021d17eefe447e2b251cf970f49 Mon Sep 17 00:00:00 2001 From: Mikhail <99481254+DCFApixels@users.noreply.github.com> Date: Tue, 23 May 2023 15:58:31 +0800 Subject: [PATCH] remove Pipeline from EcsWorld & add event subscription --- src/EcsWorld.cs | 82 ++++++++++++++++++++++++------------- src/Pools/EcsAttachPool.cs | 26 +++++++++--- src/Pools/EcsNotNullPool.cs | 21 ++++++++-- src/Pools/EcsPool.cs | 30 ++++++++++---- src/Pools/EcsPoolBase.cs | 51 +++++++++++++++++++++++ src/Pools/EcsSinglePool.cs | 23 ++++++++--- src/Pools/EcsTagPool.cs | 23 ++++++++--- src/Utils/ArrayUtility.cs | 19 +++------ src/Utils/Extensions.cs | 10 +++++ 9 files changed, 215 insertions(+), 70 deletions(-) create mode 100644 src/Utils/Extensions.cs diff --git a/src/EcsWorld.cs b/src/EcsWorld.cs index 32a7fab..9b8f66d 100644 --- a/src/EcsWorld.cs +++ b/src/EcsWorld.cs @@ -9,7 +9,7 @@ namespace DCFApixels.DragonECS internal sealed class EcsNullWorld : EcsWorld { - public EcsNullWorld() : base(null, false) { } + public EcsNullWorld() : base(false) { } } public abstract class EcsWorld @@ -44,20 +44,16 @@ namespace DCFApixels.DragonECS private EcsSubject[] _subjects; private EcsQueryExecutor[] _executors; - private EcsPipeline _pipeline; - private List> _groups; private Stack _groupsPool = new Stack(64); - private IEcsEntityCreate _entityCreate; - private IEcsEntityDestroy _entityDestry; + private List _listeners; #region Properties public abstract Type Archetype { get; } public int UniqueID => uniqueID; public int Count => _entitiesCount; public int Capacity => _entitesCapacity; //_denseEntities.Length; - public EcsPipeline Pipeline => _pipeline; public EcsReadonlyGroup Entities => _allEntites.Readonly; public ReadOnlySpan AllPools => pools;// new ReadOnlySpan(pools, 0, _poolsCount); public int PoolsCount => _poolsCount; @@ -69,11 +65,13 @@ namespace DCFApixels.DragonECS EcsNullWorld nullWorld = new EcsNullWorld(); Worlds[0] = nullWorld; } - public EcsWorld(EcsPipeline pipline) : this(pipline, true) { } - internal EcsWorld(EcsPipeline pipline, bool isIndexable) + public EcsWorld() : this(true) { } + internal EcsWorld(bool isIndexable) { _entitesCapacity = 512; + _listeners = new List(); + if (isIndexable) { uniqueID = (short)_worldIdDispenser.GetFree(); @@ -84,8 +82,6 @@ namespace DCFApixels.DragonECS _worldTypeID = WorldMetaStorage.GetWorldId(Archetype); - _pipeline = pipline ?? EcsPipeline.Empty; - if (!_pipeline.IsInit) pipline.Init(); _entityDispenser = new IntDispenser(0); _nullPool = EcsNullPool.instance; pools = new IEcsPoolImplementation[512]; @@ -103,14 +99,8 @@ namespace DCFApixels.DragonECS _subjects = new EcsSubject[128]; _executors = new EcsQueryExecutor[128]; - - _entityCreate = _pipeline.GetRunner(); - _entityDestry = _pipeline.GetRunner(); - _pipeline.GetRunner>().Inject(this); - _pipeline.GetRunner().OnWorldCreate(this); } - public void Destroy() { _entityDispenser = null; @@ -127,7 +117,6 @@ namespace DCFApixels.DragonECS public void DestryWithPipeline() { Destroy(); - _pipeline.Destroy(); } #endregion @@ -319,10 +308,11 @@ namespace DCFApixels.DragonECS foreach (var item in pools) item.OnWorldResize(_gens.Length); + _listeners.InvokeOnWorldResize(_gens.Length); } _gens[entityID] &= GEN_BITS; - _entityCreate.OnEntityCreate(entityID); _allEntites.Add(entityID); + _listeners.InvokeOnNewEntity(entityID); return entityID; } public entlong NewEmptyEntityLong() @@ -337,7 +327,7 @@ namespace DCFApixels.DragonECS _delEntBuffer[_delEntBufferCount++] = entityID; _gens[entityID] |= DEATH_GEN_BIT; _entitiesCount--; - _entityDestry.OnEntityDestroy(entityID); + _listeners.InvokeOnDelEntity(entityID); if (_delEntBufferCount >= _delEntBuffer.Length) ReleaseDelEntityBuffer(); @@ -353,6 +343,7 @@ namespace DCFApixels.DragonECS ReadOnlySpan buffser = new ReadOnlySpan(_delEntBuffer, 0, _delEntBufferCount); foreach (var pool in pools) pool.OnReleaseDelEntityBuffer(buffser); + _listeners.InvokeOnReleaseDelEntityBuffer(buffser); for (int i = 0; i < _delEntBufferCount; i++) _entityDispenser.Release(_delEntBuffer[i]); _delEntBufferCount = 0; @@ -489,8 +480,8 @@ namespace DCFApixels.DragonECS where TWorldArchetype : EcsWorld { public override Type Archetype => typeof(TWorldArchetype); - public EcsWorld(EcsPipeline pipline) : base(pipline) { } - internal EcsWorld(EcsPipeline pipline, bool isIndexable) : base(pipline, isIndexable) { } + public EcsWorld() : base() { } + internal EcsWorld(bool isIndexable) : base(isIndexable) { } } #region Utils @@ -621,12 +612,45 @@ namespace DCFApixels.DragonECS } #endregion - // #region Callbacks Interface //TODO - // public interface IWorldCallbacks - // { - // void OnWorldResize(int newSize); - // void OnReleaseDelEntityBuffer(ReadOnlySpan buffer); - // void OnWorldDestroy(); - // } - // #endregion + #region Callbacks Interface //TODO + public interface IEcsWorldEventListener + { + void OnWorldResize(int newSize); + void OnReleaseDelEntityBuffer(ReadOnlySpan buffer); + void OnWorldDestroy(); + void OnNewEntity(int entityID); + void OnDelEntity(int entityID); + } + #endregion + + #region Extensions + public static class WorldEventListExtensions + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void InvokeOnWorldResize(this List self, int newSize) + { + for (int i = 0, iMax = self.Count; i < iMax; i++) self[i].OnWorldResize(newSize); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void InvokeOnReleaseDelEntityBuffer(this List self, ReadOnlySpan buffer) + { + for (int i = 0, iMax = self.Count; i < iMax; i++) self[i].OnReleaseDelEntityBuffer(buffer); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void InvokeOnWorldDestroy(this List self) + { + for (int i = 0, iMax = self.Count; i < iMax; i++) self[i].OnWorldDestroy(); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void InvokeOnNewEntity(this List self, int entityID) + { + for (int i = 0, iMax = self.Count; i < iMax; i++) self[i].OnNewEntity(entityID); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void InvokeOnDelEntity(this List self, int entityID) + { + for (int i = 0, iMax = self.Count; i < iMax; i++) self[i].OnDelEntity(entityID); + } + } + #endregion } diff --git a/src/Pools/EcsAttachPool.cs b/src/Pools/EcsAttachPool.cs index c65968d..cf58bcd 100644 --- a/src/Pools/EcsAttachPool.cs +++ b/src/Pools/EcsAttachPool.cs @@ -17,7 +17,8 @@ namespace DCFApixels.DragonECS private bool[] _entityFlags;// index = entityID / value = entityFlag;/ value = 0 = no entityID private T[] _items; //sparse private int _count; - private PoolRunners _poolRunners; + + private List _listeners; private EcsGroup _entities; public EcsReadonlyGroup Entities @@ -47,7 +48,7 @@ namespace DCFApixels.DragonECS _source = world; _id = componentID; - _poolRunners = new PoolRunners(world.Pipeline); + _listeners = new List(); _entities = EcsGroup.New(world); @@ -71,9 +72,9 @@ namespace DCFApixels.DragonECS entityFlag = true; _count++; _entities.Add(entityID); - _poolRunners.add.OnComponentAdd(entityID); + foreach (var item in _listeners) item.OnAdd(entityID); } - _poolRunners.write.OnComponentWrite(entityID); + foreach (var item in _listeners) item.OnWrite(entityID); _items[entityID].Target = target; } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -84,7 +85,7 @@ namespace DCFApixels.DragonECS if (_sanitizeTargetWorld >= 0 && target.world != _sanitizeTargetWorld) ThrowWorldDifferent(entityID); _sanitizeTargetWorld = target.world; #endif - _poolRunners.write.OnComponentWrite(entityID); + _listeners.InvokeOnWrite(entityID); _items[entityID].Target = target; } public void AddOrSet(int entityID, entlong target) @@ -115,7 +116,7 @@ namespace DCFApixels.DragonECS _entities.Remove(entityID); _entityFlags[entityID] = false; _count--; - _poolRunners.del.OnComponentDel(entityID); + _listeners.InvokeOnDel(entityID); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void TryDel(int entityID) @@ -177,6 +178,19 @@ namespace DCFApixels.DragonECS void IEcsPool.SetRaw(int entityID, object dataRaw) => ((IEcsPool)this).Write(entityID) = (T)dataRaw; #endregion + #region Listeners + public void AddListener(IEcsPoolEventListener listener) + { + if (listener == null) { throw new ArgumentNullException("listener is null"); } + _listeners.Add(listener); + } + public void RemoveListener(IEcsPoolEventListener listener) + { + if (listener == null) { throw new ArgumentNullException("listener is null"); } + _listeners.Remove(listener); + } + #endregion + #region IEnumerator - IntelliSense hack IEnumerator IEnumerable.GetEnumerator() => throw new NotImplementedException(); IEnumerator IEnumerable.GetEnumerator() => throw new NotImplementedException(); diff --git a/src/Pools/EcsNotNullPool.cs b/src/Pools/EcsNotNullPool.cs index 96283f9..7e482d9 100644 --- a/src/Pools/EcsNotNullPool.cs +++ b/src/Pools/EcsNotNullPool.cs @@ -18,7 +18,8 @@ namespace DCFApixels.DragonECS private IEcsComponentReset _componentResetHandler; private IEcsComponentCopy _componentCopyHandler; - private PoolRunners _poolRunners; + + private List _listeners; #region Properites public int Count => _count; @@ -37,9 +38,10 @@ namespace DCFApixels.DragonECS _items = new T[world.Capacity]; _count = 0; + _listeners = new List(); + _componentResetHandler = EcsComponentResetHandler.instance; _componentCopyHandler = EcsComponentCopyHandler.instance; - _poolRunners = new PoolRunners(world.Pipeline); } #endregion @@ -47,7 +49,7 @@ namespace DCFApixels.DragonECS [MethodImpl(MethodImplOptions.AggressiveInlining)] public ref T Write(int entityID) { - _poolRunners.write.OnComponentWrite(entityID); + _listeners.InvokeOnWrite(entityID); return ref _items[entityID]; } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -93,6 +95,19 @@ namespace DCFApixels.DragonECS void IEcsPool.SetRaw(int entityID, object dataRaw) => Write(entityID) = (T)dataRaw; #endregion + #region Listeners + public void AddListener(IEcsPoolEventListener listener) + { + if (listener == null) { throw new ArgumentNullException("listener is null"); } + _listeners.Add(listener); + } + public void RemoveListener(IEcsPoolEventListener listener) + { + if (listener == null) { throw new ArgumentNullException("listener is null"); } + _listeners.Remove(listener); + } + #endregion + #region IEnumerator - IntelliSense hack IEnumerator IEnumerable.GetEnumerator() => throw new NotImplementedException(); IEnumerator IEnumerable.GetEnumerator() => throw new NotImplementedException(); diff --git a/src/Pools/EcsPool.cs b/src/Pools/EcsPool.cs index faeba2a..0f04f13 100644 --- a/src/Pools/EcsPool.cs +++ b/src/Pools/EcsPool.cs @@ -21,7 +21,8 @@ namespace DCFApixels.DragonECS private IEcsComponentReset _componentResetHandler; private IEcsComponentCopy _componentCopyHandler; - private PoolRunners _poolRunners; + + private List _listeners; #region Properites public int Count => _itemsCount; @@ -45,9 +46,10 @@ namespace DCFApixels.DragonECS _items = new T[capacity]; _itemsCount = 0; + _listeners = new List(); + _componentResetHandler = EcsComponentResetHandler.instance; _componentCopyHandler = EcsComponentCopyHandler.instance; - _poolRunners = new PoolRunners(world.Pipeline); } #endregion @@ -72,8 +74,7 @@ namespace DCFApixels.DragonECS Array.Resize(ref _items, _items.Length << 1); } this.IncrementEntityComponentCount(entityID); - _poolRunners.add.OnComponentAdd(entityID); - _poolRunners.write.OnComponentWrite(entityID); + _listeners.InvokeOnAddAndWrite(entityID); return ref _items[itemIndex]; // } } @@ -84,7 +85,7 @@ namespace DCFApixels.DragonECS #if (DEBUG && !DISABLE_DEBUG) || !DRAGONECS_NO_SANITIZE_CHECKS if (!Has(entityID)) ThrowNotHaveComponent(entityID); #endif - _poolRunners.write.OnComponentWrite(entityID); + _listeners.InvokeOnWrite(entityID); return ref _items[_mapping[entityID]]; } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -113,9 +114,9 @@ namespace DCFApixels.DragonECS Array.Resize(ref _items, _items.Length << 1); } this.IncrementEntityComponentCount(entityID); - _poolRunners.add.OnComponentAdd(entityID); + _listeners.InvokeOnAdd(entityID); } - _poolRunners.write.OnComponentWrite(entityID); + _listeners.InvokeOnWrite(entityID); return ref _items[itemIndex]; } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -136,7 +137,7 @@ namespace DCFApixels.DragonECS _mapping[entityID] = 0; _itemsCount--; this.DecrementEntityComponentCount(entityID); - _poolRunners.del.OnComponentDel(entityID); + _listeners.InvokeOnDel(entityID); } public void TryDel(int entityID) { @@ -179,6 +180,19 @@ namespace DCFApixels.DragonECS ref T IEcsPool.Write(int entityID) => ref Write(entityID); #endregion + #region Listeners + public void AddListener(IEcsPoolEventListener listener) + { + if(listener == null) { throw new ArgumentNullException("listener is null"); } + _listeners.Add(listener); + } + public void RemoveListener(IEcsPoolEventListener listener) + { + if(listener == null) { throw new ArgumentNullException("listener is null"); } + _listeners.Remove(listener); + } + #endregion + #region IEnumerator - IntelliSense hack IEnumerator IEnumerable.GetEnumerator() => throw new NotImplementedException(); IEnumerator IEnumerable.GetEnumerator() => throw new NotImplementedException(); diff --git a/src/Pools/EcsPoolBase.cs b/src/Pools/EcsPoolBase.cs index 3c67537..2e28565 100644 --- a/src/Pools/EcsPoolBase.cs +++ b/src/Pools/EcsPoolBase.cs @@ -1,5 +1,6 @@ using DCFApixels.DragonECS.Internal; using System; +using System.Collections.Generic; using System.Linq; using System.Runtime.CompilerServices; @@ -24,6 +25,20 @@ namespace DCFApixels.DragonECS void Copy(int fromEntityID, int toEntityID); void Copy(int fromEntityID, EcsWorld toWorld, int toEntityID); #endregion + + #region Add/Remove Listeners + void AddListener(IEcsPoolEventListener listener); + void RemoveListener(IEcsPoolEventListener listener); + #endregion + } + public interface IEcsPoolEventListener + { + /// Called after adding an entity to the pool, but before changing values. + void OnAdd(int entityID); + /// Is called when EcsPool.Write or EcsPool.Add is called, but before changing values. + void OnWrite(int entityID); + /// Called after deleting an entity from the pool + void OnDel(int entityID); } public interface IEcsPool { @@ -43,6 +58,7 @@ namespace DCFApixels.DragonECS /// Only used to implement a custom pool. In other contexts use IEcsPool or IEcsPool. /// Component type public interface IEcsPoolImplementation : IEcsPool, IEcsPoolImplementation { } + public static class EcsPoolThrowHalper { public static void ThrowAlreadyHasComponent(int entityID) @@ -117,6 +133,11 @@ namespace DCFApixels.DragonECS void IEcsPoolImplementation.OnWorldResize(int newSize) { } void IEcsPoolImplementation.OnReleaseDelEntityBuffer(ReadOnlySpan buffer) { } #endregion + + #region Listeners + public void AddListener(IEcsPoolEventListener listener) { } + public void RemoveListener(IEcsPoolEventListener listener) { } + #endregion } } #endregion @@ -194,4 +215,34 @@ namespace DCFApixels.DragonECS public void Copy(ref T from, ref T to) => _fakeInstnace.Copy(ref from, ref to); } #endregion + + #region Extensions + public static class PoolEventListExtensions + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void InvokeOnAdd(this List self, int entityID) + { + for (int i = 0, iMax = self.Count; i < iMax; i++) self[i].OnAdd(entityID); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void InvokeOnAddAndWrite(this List self, int entityID) + { + for (int i = 0, iMax = self.Count; i < iMax; i++) + { + self[i].OnAdd(entityID); + self[i].OnWrite(entityID); + } + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void InvokeOnWrite(this List self, int entityID) + { + for (int i = 0, iMax = self.Count; i < iMax; i++) self[i].OnWrite(entityID); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void InvokeOnDel(this List self, int entityID) + { + for (int i = 0, iMax = self.Count; i < iMax; i++) self[i].OnDel(entityID); + } + } + #endregion } diff --git a/src/Pools/EcsSinglePool.cs b/src/Pools/EcsSinglePool.cs index 5052a50..e829af6 100644 --- a/src/Pools/EcsSinglePool.cs +++ b/src/Pools/EcsSinglePool.cs @@ -17,7 +17,7 @@ namespace DCFApixels.DragonECS private int _count; private T _component; - private PoolRunners _poolRunners; + private List _listeners; #region Properites public ref T Instance @@ -40,7 +40,7 @@ namespace DCFApixels.DragonECS _mapping = new int[world.Capacity]; _count = 0; - _poolRunners = new PoolRunners(world.Pipeline); + _listeners = new List(); } #endregion @@ -52,7 +52,7 @@ namespace DCFApixels.DragonECS #endif _mapping[entityID] = ++_count; this.IncrementEntityComponentCount(entityID); - _poolRunners.add.OnComponentAdd(entityID); + _listeners.InvokeOnAddAndWrite(entityID); return ref _component; } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -61,7 +61,7 @@ namespace DCFApixels.DragonECS #if (DEBUG && !DISABLE_DEBUG) || !DRAGONECS_NO_SANITIZE_CHECKS if (!Has(entityID)) ThrowNotHaveComponent(entityID); #endif - _poolRunners.write.OnComponentWrite(entityID); + _listeners.InvokeOnWrite(entityID); return ref _component; } public ref T TryAddOrWrite(int entityID) @@ -92,7 +92,7 @@ namespace DCFApixels.DragonECS _mapping[entityID] = 0; _count--; this.DecrementEntityComponentCount(entityID); - _poolRunners.del.OnComponentDel(entityID); + _listeners.InvokeOnDel(entityID); } public void TryDel(int entityID) { @@ -133,6 +133,19 @@ namespace DCFApixels.DragonECS void IEcsPool.SetRaw(int entityID, object dataRaw) => Instance = (T)dataRaw; #endregion + #region Listeners + public void AddListener(IEcsPoolEventListener listener) + { + if (listener == null) { throw new ArgumentNullException("listener is null"); } + _listeners.Add(listener); + } + public void RemoveListener(IEcsPoolEventListener listener) + { + if (listener == null) { throw new ArgumentNullException("listener is null"); } + _listeners.Remove(listener); + } + #endregion + #region IEnumerator - IntelliSense hack IEnumerator IEnumerable.GetEnumerator() => throw new NotImplementedException(); IEnumerator IEnumerable.GetEnumerator() => throw new NotImplementedException(); diff --git a/src/Pools/EcsTagPool.cs b/src/Pools/EcsTagPool.cs index 5d275de..13270d8 100644 --- a/src/Pools/EcsTagPool.cs +++ b/src/Pools/EcsTagPool.cs @@ -15,7 +15,7 @@ namespace DCFApixels.DragonECS private bool[] _mapping;// index = entityID / value = itemIndex;/ value = 0 = no entityID private int _count; - private PoolRunners _poolRunners; + private List _listeners; private T _fakeComponent; @@ -36,7 +36,7 @@ namespace DCFApixels.DragonECS _mapping = new bool[world.Capacity]; _count = 0; - _poolRunners = new PoolRunners(world.Pipeline); + _listeners = new List(); } #endregion @@ -49,7 +49,7 @@ namespace DCFApixels.DragonECS _count++; _mapping[entityID] = true; this.IncrementEntityComponentCount(entityID); - _poolRunners.add.OnComponentAdd(entityID); + _listeners.InvokeOnAdd(entityID); } public void TryAdd(int entityID) { @@ -58,7 +58,7 @@ namespace DCFApixels.DragonECS _count++; _mapping[entityID] = true; this.IncrementEntityComponentCount(entityID); - _poolRunners.add.OnComponentAdd(entityID); + _listeners.InvokeOnAdd(entityID); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -74,7 +74,7 @@ namespace DCFApixels.DragonECS _mapping[entityID] = false; _count--; this.DecrementEntityComponentCount(entityID); - _poolRunners.del.OnComponentDel(entityID); + _listeners.InvokeOnDel(entityID); } public void TryDel(int entityID) { @@ -166,6 +166,19 @@ namespace DCFApixels.DragonECS } #endregion + #region Listeners + public void AddListener(IEcsPoolEventListener listener) + { + if (listener == null) { throw new ArgumentNullException("listener is null"); } + _listeners.Add(listener); + } + public void RemoveListener(IEcsPoolEventListener listener) + { + if (listener == null) { throw new ArgumentNullException("listener is null"); } + _listeners.Remove(listener); + } + #endregion + #region IEnumerator - IntelliSense hack IEnumerator IEnumerable.GetEnumerator() => throw new NotImplementedException(); IEnumerator IEnumerable.GetEnumerator() => throw new NotImplementedException(); diff --git a/src/Utils/ArrayUtility.cs b/src/Utils/ArrayUtility.cs index 2f55154..e5e72b6 100644 --- a/src/Utils/ArrayUtility.cs +++ b/src/Utils/ArrayUtility.cs @@ -8,30 +8,22 @@ namespace DCFApixels.DragonECS public static void Fill(T[] array, T value, int startIndex = 0, int length = -1) { if (length < 0) - { length = array.Length; - } else - { length = startIndex + length; - } for (int i = startIndex; i < length; i++) - { array[i] = value; - } } } - internal static unsafe class UnmanagedArray + internal static unsafe class UnmanagedArrayUtility { - public static void* New(int elementCount) - where T : struct + public static void* New(int elementCount) where T : struct { return Marshal.AllocHGlobal(Marshal.SizeOf(typeof(T)) * elementCount).ToPointer(); } - public static void* NewAndInit(int elementCount) - where T : struct + public static void* NewAndInit(int elementCount) where T : struct { int newSizeInBytes = Marshal.SizeOf(typeof(T)) * elementCount; byte* newArrayPointer = (byte*)Marshal.AllocHGlobal(newSizeInBytes).ToPointer(); @@ -39,7 +31,7 @@ namespace DCFApixels.DragonECS for (int i = 0; i < newSizeInBytes; i++) *(newArrayPointer + i) = 0; - return (void*)newArrayPointer; + return newArrayPointer; } public static void Free(void* pointerToUnmanagedMemory) @@ -47,8 +39,7 @@ namespace DCFApixels.DragonECS Marshal.FreeHGlobal(new IntPtr(pointerToUnmanagedMemory)); } - public static void* Resize(void* oldPointer, int newElementCount) - where T : struct + public static void* Resize(void* oldPointer, int newElementCount) where T : struct { return (Marshal.ReAllocHGlobal(new IntPtr(oldPointer), new IntPtr(Marshal.SizeOf(typeof(T)) * newElementCount))).ToPointer(); diff --git a/src/Utils/Extensions.cs b/src/Utils/Extensions.cs new file mode 100644 index 0000000..2e1fd6e --- /dev/null +++ b/src/Utils/Extensions.cs @@ -0,0 +1,10 @@ +namespace DCFApixels.DragonECS +{ + public static class Extensions + { + public static entlong ToEntityLong(this int self, EcsWorld world) + { + return world.GetEntityLong(self); + } + } +}