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 internal class ComponentEmitter<TComponent> : Engine where TComponent : struct, IComponent
{ {
public ComponentEmitter()
{
sendTypes.Add(typeof(TComponent));
}
public override void Update(double dt) public override void Update(double dt)
{ {
foreach (var (component, entity) in InternalRead<TComponent>()) foreach (var (component, entity) in InternalRead<TComponent>())

View File

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Reflection; using System.Reflection;
namespace Encompass namespace Encompass
@ -7,13 +8,17 @@ namespace Encompass
internal class UberEngine : Engine internal class UberEngine : Engine
{ {
private IEnumerable<Type> _componentTypes; private IEnumerable<Type> _componentTypes;
private IEnumerable<Type> _messageTypes;
private Entity _entity; private Entity _entity;
public UberEngine(Entity entity, IEnumerable<Type> componentTypes) public UberEngine(Entity entity, IEnumerable<Type> componentTypes, IEnumerable<Type> messageTypes)
{ {
_componentTypes = componentTypes; _componentTypes = componentTypes;
_messageTypes = messageTypes;
readTypes.UnionWith(componentTypes); readTypes.UnionWith(componentTypes);
writeTypes.UnionWith(componentTypes); writeTypes.UnionWith(componentTypes);
sendTypes.UnionWith(messageTypes);
receiveTypes.UnionWith(messageTypes);
_entity = entity; _entity = entity;
} }
@ -43,6 +48,16 @@ namespace Encompass
CallGenericMethod(type, "DestroyWith", null); CallGenericMethod(type, "DestroyWith", null);
CallGenericMethod(type, "DestroyAllWith", 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) private void CallGenericMethod(Type type, string methodName, object[] parameters)
@ -58,5 +73,12 @@ namespace Encompass
var genericReadComponentMethod = readComponentMethod.MakeGenericMethod(type); var genericReadComponentMethod = readComponentMethod.MakeGenericMethod(type);
genericReadComponentMethod.Invoke(this, parameters); 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.Collections.Generic;
using System.Reflection; using System.Reflection;
using System.Linq; using System.Linq;
@ -37,6 +37,8 @@ namespace Encompass
private readonly HashSet<Type> componentTypesToRegister = new HashSet<Type>(); private readonly HashSet<Type> componentTypesToRegister = new HashSet<Type>();
private readonly HashSet<Type> messageTypes = new HashSet<Type>();
public WorldBuilder() public WorldBuilder()
{ {
drawLayerManager = new DrawLayerManager(); drawLayerManager = new DrawLayerManager();
@ -98,6 +100,11 @@ namespace Encompass
startingComponentStoreForComponentUpdateManager.RegisterComponentType<TComponent>(); startingComponentStoreForComponentUpdateManager.RegisterComponentType<TComponent>();
} }
internal void RegisterMessageTypes(IEnumerable<Type> types)
{
messageTypes.UnionWith(types);
}
internal void AddComponentTypeToRegister(Type componentType) internal void AddComponentTypeToRegister(Type componentType)
{ {
componentTypesToRegister.Add(componentType); componentTypesToRegister.Add(componentType);
@ -121,6 +128,8 @@ namespace Encompass
var messageReceiveTypes = engine.receiveTypes; var messageReceiveTypes = engine.receiveTypes;
var messageSendTypes = engine.sendTypes; var messageSendTypes = engine.sendTypes;
RegisterMessageTypes(engine.receiveTypes.Union(engine.sendTypes));
foreach (var writePendingType in engine.writePendingTypes.Intersect(engine.readPendingTypes)) 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); 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); engineOrder.Add(emitterEngine);
} }
PreloadJIT(componentTypesToRegister); PreloadJIT(componentTypesToRegister, messageTypes);
foreach (var engine in engineGraph.TopologicalSort()) foreach (var engine in engineGraph.TopologicalSort())
{ {
@ -379,7 +388,7 @@ namespace Encompass
/// This is necessary because Encompass heavily uses generic methods with value types, /// 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. /// so the first time any code path runs the JIT gets smashed. This method warms up the runtime.
/// </summary> /// </summary>
private void PreloadJIT(IEnumerable<Type> componentTypes) private void PreloadJIT(IEnumerable<Type> componentTypes, IEnumerable<Type> messageTypes)
{ {
var dummyTimeManager = new TimeManager(); var dummyTimeManager = new TimeManager();
var dummyMessageManager = new MessageManager(dummyTimeManager); var dummyMessageManager = new MessageManager(dummyTimeManager);
@ -390,7 +399,7 @@ namespace Encompass
var dummyRenderManager = new RenderManager(dummyDrawLayerManager); var dummyRenderManager = new RenderManager(dummyDrawLayerManager);
var prepEngineOrder = new List<Engine>(); var prepEngineOrder = new List<Engine>();
var uberEngine = new UberEngine(dummyEntityManager.CreateEntity(), componentTypes); var uberEngine = new UberEngine(dummyEntityManager.CreateEntity(), componentTypes, messageTypes);
uberEngine.AssignEntityManager(dummyEntityManager); uberEngine.AssignEntityManager(dummyEntityManager);
uberEngine.AssignComponentManager(dummyComponentManager); uberEngine.AssignComponentManager(dummyComponentManager);