encompass-cs/encompass-cs/UberEngine.cs

98 lines
3.6 KiB
C#

using System;
using System.Collections.Generic;
using System.Reflection;
namespace Encompass
{
internal class UberEngine : Engine
{
private readonly IEnumerable<Type> _componentTypes;
private readonly IEnumerable<Type> _messageTypes;
public Entity Entity { get; private set; }
public UberEngine(IEnumerable<Type> componentTypes, IEnumerable<Type> messageTypes)
{
_componentTypes = componentTypes;
_messageTypes = messageTypes;
AddTypes.UnionWith(componentTypes);
ReadTypes.UnionWith(componentTypes);
WriteTypes.UnionWith(componentTypes);
SendTypes.UnionWith(messageTypes);
ReceiveTypes.UnionWith(messageTypes);
}
public void Write()
{
Entity = CreateEntity();
foreach (var type in _componentTypes)
{
var instance = Activator.CreateInstance(type);
var instanceParam = new object[] { Entity, instance };
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)
{
foreach (var type in _componentTypes)
{
CallGenericWrappedMethod(type, "CallAllComponentMethods", null);
}
foreach (var type in _messageTypes)
{
CallGenericWrappedMethod(type, "CallAllMessageMethods", null);
if (typeof(IHasEntity).IsAssignableFrom(type))
{
CallGenericWrappedMethod(type, "CallAllEntityMessageMethods", null);
}
}
}
// we can't reflect invoke on byref returns or Span returns right now... so we have non-return wrapper methods
protected void CallAllComponentMethods<TComponent>() where TComponent : struct
{
ReadComponent<TComponent>();
ReadComponents<TComponent>();
ReadEntity<TComponent>();
ReadEntities<TComponent>();
GetComponent<TComponent>(Entity);
HasComponent<TComponent>(Entity);
SomeComponent<TComponent>();
DestroyWith<TComponent>();
DestroyAllWith<TComponent>();
RemoveComponent<TComponent>(Entity);
AddComponent<TComponent>(Entity, default);
}
protected void CallAllMessageMethods<TMessage>() where TMessage : struct
{
SendMessageIgnoringTimeDilation<TMessage>(default, 0.1);
SendMessage<TMessage>(default);
SendMessage<TMessage>(default, 0.1);
ReadMessage<TMessage>();
ReadMessages<TMessage>();
SomeMessage<TMessage>();
}
protected void CallAllEntityMessageMethods<TMessage>() where TMessage : struct, IHasEntity
{
ReadMessagesWithEntity<TMessage>(Entity);
ReadMessageWithEntity<TMessage>(Entity);
SomeMessageWithEntity<TMessage>(Entity);
}
private void CallGenericWrappedMethod(Type type, string methodName, object[] parameters)
{
var readComponentMethod = typeof(UberEngine).GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance);
var genericReadComponentMethod = readComponentMethod.MakeGenericMethod(type);
genericReadComponentMethod.Invoke(this, parameters);
}
}
}