generating stores at init time

pull/5/head
Evan Hemsley 2019-12-15 23:28:02 -08:00
parent f904f566ac
commit db8964b54c
7 changed files with 85 additions and 40 deletions

View File

@ -15,13 +15,19 @@ namespace Encompass
} }
} }
private TypedComponentStore<TComponent> Lookup<TComponent>() where TComponent : struct, IComponent public void RegisterComponentType<TComponent>() where TComponent : struct, IComponent
{ {
if (!Stores.ContainsKey(typeof(TComponent))) if (!Stores.ContainsKey(typeof(TComponent)))
{ {
System.Console.WriteLine("register component type in component store");
var store = new TypedComponentStore<TComponent>(); var store = new TypedComponentStore<TComponent>();
Stores.Add(typeof(TComponent), store); Stores.Add(typeof(TComponent), store);
} }
}
private TypedComponentStore<TComponent> Lookup<TComponent>() where TComponent : struct, IComponent
{
//RegisterComponentType<TComponent>();
return Stores[typeof(TComponent)] as TypedComponentStore<TComponent>; return Stores[typeof(TComponent)] as TypedComponentStore<TComponent>;
} }

View File

@ -17,6 +17,11 @@ namespace Encompass
this.componentUpdateManager = componentUpdateManager; this.componentUpdateManager = componentUpdateManager;
} }
public void RegisterComponentType<TComponent>() where TComponent : struct, IComponent
{
componentStore.RegisterComponentType<TComponent>();
}
internal void SetComponentStore(ComponentStore componentStore) internal void SetComponentStore(ComponentStore componentStore)
{ {
this.componentStore.SwapWith(componentStore); this.componentStore.SwapWith(componentStore);

View File

@ -13,6 +13,13 @@ namespace Encompass
public ComponentStore UpToDateComponentStore { get; private set; } = new ComponentStore(); public ComponentStore UpToDateComponentStore { get; private set; } = new ComponentStore();
public void RegisterComponentType<TComponent>() where TComponent : struct, IComponent
{
existingAndPendingComponentStore.RegisterComponentType<TComponent>();
existingComponentStore.RegisterComponentType<TComponent>();
pendingComponentStore.RegisterComponentType<TComponent>();
}
internal void Clear() internal void Clear()
{ {
existingAndPendingComponentStore.ClearAll(); existingAndPendingComponentStore.ClearAll();

View File

@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using Encompass.Exceptions;
namespace Encompass namespace Encompass
{ {
@ -15,26 +16,32 @@ namespace Encompass
public IEnumerable<int> LayerOrder { get { return layerOrder.Values; } } public IEnumerable<int> LayerOrder { get { return layerOrder.Values; } }
public void RegisterGeneralRendererWithLayer(GeneralRenderer renderer, int layer) public void RegisterDrawLayer(int layer)
{ {
if (layerIndexToGeneralRenderers.ContainsKey(layer)) if (!layerIndexToComponentStore.ContainsKey(layer))
{
var set = layerIndexToGeneralRenderers[layer];
set.Add(renderer);
}
else
{
var set = new HashSet<GeneralRenderer>();
layerIndexToGeneralRenderers.Add(layer, set);
set.Add(renderer);
}
if (!layerOrder.ContainsKey(layer))
{ {
layerOrder.Add(layer, layer); layerOrder.Add(layer, layer);
layerIndexToGeneralRenderers.Add(layer, new HashSet<GeneralRenderer>());
layerIndexToComponentStore.Add(layer, new ComponentStore());
} }
} }
public void RegisterOrderedDrawable<TComponent>() where TComponent : struct, IComponent
{
typeToEntityToLayer.Add(typeof(TComponent), new Dictionary<Entity, int>(128));
foreach (var pair in layerIndexToComponentStore)
{
pair.Value.RegisterComponentType<TComponent>();
}
}
public void RegisterGeneralRendererWithLayer(GeneralRenderer renderer, int layer)
{
RegisterDrawLayer(layer);
var set = layerIndexToGeneralRenderers[layer];
set.Add(renderer);
}
public void UnregisterGeneralRendererWithLayer(GeneralRenderer renderer, int layer) public void UnregisterGeneralRendererWithLayer(GeneralRenderer renderer, int layer)
{ {
if (layerIndexToGeneralRenderers.ContainsKey(layer)) if (layerIndexToGeneralRenderers.ContainsKey(layer))
@ -51,31 +58,17 @@ namespace Encompass
public void RegisterComponentWithLayer<TComponent>(Entity entity, TComponent component, int layer) where TComponent : struct, IComponent public void RegisterComponentWithLayer<TComponent>(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<Entity, int>()); throw new UndefinedLayerException("Layer {0} is not defined. Use WorldBuilder.RegisterDrawLayer to register the layer.", layer);
} }
if (typeToEntityToLayer[typeof(TComponent)].ContainsKey(entity)) { UnRegisterComponentWithLayer<TComponent>(entity); } if (typeToEntityToLayer[typeof(TComponent)].ContainsKey(entity)) { UnRegisterComponentWithLayer<TComponent>(entity); }
if (layerIndexToComponentStore.ContainsKey(layer)) var set = layerIndexToComponentStore[layer];
{ set.Set<TComponent>(entity, component);
var set = layerIndexToComponentStore[layer];
set.Set<TComponent>(entity, component);
}
else
{
var set = new ComponentStore();
layerIndexToComponentStore.Add(layer, set);
set.Set<TComponent>(entity, component);
}
typeToEntityToLayer[typeof(TComponent)].Add(entity, layer); typeToEntityToLayer[typeof(TComponent)].Add(entity, layer);
if (!layerOrder.ContainsKey(layer))
{
layerOrder.Add(layer, layer);
}
} }
public void UnRegisterComponentWithLayer<TComponent>(Entity entity) where TComponent : struct, IComponent public void UnRegisterComponentWithLayer<TComponent>(Entity entity) where TComponent : struct, IComponent

View File

@ -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)) { }
}
}

View File

@ -17,6 +17,7 @@ namespace Encompass
public void RegisterOrderedRenderer<TComponent>(Action<Entity, IComponent> renderAction) where TComponent : struct, IComponent public void RegisterOrderedRenderer<TComponent>(Action<Entity, IComponent> renderAction) where TComponent : struct, IComponent
{ {
drawComponentTypeToOrderedRenderer.Add(typeof(TComponent), renderAction); drawComponentTypeToOrderedRenderer.Add(typeof(TComponent), renderAction);
drawLayerManager.RegisterOrderedDrawable<TComponent>();
} }
public void RegisterGeneralRendererWithLayer(GeneralRenderer renderer, int layer) public void RegisterGeneralRendererWithLayer(GeneralRenderer renderer, int layer)

View File

@ -35,7 +35,7 @@ namespace Encompass
private readonly HashSet<Engine> senders = new HashSet<Engine>(); private readonly HashSet<Engine> senders = new HashSet<Engine>();
private readonly HashSet<Type> registeredComponentTypes = new HashSet<Type>(); private readonly HashSet<Type> componentTypesToRegister = new HashSet<Type>();
public WorldBuilder() public WorldBuilder()
{ {
@ -77,20 +77,28 @@ namespace Encompass
/// </summary> /// </summary>
public void SetComponent<TComponent>(Entity entity, TComponent component) where TComponent : struct, IComponent public void SetComponent<TComponent>(Entity entity, TComponent component) where TComponent : struct, IComponent
{ {
RegisterComponentType<TComponent>();
startingComponentStoreForComponentManager.Set(entity, component); startingComponentStoreForComponentManager.Set(entity, component);
startingComponentStoreForComponentUpdateManager.Set(entity, component); startingComponentStoreForComponentUpdateManager.Set(entity, component);
RegisterComponent(typeof(TComponent));
if (component is IDrawableComponent drawableComponent) if (component is IDrawableComponent drawableComponent)
{ {
componentManager.RegisterDrawableComponent(entity, component, drawableComponent.Layer); componentManager.RegisterDrawableComponent(entity, component, drawableComponent.Layer);
} }
} }
internal void RegisterComponent(Type componentType) internal void RegisterComponentType<TComponent>() where TComponent : struct, IComponent
{ {
registeredComponentTypes.Add(componentType); componentManager.RegisterComponentType<TComponent>();
componentUpdateManager.RegisterComponentType<TComponent>();
startingComponentStoreForComponentManager.RegisterComponentType<TComponent>();
startingComponentStoreForComponentUpdateManager.RegisterComponentType<TComponent>();
}
internal void AddComponentTypeToRegister(Type componentType)
{
componentTypesToRegister.Add(componentType);
} }
/// <summary> /// <summary>
@ -128,7 +136,7 @@ namespace Encompass
foreach (var componentType in engine.readTypes.Union(engine.writeTypes).Union(engine.readPendingTypes)) 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)) foreach (var receiveType in engine.receiveTypes.Union(engine.readPendingTypes))
@ -144,6 +152,15 @@ namespace Encompass
return engine; return engine;
} }
/// <summary>
/// Registers a draw layer. This must be done before any Renderers are registered.
/// </summary>
/// <param name="layer">The draw layer to register.</param>
public void RegisterDrawLayer(int layer)
{
drawLayerManager.RegisterDrawLayer(layer);
}
/// <summary> /// <summary>
/// Adds the specified OrderedRenderer to the World. /// Adds the specified OrderedRenderer to the World.
/// </summary> /// </summary>
@ -319,8 +336,12 @@ namespace Encompass
var engineOrder = new List<Engine>(); var engineOrder = new List<Engine>();
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)); var emitterEngine = (Engine)Activator.CreateInstance(typeof(ComponentEmitter<>).MakeGenericType(registeredComponentType));
AddEngine(emitterEngine); AddEngine(emitterEngine);
engineOrder.Add(emitterEngine); engineOrder.Add(emitterEngine);