diff --git a/encompass-cs/Collections/ComponentStore.cs b/encompass-cs/Collections/ComponentStore.cs index ffb4eda..c04845c 100644 --- a/encompass-cs/Collections/ComponentStore.cs +++ b/encompass-cs/Collections/ComponentStore.cs @@ -15,13 +15,19 @@ namespace Encompass } } - private TypedComponentStore Lookup() where TComponent : struct, IComponent + public void RegisterComponentType() where TComponent : struct, IComponent { if (!Stores.ContainsKey(typeof(TComponent))) { + System.Console.WriteLine("register component type in component store"); var store = new TypedComponentStore(); Stores.Add(typeof(TComponent), store); } + } + + private TypedComponentStore Lookup() where TComponent : struct, IComponent + { + //RegisterComponentType(); return Stores[typeof(TComponent)] as TypedComponentStore; } diff --git a/encompass-cs/ComponentManager.cs b/encompass-cs/ComponentManager.cs index c0d53e3..611526d 100644 --- a/encompass-cs/ComponentManager.cs +++ b/encompass-cs/ComponentManager.cs @@ -17,6 +17,11 @@ namespace Encompass this.componentUpdateManager = componentUpdateManager; } + public void RegisterComponentType() where TComponent : struct, IComponent + { + componentStore.RegisterComponentType(); + } + internal void SetComponentStore(ComponentStore componentStore) { this.componentStore.SwapWith(componentStore); diff --git a/encompass-cs/ComponentUpdateManager.cs b/encompass-cs/ComponentUpdateManager.cs index c61955c..26b3ea8 100644 --- a/encompass-cs/ComponentUpdateManager.cs +++ b/encompass-cs/ComponentUpdateManager.cs @@ -13,6 +13,13 @@ namespace Encompass public ComponentStore UpToDateComponentStore { get; private set; } = new ComponentStore(); + public void RegisterComponentType() where TComponent : struct, IComponent + { + existingAndPendingComponentStore.RegisterComponentType(); + existingComponentStore.RegisterComponentType(); + pendingComponentStore.RegisterComponentType(); + } + internal void Clear() { existingAndPendingComponentStore.ClearAll(); diff --git a/encompass-cs/DrawLayerManager.cs b/encompass-cs/DrawLayerManager.cs index 9785987..1680df2 100644 --- a/encompass-cs/DrawLayerManager.cs +++ b/encompass-cs/DrawLayerManager.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using Encompass.Exceptions; namespace Encompass { @@ -15,26 +16,32 @@ namespace Encompass public IEnumerable LayerOrder { get { return layerOrder.Values; } } - public void RegisterGeneralRendererWithLayer(GeneralRenderer renderer, int layer) + public void RegisterDrawLayer(int layer) { - if (layerIndexToGeneralRenderers.ContainsKey(layer)) - { - var set = layerIndexToGeneralRenderers[layer]; - set.Add(renderer); - } - else - { - var set = new HashSet(); - layerIndexToGeneralRenderers.Add(layer, set); - set.Add(renderer); - } - - if (!layerOrder.ContainsKey(layer)) + if (!layerIndexToComponentStore.ContainsKey(layer)) { layerOrder.Add(layer, layer); + layerIndexToGeneralRenderers.Add(layer, new HashSet()); + layerIndexToComponentStore.Add(layer, new ComponentStore()); } } + public void RegisterOrderedDrawable() where TComponent : struct, IComponent + { + typeToEntityToLayer.Add(typeof(TComponent), new Dictionary(128)); + foreach (var pair in layerIndexToComponentStore) + { + pair.Value.RegisterComponentType(); + } + } + + public void RegisterGeneralRendererWithLayer(GeneralRenderer renderer, int layer) + { + RegisterDrawLayer(layer); + var set = layerIndexToGeneralRenderers[layer]; + set.Add(renderer); + } + public void UnregisterGeneralRendererWithLayer(GeneralRenderer renderer, int layer) { if (layerIndexToGeneralRenderers.ContainsKey(layer)) @@ -51,31 +58,17 @@ namespace Encompass public void RegisterComponentWithLayer(Entity entity, TComponent component, int layer) where TComponent : struct, IComponent { - if (!typeToEntityToLayer.ContainsKey(typeof(TComponent))) + if (!layerIndexToComponentStore.ContainsKey(layer)) { - typeToEntityToLayer.Add(typeof(TComponent), new Dictionary()); + throw new UndefinedLayerException("Layer {0} is not defined. Use WorldBuilder.RegisterDrawLayer to register the layer.", layer); } if (typeToEntityToLayer[typeof(TComponent)].ContainsKey(entity)) { UnRegisterComponentWithLayer(entity); } - if (layerIndexToComponentStore.ContainsKey(layer)) - { - var set = layerIndexToComponentStore[layer]; - set.Set(entity, component); - } - else - { - var set = new ComponentStore(); - layerIndexToComponentStore.Add(layer, set); - set.Set(entity, component); - } + var set = layerIndexToComponentStore[layer]; + set.Set(entity, component); typeToEntityToLayer[typeof(TComponent)].Add(entity, layer); - - if (!layerOrder.ContainsKey(layer)) - { - layerOrder.Add(layer, layer); - } } public void UnRegisterComponentWithLayer(Entity entity) where TComponent : struct, IComponent diff --git a/encompass-cs/Exceptions/UndefinedLayerException.cs b/encompass-cs/Exceptions/UndefinedLayerException.cs new file mode 100644 index 0000000..711d9a8 --- /dev/null +++ b/encompass-cs/Exceptions/UndefinedLayerException.cs @@ -0,0 +1,12 @@ +using System; + +namespace Encompass.Exceptions +{ + public class UndefinedLayerException : Exception + { + public UndefinedLayerException( + string format, + params object[] args + ) : base(string.Format(format, args)) { } + } +} diff --git a/encompass-cs/RenderManager.cs b/encompass-cs/RenderManager.cs index cea10c0..c1f7e92 100644 --- a/encompass-cs/RenderManager.cs +++ b/encompass-cs/RenderManager.cs @@ -17,6 +17,7 @@ namespace Encompass public void RegisterOrderedRenderer(Action renderAction) where TComponent : struct, IComponent { drawComponentTypeToOrderedRenderer.Add(typeof(TComponent), renderAction); + drawLayerManager.RegisterOrderedDrawable(); } public void RegisterGeneralRendererWithLayer(GeneralRenderer renderer, int layer) diff --git a/encompass-cs/WorldBuilder.cs b/encompass-cs/WorldBuilder.cs index 331a08d..a4efde1 100644 --- a/encompass-cs/WorldBuilder.cs +++ b/encompass-cs/WorldBuilder.cs @@ -35,7 +35,7 @@ namespace Encompass private readonly HashSet senders = new HashSet(); - private readonly HashSet registeredComponentTypes = new HashSet(); + private readonly HashSet componentTypesToRegister = new HashSet(); public WorldBuilder() { @@ -77,20 +77,28 @@ namespace Encompass /// public void SetComponent(Entity entity, TComponent component) where TComponent : struct, IComponent { + RegisterComponentType(); + startingComponentStoreForComponentManager.Set(entity, component); startingComponentStoreForComponentUpdateManager.Set(entity, component); - RegisterComponent(typeof(TComponent)); - if (component is IDrawableComponent drawableComponent) { componentManager.RegisterDrawableComponent(entity, component, drawableComponent.Layer); } } - internal void RegisterComponent(Type componentType) + internal void RegisterComponentType() where TComponent : struct, IComponent { - registeredComponentTypes.Add(componentType); + componentManager.RegisterComponentType(); + componentUpdateManager.RegisterComponentType(); + startingComponentStoreForComponentManager.RegisterComponentType(); + startingComponentStoreForComponentUpdateManager.RegisterComponentType(); + } + + internal void AddComponentTypeToRegister(Type componentType) + { + componentTypesToRegister.Add(componentType); } /// @@ -128,7 +136,7 @@ namespace Encompass foreach (var componentType in engine.readTypes.Union(engine.writeTypes).Union(engine.readPendingTypes)) { - RegisterComponent(componentType); + AddComponentTypeToRegister(componentType); } foreach (var receiveType in engine.receiveTypes.Union(engine.readPendingTypes)) @@ -144,6 +152,15 @@ namespace Encompass return engine; } + /// + /// Registers a draw layer. This must be done before any Renderers are registered. + /// + /// The draw layer to register. + public void RegisterDrawLayer(int layer) + { + drawLayerManager.RegisterDrawLayer(layer); + } + /// /// Adds the specified OrderedRenderer to the World. /// @@ -319,8 +336,12 @@ namespace Encompass var engineOrder = new List(); - foreach (var registeredComponentType in registeredComponentTypes) + foreach (var registeredComponentType in componentTypesToRegister) { + var method = typeof(WorldBuilder).GetMethod("RegisterComponentType", BindingFlags.NonPublic | BindingFlags.Instance); + var generic = method.MakeGenericMethod(registeredComponentType); + generic.Invoke(this, null); + var emitterEngine = (Engine)Activator.CreateInstance(typeof(ComponentEmitter<>).MakeGenericType(registeredComponentType)); AddEngine(emitterEngine); engineOrder.Add(emitterEngine);