From f5654991382d7ff483ac9ac69d607fb24347fd09 Mon Sep 17 00:00:00 2001 From: Mikhail <99481254+DCFApixels@users.noreply.github.com> Date: Tue, 30 May 2023 15:15:37 +0800 Subject: [PATCH] add world components --- src/EcsWorld.cs | 166 +++------------------------- src/Utils/WorldMetaStorage.cs | 198 ++++++++++++++++++++++++++++++++++ 2 files changed, 215 insertions(+), 149 deletions(-) create mode 100644 src/Utils/WorldMetaStorage.cs diff --git a/src/EcsWorld.cs b/src/EcsWorld.cs index 1227d6a..eb53348 100644 --- a/src/EcsWorld.cs +++ b/src/EcsWorld.cs @@ -40,6 +40,8 @@ namespace DCFApixels.DragonECS private List _listeners; + private object[] _components; + #region Properties public abstract Type Archetype { get; } public int UniqueID => uniqueID; @@ -85,6 +87,8 @@ namespace DCFApixels.DragonECS _subjects = new EcsSubject[128]; _executors = new EcsQueryExecutor[128]; + + _components = new object[0]; } public void Destroy() { @@ -99,6 +103,19 @@ namespace DCFApixels.DragonECS } #endregion + #region WorldComponent + public T Get() where T : class, new() + { + var result = _components[WorldMetaStorage.GetWorldComponentId(_worldTypeID)]; + if(result == null) + { + result = new T(); + _components[WorldMetaStorage.GetWorldComponentId(_worldTypeID)] = result; + } + return (T)result; + } + #endregion + #region ComponentInfo public int GetComponentID() => WorldMetaStorage.GetComponentId(_worldTypeID); public Type GetComponentType(int componentID) => WorldMetaStorage.GetComponentType(_worldTypeID, componentID); @@ -369,155 +386,6 @@ namespace DCFApixels.DragonECS internal EcsWorld(bool isIndexable) : base(isIndexable) { } } - #region WorldMetaStorage - internal static class WorldMetaStorage - { - private static List _resizer = new List(); - private static int _tokenCount = 0; - - private static WorldTypeMeta[] _metas = new WorldTypeMeta[0]; - private static Dictionary _worldIds = new Dictionary(); - private static class WorldIndex - { - public static int id = GetWorldID(typeof(TWorldArchetype)); - } - private static int GetToken() - { - WorldTypeMeta meta = new WorldTypeMeta(); - meta.id = _tokenCount; - Array.Resize(ref _metas, ++_tokenCount); - _metas[_tokenCount - 1] = meta; - - foreach (var item in _resizer) - item.Resize(_tokenCount); - return _tokenCount - 1; - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int GetWorldID(Type archetype) - { - if(!_worldIds.TryGetValue(archetype, out int id)) - { - id = GetToken(); - _worldIds.Add(archetype, id); - } - return id; - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int GetWorldId() => WorldIndex.id; - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int GetComponentId(int worldID) => Component.Get(worldID); - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int GetSubjectId(int worldID) => Subject.Get(worldID); - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int GetExecutorId(int worldID) => Executor.Get(worldID); - - public static bool IsComponentTypeDeclared(int worldID, Type type) => _metas[worldID].IsDeclaredType(type); - public static Type GetComponentType(int worldID, int componentID) => _metas[worldID].GetComponentType(componentID); - - #region Resizer - private abstract class Resizer - { - public abstract void Resize(int size); - } - private sealed class Resizer : Resizer - { - public override void Resize(int size) - { - Array.Resize(ref Component.ids, size); - Array.Resize(ref Subject.ids, size); - Array.Resize(ref Executor.ids, size); - } - } - #endregion - private static class Component - { - public static int[] ids; - static Component() - { - ids = new int[_tokenCount]; - for (int i = 0; i < ids.Length; i++) - ids[i] = -1; - _resizer.Add(new Resizer()); - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int Get(int token) - { - ref int id = ref ids[token]; - if (id < 0) - { - var meta = _metas[token]; - id = meta.componentCount++; - meta.AddType(id, typeof(T)); - } - return id; - } - } - private static class Subject - { - public static int[] ids; - static Subject() - { - ids = new int[_tokenCount]; - for (int i = 0; i < ids.Length; i++) - ids[i] = -1; - _resizer.Add(new Resizer()); - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int Get(int token) - { - ref int id = ref ids[token]; - if (id < 0) - id = _metas[token].subjectsCount++; - return id; - } - } - private static class Executor - { - public static int[] ids; - static Executor() - { - ids = new int[_tokenCount]; - for (int i = 0; i < ids.Length; i++) - ids[i] = -1; - _resizer.Add(new Resizer()); - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int Get(int token) - { - ref int id = ref ids[token]; - if (id < 0) - id = _metas[token].executorsCount++; - return id; - } - } - - private class WorldTypeMeta - { - public int id; - public int componentCount; - public int subjectsCount; - public int executorsCount; - private Type[] types; - private HashSet declaredComponentTypes; - public void AddType(int id, Type type) - { - if(types.Length <= id) - Array.Resize(ref types, id + 10); - types[id] = type; - - declaredComponentTypes.Add(type); - } - public Type GetComponentType(int componentID) => types[componentID]; - public bool IsDeclaredType(Type type) => declaredComponentTypes.Contains(type); - public WorldTypeMeta() - { - types = new Type[10]; - declaredComponentTypes = new HashSet(); - } - } - } - #endregion - #region Callbacks Interface public interface IEcsWorldEventListener { diff --git a/src/Utils/WorldMetaStorage.cs b/src/Utils/WorldMetaStorage.cs new file mode 100644 index 0000000..7a460d3 --- /dev/null +++ b/src/Utils/WorldMetaStorage.cs @@ -0,0 +1,198 @@ +using DCFApixels.DragonECS.Utils; +using System; +using System.Collections.Generic; +using System.Runtime.CompilerServices; + +namespace DCFApixels.DragonECS +{ + internal static class WorldMetaStorage + { + private static int _tokenCount = 0; + private static List _resizers = new List(); + private static WorldTypeMeta[] _metas = new WorldTypeMeta[0]; + private static Dictionary _worldIds = new Dictionary(); + private static class WorldIndex + { + public static int id = GetWorldID(typeof(TWorldArchetype)); + } + private static int GetToken() + { + WorldTypeMeta meta = new WorldTypeMeta(); + meta.id = _tokenCount; + Array.Resize(ref _metas, ++_tokenCount); + _metas[_tokenCount - 1] = meta; + + foreach (var item in _resizers) + item.Resize(_tokenCount); + return _tokenCount - 1; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int GetWorldID(Type archetype) + { + if (!_worldIds.TryGetValue(archetype, out int id)) + { + id = GetToken(); + _worldIds.Add(archetype, id); + } + return id; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int GetWorldId() => WorldIndex.id; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int GetComponentId(int worldID) => Component.Get(worldID); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int GetSubjectId(int worldID) => Subject.Get(worldID); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int GetExecutorId(int worldID) => Executor.Get(worldID); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int GetWorldComponentId(int worldID) => WorldComponent.Get(worldID); + public static bool IsComponentTypeDeclared(int worldID, Type type) => _metas[worldID].IsDeclaredType(type); + public static Type GetComponentType(int worldID, int componentID) => _metas[worldID].GetComponentType(componentID); + + private abstract class ResizerBase + { + public abstract void Resize(int size); + } + private static class Component + { + public static int[] ids; + static Component() + { + ids = new int[_tokenCount]; + for (int i = 0; i < ids.Length; i++) + ids[i] = -1; + _resizers.Add(new Resizer()); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int Get(int token) + { + ref int id = ref ids[token]; + if (id < 0) + { + var meta = _metas[token]; + id = (ushort)meta.componentCount++; + meta.AddType(id, typeof(T)); + } + return id; + } + private sealed class Resizer : ResizerBase + { + public override void Resize(int size) + { + int oldSize = ids.Length; + Array.Resize(ref ids, size); + ArrayUtility.Fill(ids, -1, oldSize, size); + } + } + } + private static class Subject + { + public static int[] ids; + static Subject() + { + ids = new int[_tokenCount]; + for (int i = 0; i < ids.Length; i++) + ids[i] = -1; + _resizers.Add(new Resizer()); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int Get(int token) + { + ref int id = ref ids[token]; + if (id < 0) + id = _metas[token].subjectsCount++; + return id; + } + private sealed class Resizer : ResizerBase + { + public override void Resize(int size) + { + int oldSize = ids.Length; + Array.Resize(ref ids, size); + ArrayUtility.Fill(ids, -1, oldSize, size); + } + } + } + private static class Executor + { + public static int[] ids; + static Executor() + { + ids = new int[_tokenCount]; + for (int i = 0; i < ids.Length; i++) + ids[i] = -1; + _resizers.Add(new Resizer()); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int Get(int token) + { + ref int id = ref ids[token]; + if (id < 0) + id = _metas[token].executorsCount++; + return id; + } + private sealed class Resizer : ResizerBase + { + public override void Resize(int size) + { + int oldSize = ids.Length; + Array.Resize(ref ids, size); + ArrayUtility.Fill(ids, -1, oldSize, size); + } + } + } + private static class WorldComponent + { + public static int[] ids; + static WorldComponent() + { + ids = new int[_tokenCount]; + for (int i = 0; i < ids.Length; i++) + ids[i] = -1; + _resizers.Add(new Resizer()); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int Get(int token) + { + ref int id = ref ids[token]; + if (id < 0) + id = _metas[token].worldComponentCount++; + return id; + } + private sealed class Resizer : ResizerBase + { + public override void Resize(int size) + { + int oldSize = ids.Length; + Array.Resize(ref ids, size); + ArrayUtility.Fill(ids, -1, oldSize, size); + } + } + } + private class WorldTypeMeta + { + public int id; + public int componentCount; + public int subjectsCount; + public int executorsCount; + public int worldComponentCount; + private Type[] _types; + private HashSet _declaredComponentTypes; + public void AddType(int id, Type type) + { + if (_types.Length <= id) + Array.Resize(ref _types, id + 10); + _types[id] = type; + + _declaredComponentTypes.Add(type); + } + public Type GetComponentType(int componentID) => _types[componentID]; + public bool IsDeclaredType(Type type) => _declaredComponentTypes.Contains(type); + public WorldTypeMeta() + { + _types = new Type[10]; + _declaredComponentTypes = new HashSet(); + } + } + } +}