encompass-cs/encompass-cs/UberEngine.cs

122 lines
5.6 KiB
C#
Raw Normal View History

2019-12-17 03:55:27 +00:00
using System;
2019-12-17 02:51:45 +00:00
using System.Collections.Generic;
2019-12-17 03:55:27 +00:00
using System.Linq;
using System.Reflection;
2020-03-22 21:04:09 +00:00
using System.Runtime.CompilerServices;
namespace Encompass
{
internal class UberEngine : Engine
{
2020-03-20 07:09:57 +00:00
private readonly IEnumerable<Type> _componentTypes;
private readonly IEnumerable<Type> _messageTypes;
public Entity Entity { get; private set; }
2019-12-17 02:51:45 +00:00
public UberEngine(IEnumerable<Type> componentTypes, IEnumerable<Type> messageTypes)
2019-12-17 02:51:45 +00:00
{
_componentTypes = componentTypes;
2019-12-17 03:55:27 +00:00
_messageTypes = messageTypes;
2020-03-20 07:09:57 +00:00
ReadTypes.UnionWith(componentTypes);
WriteTypes.UnionWith(componentTypes);
SendTypes.UnionWith(messageTypes);
ReceiveTypes.UnionWith(messageTypes);
2019-12-17 02:51:45 +00:00
}
public void Write()
{
Entity = CreateEntity();
2019-12-17 02:51:45 +00:00
foreach (var type in _componentTypes)
{
var instanceParam = new object[] { Entity, Activator.CreateInstance(type) };
2019-12-17 02:51:45 +00:00
var setComponentMethod = typeof(Engine).GetMethod("SetComponent", BindingFlags.NonPublic | BindingFlags.Instance);
var genericSetComponentMethod = setComponentMethod.MakeGenericMethod(type);
genericSetComponentMethod.Invoke(this, instanceParam);
}
}
2019-12-17 02:51:45 +00:00
public override void Update(double dt)
{
foreach (var type in _componentTypes)
{
CallGenericMethod(type, "ReadComponent", null);
2020-03-25 04:28:56 +00:00
CallGenericWrappedMethod(type, "ReadComponentsWrapper", null);
2019-12-17 04:16:46 +00:00
CallGenericMethod(type, "ReadEntity", null);
2020-03-25 04:28:56 +00:00
CallGenericWrappedMethod(type, "ReadEntitiesWrapper", null);
2020-03-23 02:10:28 +00:00
CallGenericMethod(type, "GetComponent", new object[] { Entity });
CallGenericMethod(type, "HasComponent", 1, new object[] { Entity });
2019-12-17 02:51:45 +00:00
CallGenericMethod(type, "SomeComponent", null);
CallGenericMethod(type, "DestroyWith", null);
CallGenericMethod(type, "DestroyAllWith", null);
2020-03-23 02:10:28 +00:00
CallGenericMethod(type, "RemoveComponent", new object[] { Entity });
}
2019-12-17 03:55:27 +00:00
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);
2020-03-22 20:41:55 +00:00
2020-03-25 04:28:56 +00:00
CallGenericWrappedMethod(type, "ReadMessagesWrapper", null);
2019-12-17 03:55:27 +00:00
CallGenericMethod(type, "SomeMessage", null);
2019-12-30 07:55:48 +00:00
if (typeof(IHasEntity).IsAssignableFrom(type))
{
2020-03-23 02:10:28 +00:00
CallGenericMethod(type, "ReadMessagesWithEntity", new object[] { Entity });
CallGenericMethod(type, "ReadMessageWithEntity", new object[] { Entity });
CallGenericMethod(type, "SomeMessageWithEntity", new object[] { Entity });
2019-12-30 07:55:48 +00:00
}
2019-12-17 03:55:27 +00:00
}
}
2020-03-25 04:28:56 +00:00
// we can't reflect invoke on Span returns right now... so we have non-return wrapper methods
protected void ReadComponentsWrapper<TComponent>() where TComponent : struct, IComponent
{
ReadComponents<TComponent>();
}
protected void ReadMessagesWrapper<TMessage>() where TMessage : struct, IMessage
{
ReadMessages<TMessage>();
}
protected void ReadEntitiesWrapper<TComponent>() where TComponent : struct, IComponent
{
ReadEntities<TComponent>();
}
2020-03-22 21:04:09 +00:00
// trying to use PrepareMethod because we can't reflect invoke methods that return a span...
2019-12-17 02:51:45 +00:00
private void CallGenericMethod(Type type, string methodName, object[] parameters)
{
var readComponentMethod = typeof(Engine).GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance);
var genericReadComponentMethod = readComponentMethod.MakeGenericMethod(type);
2020-03-23 02:10:28 +00:00
genericReadComponentMethod.Invoke(this, parameters);
// RuntimeHelpers.PrepareMethod(genericReadComponentMethod.MethodHandle);
2019-12-17 02:51:45 +00:00
}
2020-03-25 04:28:56 +00:00
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);
}
2019-12-17 02:51:45 +00:00
private void CallGenericMethod(Type type, string methodName, Type[] types, object[] parameters)
{
2019-12-17 02:51:45 +00:00
var readComponentMethod = typeof(Engine).GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance, null, types, null);
var genericReadComponentMethod = readComponentMethod.MakeGenericMethod(type);
2020-03-23 02:10:28 +00:00
genericReadComponentMethod.Invoke(this, parameters);
// RuntimeHelpers.PrepareMethod(genericReadComponentMethod.MethodHandle);
}
2019-12-17 03:55:27 +00:00
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);
2020-03-23 02:10:28 +00:00
genericMethod.Invoke(this, parameters);
// RuntimeHelpers.PrepareMethod(genericMethod.MethodHandle);
2019-12-17 03:55:27 +00:00
}
}
}