From f045335881092a9533752a510a09da2779074a24 Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Mon, 5 Dec 2022 17:46:18 -0800 Subject: [PATCH] initial template system --- src/ComponentDepot.cs | 14 +++++++++----- src/ComponentStorage.cs | 23 +++++++++++++---------- src/DebugSystem.cs | 4 +--- src/EntityComponentReader.cs | 2 ++ src/EntityStorage.cs | 12 ++++++------ src/System.cs | 22 ++++++++++++++++++++++ src/TemplateStorage.cs | 15 +++++++++++++++ src/World.cs | 21 ++++++++++++++------- 8 files changed, 82 insertions(+), 31 deletions(-) diff --git a/src/ComponentDepot.cs b/src/ComponentDepot.cs index e0a4618..94487ec 100644 --- a/src/ComponentDepot.cs +++ b/src/ComponentDepot.cs @@ -15,7 +15,7 @@ namespace MoonTools.ECS } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private void Register(int index) where TComponent : unmanaged + internal void Register(int index) where TComponent : unmanaged { if (index >= storages.Length) { @@ -47,12 +47,11 @@ namespace MoonTools.ECS return ref Lookup().Get(entityID); } -#if DEBUG - public object Debug_Get(int entityID, int componentTypeIndex) + // used for debugging and template instantiation + internal object UntypedGet(int entityID, int componentTypeIndex) { - return storages[componentTypeIndex].Debug_Get(entityID); + return storages[componentTypeIndex].UntypedGet(entityID); } -#endif public ref readonly TComponent GetFirst() where TComponent : unmanaged { @@ -64,6 +63,11 @@ namespace MoonTools.ECS Lookup().Set(entityID, component); } + internal void Set(int entityID, int componentTypeIndex, object component) + { + storages[componentTypeIndex].Set(entityID, component); + } + public Entity GetSingletonEntity() where TComponent : unmanaged { return Lookup().FirstEntity(); diff --git a/src/ComponentStorage.cs b/src/ComponentStorage.cs index 35d6f5b..6714b90 100644 --- a/src/ComponentStorage.cs +++ b/src/ComponentStorage.cs @@ -6,14 +6,14 @@ namespace MoonTools.ECS { internal abstract class ComponentStorage { + internal abstract void Set(int entityID, object component); public abstract bool Remove(int entityID); public abstract ComponentStorageState CreateState(); public abstract void Save(ComponentStorageState state); public abstract void Load(ComponentStorageState state); -#if DEBUG - public abstract object Debug_Get(int entityID); -#endif + // used for debugging and template instantiation + internal abstract object UntypedGet(int entityID); } internal class ComponentStorage : ComponentStorage where TComponent : unmanaged @@ -33,6 +33,11 @@ namespace MoonTools.ECS return ref components[entityIDToStorageIndex[entityID]]; } + internal override object UntypedGet(int entityID) + { + return components[entityIDToStorageIndex[entityID]]; + } + public ref readonly TComponent GetFirst() { #if DEBUG @@ -64,6 +69,11 @@ namespace MoonTools.ECS components[entityIDToStorageIndex[entityID]] = component; } + internal override void Set(int entityID, object component) + { + Set(entityID, (TComponent) component); + } + // Returns true if the entity had this component. public override bool Remove(int entityID) { @@ -151,12 +161,5 @@ namespace MoonTools.ECS nextID = state.Count; } - -#if DEBUG - public override object Debug_Get(int entityID) - { - return components[entityIDToStorageIndex[entityID]]; - } -#endif } } diff --git a/src/DebugSystem.cs b/src/DebugSystem.cs index a8e0002..36aada6 100644 --- a/src/DebugSystem.cs +++ b/src/DebugSystem.cs @@ -9,9 +9,7 @@ namespace MoonTools.ECS { public abstract class DebugSystem : System { -#if DEBUG private Dictionary singleComponentFilters = new Dictionary(); -#endif protected DebugSystem(World world) : base(world) { @@ -21,7 +19,7 @@ namespace MoonTools.ECS { foreach (var typeIndex in EntityStorage.ComponentTypeIndices(entity.ID)) { - yield return ComponentDepot.Debug_Get(entity.ID, typeIndex); + yield return ComponentDepot.UntypedGet(entity.ID, typeIndex); } } diff --git a/src/EntityComponentReader.cs b/src/EntityComponentReader.cs index caf1ba7..91fa1ac 100644 --- a/src/EntityComponentReader.cs +++ b/src/EntityComponentReader.cs @@ -13,6 +13,8 @@ namespace MoonTools.ECS internal FilterStorage FilterStorage => World.FilterStorage; internal TypeIndices ComponentTypeIndices => World.ComponentTypeIndices; internal TypeIndices RelationTypeIndices => World.RelationTypeIndices; + internal TemplateStorage TemplateStorage => World.TemplateStorage; + internal ComponentDepot TemplateComponentDepot => World.TemplateComponentDepot; public EntityComponentReader(World world) { diff --git a/src/EntityStorage.cs b/src/EntityStorage.cs index 39aa9b9..44fd0a9 100644 --- a/src/EntityStorage.cs +++ b/src/EntityStorage.cs @@ -33,20 +33,20 @@ namespace MoonTools.ECS } // Returns true if the component is new. - public bool SetComponent(int entityID, int storageIndex) + public bool SetComponent(int entityID, int componentTypeIndex) { - return EntityToComponentTypeIndices[entityID].Add(storageIndex); + return EntityToComponentTypeIndices[entityID].Add(componentTypeIndex); } - public bool HasComponent(int entityID, int storageIndex) + public bool HasComponent(int entityID, int componentTypeIndex) { - return EntityToComponentTypeIndices[entityID].Contains(storageIndex); + return EntityToComponentTypeIndices[entityID].Contains(componentTypeIndex); } // Returns true if the component existed. - public bool RemoveComponent(int entityID, int storageIndex) + public bool RemoveComponent(int entityID, int componentTypeIndex) { - return EntityToComponentTypeIndices[entityID].Remove(storageIndex); + return EntityToComponentTypeIndices[entityID].Remove(componentTypeIndex); } public void AddRelation(int entityID, int relationIndex) diff --git a/src/System.cs b/src/System.cs index 15ca930..888a9bd 100644 --- a/src/System.cs +++ b/src/System.cs @@ -42,6 +42,28 @@ namespace MoonTools.ECS } } + protected void Set(in Template template, in TComponent component) where TComponent : unmanaged + { + var componentTypeIndex = ComponentTypeIndices.GetIndex(); + TemplateStorage.SetComponent(template.ID, componentTypeIndex); + TemplateComponentDepot.Set(template.ID, component); + ComponentDepot.Register(componentTypeIndex); + } + + protected Entity Instantiate(in Template template) + { + var entity = EntityStorage.Create(); + + foreach (var componentTypeIndex in TemplateStorage.ComponentTypeIndices(template.ID)) + { + EntityStorage.SetComponent(entity.ID, componentTypeIndex); + FilterStorage.Check(entity.ID, componentTypeIndex); + ComponentDepot.Set(entity.ID, componentTypeIndex, TemplateComponentDepot.UntypedGet(template.ID, componentTypeIndex)); + } + + return entity; + } + protected ReadOnlySpan ReadMessages() where TMessage : unmanaged { return MessageDepot.All(); diff --git a/src/TemplateStorage.cs b/src/TemplateStorage.cs index e3b36f7..c45f32f 100644 --- a/src/TemplateStorage.cs +++ b/src/TemplateStorage.cs @@ -1,14 +1,29 @@ +using System.Collections.Generic; + namespace MoonTools.ECS { public class TemplateStorage { private int nextID = 0; + private Dictionary> TemplateToComponentTypeIndices = new Dictionary>(); + public Template Create() { + TemplateToComponentTypeIndices.Add(nextID, new HashSet()); return new Template(NextID()); } + public bool SetComponent(int templateID, int componentTypeIndex) + { + return TemplateToComponentTypeIndices[templateID].Add(componentTypeIndex); + } + + public IEnumerable ComponentTypeIndices(int templateID) + { + return TemplateToComponentTypeIndices[templateID]; + } + private int NextID() { var id = nextID; diff --git a/src/World.cs b/src/World.cs index 0517633..d0b4834 100644 --- a/src/World.cs +++ b/src/World.cs @@ -10,16 +10,16 @@ internal readonly RelationDepot RelationDepot; internal readonly FilterStorage FilterStorage; - /* internal readonly TemplateStorage TemplateStorage = new TemplateStorage(); - internal readonly ComponentDepot TemplateComponentDepot = new ComponentDepot(); - */ + internal readonly ComponentDepot TemplateComponentDepot; + public World() { ComponentDepot = new ComponentDepot(ComponentTypeIndices); RelationDepot = new RelationDepot(RelationTypeIndices); FilterStorage = new FilterStorage(EntityStorage, ComponentTypeIndices); + TemplateComponentDepot = new ComponentDepot(ComponentTypeIndices); } public Entity CreateEntity() @@ -37,22 +37,29 @@ ComponentDepot.Set(entity.ID, component); } - /* public Template CreateTemplate() { return TemplateStorage.Create(); } - public void Set(Template template, in TComponent component) where TComponent : unmanaged + public void Set(in Template template, in TComponent component) where TComponent : unmanaged { + TemplateStorage.SetComponent(template.ID, ComponentTypeIndices.GetIndex()); TemplateComponentDepot.Set(template.ID, component); } - */ - public Entity Instantiate(Template template) + // TODO: TEST ME!!! + public Entity Instantiate(in Template template) { var entity = EntityStorage.Create(); + foreach (var componentTypeIndex in TemplateStorage.ComponentTypeIndices(template.ID)) + { + EntityStorage.SetComponent(entity.ID, componentTypeIndex); + FilterStorage.Check(entity.ID, componentTypeIndex); + ComponentDepot.Set(entity.ID, componentTypeIndex, TemplateComponentDepot.UntypedGet(template.ID, componentTypeIndex)); + } + return entity; }