initial JIT preload

pull/5/head
evan 2019-12-16 18:51:45 -08:00
parent 629e23e98c
commit 67ac748a29
6 changed files with 127 additions and 23 deletions

View File

@ -18,6 +18,7 @@ namespace Encompass
existingAndPendingComponentStore.RegisterComponentType<TComponent>(); existingAndPendingComponentStore.RegisterComponentType<TComponent>();
existingComponentStore.RegisterComponentType<TComponent>(); existingComponentStore.RegisterComponentType<TComponent>();
pendingComponentStore.RegisterComponentType<TComponent>(); pendingComponentStore.RegisterComponentType<TComponent>();
UpToDateComponentStore.RegisterComponentType<TComponent>();
} }
internal void Clear() internal void Clear()

View File

@ -16,6 +16,11 @@ namespace Encompass
public IEnumerable<int> LayerOrder { get { return layerOrder.Values; } } public IEnumerable<int> LayerOrder { get { return layerOrder.Values; } }
public DrawLayerManager()
{
RegisterDrawLayer(0);
}
public void RegisterDrawLayer(int layer) public void RegisterDrawLayer(int layer)
{ {
if (!layerIndexToComponentStore.ContainsKey(layer)) if (!layerIndexToComponentStore.ContainsKey(layer))
@ -27,8 +32,12 @@ namespace Encompass
} }
public void RegisterOrderedDrawable<TComponent>() where TComponent : struct, IComponent public void RegisterOrderedDrawable<TComponent>() where TComponent : struct, IComponent
{
if (!typeToEntityToLayer.ContainsKey(typeof(TComponent)))
{ {
typeToEntityToLayer.Add(typeof(TComponent), new Dictionary<Entity, int>(128)); typeToEntityToLayer.Add(typeof(TComponent), new Dictionary<Entity, int>(128));
}
foreach (var pair in layerIndexToComponentStore) foreach (var pair in layerIndexToComponentStore)
{ {
pair.Value.RegisterComponentType<TComponent>(); pair.Value.RegisterComponentType<TComponent>();

View File

@ -1,33 +1,60 @@
using System; using System;
using System.Collections.Generic;
using System.Reflection; using System.Reflection;
namespace Encompass namespace Encompass
{ {
internal class UberEngine : Engine internal class UberEngine : Engine
{ {
private IEnumerable<Type> _componentTypes;
private Entity _entity;
public UberEngine(Entity entity, IEnumerable<Type> componentTypes)
{
_componentTypes = componentTypes;
readTypes.UnionWith(componentTypes);
writeTypes.UnionWith(componentTypes);
_entity = entity;
}
public void Write()
{
foreach (var type in _componentTypes)
{
var instanceParam = new object[] { _entity, Activator.CreateInstance(type) };
var setComponentMethod = typeof(Engine).GetMethod("SetComponent", BindingFlags.NonPublic | BindingFlags.Instance);
var genericSetComponentMethod = setComponentMethod.MakeGenericMethod(type);
genericSetComponentMethod.Invoke(this, instanceParam);
}
}
public override void Update(double dt) public override void Update(double dt)
{ {
foreach (var type in readTypes) foreach (var type in _componentTypes)
{ {
var instanceParam = new object[] { Activator.CreateInstance(type) }; CallGenericMethod(type, "ReadComponent", null);
CallGenericMethod(type, "ReadComponentIncludingEntity", null);
CallMethodByName(type, "ReadComponent", null); CallGenericMethod(type, "ReadComponents", null);
CallMethodByName(type, "ReadComponentIncludingEntity", null); CallGenericMethod(type, "ReadComponentsIncludingEntity", null);
CallMethodByName(type, "ReadComponents", null); CallGenericMethod(type, "GetComponent", new Type[] { typeof(Entity) }, new object[] { _entity });
CallMethodByName(type, "ReadComponentsIncludingEntity", null); CallGenericMethod(type, "HasComponent", new Type[] { typeof(Entity) }, new object[] { _entity });
CallMethodByName(type, "GetComponent", null); CallGenericMethod(type, "SomeComponent", null);
CallMethodByName(type, "SetComponent", instanceParam); CallGenericMethod(type, "RemoveComponent", new Type[] { typeof(Entity) }, new object[] { _entity });
CallMethodByName(type, "HasComponent", null); CallGenericMethod(type, "DestroyWith", null);
CallMethodByName(type, "SomeComponent", null); CallGenericMethod(type, "DestroyAllWith", null);
CallMethodByName(type, "RemoveComponent", null);
CallMethodByName(type, "DestroyWith", null);
CallMethodByName(type, "DestroyAllWith", null);
} }
} }
private void CallMethodByName(Type type, string methodName, object[] parameters) private void CallGenericMethod(Type type, string methodName, object[] parameters)
{ {
var readComponentMethod = typeof(WorldBuilder).GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance); var readComponentMethod = typeof(Engine).GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance);
var genericReadComponentMethod = readComponentMethod.MakeGenericMethod(type);
genericReadComponentMethod.Invoke(this, parameters);
}
private void CallGenericMethod(Type type, string methodName, Type[] types, object[] parameters)
{
var readComponentMethod = typeof(Engine).GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance, null, types, null);
var genericReadComponentMethod = readComponentMethod.MakeGenericMethod(type); var genericReadComponentMethod = readComponentMethod.MakeGenericMethod(type);
genericReadComponentMethod.Invoke(this, parameters); genericReadComponentMethod.Invoke(this, parameters);
} }

View File

@ -78,6 +78,7 @@ namespace Encompass
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>(); RegisterComponentType<TComponent>();
componentTypesToRegister.Add(typeof(TComponent));
startingComponentStoreForComponentManager.Set(entity, component); startingComponentStoreForComponentManager.Set(entity, component);
startingComponentStoreForComponentUpdateManager.Set(entity, component); startingComponentStoreForComponentUpdateManager.Set(entity, component);
@ -85,6 +86,7 @@ namespace Encompass
if (component is IDrawableComponent drawableComponent) if (component is IDrawableComponent drawableComponent)
{ {
componentManager.RegisterDrawableComponent(entity, component, drawableComponent.Layer); componentManager.RegisterDrawableComponent(entity, component, drawableComponent.Layer);
drawLayerManager.RegisterOrderedDrawable<TComponent>();
} }
} }
@ -350,6 +352,8 @@ namespace Encompass
engineOrder.Add(emitterEngine); engineOrder.Add(emitterEngine);
} }
PreloadJIT(componentTypesToRegister);
foreach (var engine in engineGraph.TopologicalSort()) foreach (var engine in engineGraph.TopologicalSort())
{ {
engineOrder.Add(engine); engineOrder.Add(engine);
@ -377,14 +381,67 @@ namespace Encompass
/// </summary> /// </summary>
private void PreloadJIT(IEnumerable<Type> componentTypes) private void PreloadJIT(IEnumerable<Type> componentTypes)
{ {
var dummyWorldBuilder = new WorldBuilder(); var dummyTimeManager = new TimeManager();
var dummyMessageManager = new MessageManager(dummyTimeManager);
var dummyDrawLayerManager = new DrawLayerManager();
var dummyComponentUpdateManager = new ComponentUpdateManager();
var dummyComponentManager = new ComponentManager(dummyDrawLayerManager, dummyComponentUpdateManager);
var dummyEntityManager = new EntityManager(dummyComponentManager);
var dummyRenderManager = new RenderManager(dummyDrawLayerManager);
dummyWorldBuilder.AddEngine(new UberEngine()); var prepEngineOrder = new List<Engine>();
var uberEngine = new UberEngine(dummyEntityManager.CreateEntity(), componentTypes);
var dummyWorld = dummyWorldBuilder.Build(); uberEngine.AssignEntityManager(dummyEntityManager);
uberEngine.AssignComponentManager(dummyComponentManager);
uberEngine.AssignMessageManager(dummyMessageManager);
uberEngine.AssignComponentUpdateManager(dummyComponentUpdateManager);
uberEngine.AssignTimeManager(dummyTimeManager);
foreach (var type in componentTypes)
{
var componentManagerRegisterMethod = typeof(ComponentManager).GetMethod("RegisterComponentType");
var componentManagerRegisterGenericMethod = componentManagerRegisterMethod.MakeGenericMethod(type);
componentManagerRegisterGenericMethod.Invoke(dummyComponentManager, null);
var componentUpdateManagerRegisterMethod = typeof(ComponentUpdateManager).GetMethod("RegisterComponentType");
var componentUpdateManagerRegisterGenericMethod = componentUpdateManagerRegisterMethod.MakeGenericMethod(type);
componentUpdateManagerRegisterGenericMethod.Invoke(dummyComponentUpdateManager, null);
if (type.GetInterface("IDrawableComponent") != null)
{
var drawLayerManagerRegisterMethod = typeof(DrawLayerManager).GetMethod("RegisterOrderedDrawable");
var drawLayerManagerRegisterGenericMethod = drawLayerManagerRegisterMethod.MakeGenericMethod(type);
drawLayerManagerRegisterGenericMethod.Invoke(dummyDrawLayerManager, null);
}
var emitterEngine = (Engine)Activator.CreateInstance(typeof(ComponentEmitter<>).MakeGenericType(type));
emitterEngine.AssignEntityManager(dummyEntityManager);
emitterEngine.AssignComponentManager(dummyComponentManager);
emitterEngine.AssignMessageManager(dummyMessageManager);
emitterEngine.AssignComponentUpdateManager(dummyComponentUpdateManager);
emitterEngine.AssignTimeManager(dummyTimeManager);
prepEngineOrder.Add(emitterEngine);
}
prepEngineOrder.Add(uberEngine);
var dummyWorld = new World(
prepEngineOrder,
dummyEntityManager,
dummyComponentManager,
dummyMessageManager,
dummyComponentUpdateManager,
dummyTimeManager,
dummyRenderManager
);
uberEngine.Write();
dummyComponentManager.WriteComponents();
dummyComponentUpdateManager.Clear();
dummyWorld.Update(1); dummyWorld.Update(1);
dummyWorld.Draw();
} }
} }
} }

View File

@ -48,6 +48,8 @@ namespace Tests
public void RenderMethodCalledOnWorldDraw() public void RenderMethodCalledOnWorldDraw()
{ {
var worldBuilder = new WorldBuilder(); var worldBuilder = new WorldBuilder();
worldBuilder.RegisterDrawLayer(2);
var renderer = worldBuilder.AddOrderedRenderer(new CalledRenderer()); var renderer = worldBuilder.AddOrderedRenderer(new CalledRenderer());
AComponent aComponent; AComponent aComponent;
@ -86,6 +88,8 @@ namespace Tests
calledOnDraw = false; calledOnDraw = false;
var worldBuilder = new WorldBuilder(); var worldBuilder = new WorldBuilder();
worldBuilder.RegisterDrawLayer(1);
worldBuilder.AddEngine(new DestroyerEngine()); worldBuilder.AddEngine(new DestroyerEngine());
var renderer = worldBuilder.AddOrderedRenderer(new CalledRenderer()); var renderer = worldBuilder.AddOrderedRenderer(new CalledRenderer());

View File

@ -39,6 +39,12 @@ namespace Tests
public void DrawOrder() public void DrawOrder()
{ {
var worldBuilder = new WorldBuilder(); var worldBuilder = new WorldBuilder();
worldBuilder.RegisterDrawLayer(1);
worldBuilder.RegisterDrawLayer(2);
worldBuilder.RegisterDrawLayer(3);
worldBuilder.RegisterDrawLayer(4);
worldBuilder.RegisterDrawLayer(7);
worldBuilder.AddOrderedRenderer(new TestEntityRenderer()); worldBuilder.AddOrderedRenderer(new TestEntityRenderer());
var testGeneralRenderer = worldBuilder.AddGeneralRenderer(new TestGeneralRenderer(), 7); var testGeneralRenderer = worldBuilder.AddGeneralRenderer(new TestGeneralRenderer(), 7);