message JIT preload

pull/5/head
evan 2019-12-16 19:55:27 -08:00
parent 67ac748a29
commit d8a5cd6493
3 changed files with 38 additions and 12 deletions

View File

@ -1,12 +1,7 @@
namespace Encompass
namespace Encompass
{
internal class ComponentEmitter<TComponent> : Engine where TComponent : struct, IComponent
{
public ComponentEmitter()
{
sendTypes.Add(typeof(TComponent));
}
public override void Update(double dt)
{
foreach (var (component, entity) in InternalRead<TComponent>())

View File

@ -1,5 +1,6 @@
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
namespace Encompass
@ -7,13 +8,17 @@ namespace Encompass
internal class UberEngine : Engine
{
private IEnumerable<Type> _componentTypes;
private IEnumerable<Type> _messageTypes;
private Entity _entity;
public UberEngine(Entity entity, IEnumerable<Type> componentTypes)
public UberEngine(Entity entity, IEnumerable<Type> componentTypes, IEnumerable<Type> messageTypes)
{
_componentTypes = componentTypes;
_messageTypes = messageTypes;
readTypes.UnionWith(componentTypes);
writeTypes.UnionWith(componentTypes);
sendTypes.UnionWith(messageTypes);
receiveTypes.UnionWith(messageTypes);
_entity = entity;
}
@ -43,6 +48,16 @@ namespace Encompass
CallGenericMethod(type, "DestroyWith", null);
CallGenericMethod(type, "DestroyAllWith", null);
}
foreach (var type in _messageTypes)
{
CallGenericMethod(type, "SendMessageIgnoringTimeDilation", new object[] { Activator.CreateInstance(type), 1 });
CallGenericMethod(type, "SendMessage", 1, new object[] { Activator.CreateInstance(type) });
CallGenericMethod(type, "SendMessage", 2, new object[] { Activator.CreateInstance(type), 1 });
CallGenericMethod(type, "ReadMessage", null);
CallGenericMethod(type, "ReadMessages", null);
CallGenericMethod(type, "SomeMessage", null);
}
}
private void CallGenericMethod(Type type, string methodName, object[] parameters)
@ -58,5 +73,12 @@ namespace Encompass
var genericReadComponentMethod = readComponentMethod.MakeGenericMethod(type);
genericReadComponentMethod.Invoke(this, parameters);
}
private void CallGenericMethod(Type type, string methodName, int argumentNum, object[] parameters)
{
var method = typeof(Engine).GetRuntimeMethods().Where(m => m.Name == methodName && m.GetParameters().Length == argumentNum).First();
var genericMethod = method.MakeGenericMethod(type);
genericMethod.Invoke(this, parameters);
}
}
}

View File

@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Linq;
@ -37,6 +37,8 @@ namespace Encompass
private readonly HashSet<Type> componentTypesToRegister = new HashSet<Type>();
private readonly HashSet<Type> messageTypes = new HashSet<Type>();
public WorldBuilder()
{
drawLayerManager = new DrawLayerManager();
@ -98,6 +100,11 @@ namespace Encompass
startingComponentStoreForComponentUpdateManager.RegisterComponentType<TComponent>();
}
internal void RegisterMessageTypes(IEnumerable<Type> types)
{
messageTypes.UnionWith(types);
}
internal void AddComponentTypeToRegister(Type componentType)
{
componentTypesToRegister.Add(componentType);
@ -121,6 +128,8 @@ namespace Encompass
var messageReceiveTypes = engine.receiveTypes;
var messageSendTypes = engine.sendTypes;
RegisterMessageTypes(engine.receiveTypes.Union(engine.sendTypes));
foreach (var writePendingType in engine.writePendingTypes.Intersect(engine.readPendingTypes))
{
throw new EngineSelfCycleException("Engine {0} both writes and reads pending Component {1}", engine.GetType().Name, writePendingType.Name);
@ -352,7 +361,7 @@ namespace Encompass
engineOrder.Add(emitterEngine);
}
PreloadJIT(componentTypesToRegister);
PreloadJIT(componentTypesToRegister, messageTypes);
foreach (var engine in engineGraph.TopologicalSort())
{
@ -379,7 +388,7 @@ namespace Encompass
/// This is necessary because Encompass heavily uses generic methods with value types,
/// so the first time any code path runs the JIT gets smashed. This method warms up the runtime.
/// </summary>
private void PreloadJIT(IEnumerable<Type> componentTypes)
private void PreloadJIT(IEnumerable<Type> componentTypes, IEnumerable<Type> messageTypes)
{
var dummyTimeManager = new TimeManager();
var dummyMessageManager = new MessageManager(dummyTimeManager);
@ -390,7 +399,7 @@ namespace Encompass
var dummyRenderManager = new RenderManager(dummyDrawLayerManager);
var prepEngineOrder = new List<Engine>();
var uberEngine = new UberEngine(dummyEntityManager.CreateEntity(), componentTypes);
var uberEngine = new UberEngine(dummyEntityManager.CreateEntity(), componentTypes, messageTypes);
uberEngine.AssignEntityManager(dummyEntityManager);
uberEngine.AssignComponentManager(dummyComponentManager);