diff --git a/encompass-cs/UberEngine.cs b/encompass-cs/UberEngine.cs new file mode 100644 index 0000000..f27b596 --- /dev/null +++ b/encompass-cs/UberEngine.cs @@ -0,0 +1,35 @@ +using System; +using System.Reflection; + +namespace Encompass +{ + internal class UberEngine : Engine + { + public override void Update(double dt) + { + foreach (var type in readTypes) + { + var instanceParam = new object[] { Activator.CreateInstance(type) }; + + CallMethodByName(type, "ReadComponent", null); + CallMethodByName(type, "ReadComponentIncludingEntity", null); + CallMethodByName(type, "ReadComponents", null); + CallMethodByName(type, "ReadComponentsIncludingEntity", null); + CallMethodByName(type, "GetComponent", null); + CallMethodByName(type, "SetComponent", instanceParam); + CallMethodByName(type, "HasComponent", null); + CallMethodByName(type, "SomeComponent", null); + CallMethodByName(type, "RemoveComponent", null); + CallMethodByName(type, "DestroyWith", null); + CallMethodByName(type, "DestroyAllWith", null); + } + } + + private void CallMethodByName(Type type, string methodName, object[] parameters) + { + var readComponentMethod = typeof(WorldBuilder).GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance); + var genericReadComponentMethod = readComponentMethod.MakeGenericMethod(type); + genericReadComponentMethod.Invoke(this, parameters); + } + } +} diff --git a/encompass-cs/WorldBuilder.cs b/encompass-cs/WorldBuilder.cs index a4efde1..ac84f26 100644 --- a/encompass-cs/WorldBuilder.cs +++ b/encompass-cs/WorldBuilder.cs @@ -149,6 +149,9 @@ namespace Encompass typeToReaders[receiveType].Add(engine); } + // System.Runtime.CompilerServices.RuntimeHelpers.PrepareMethod(typeof(TEngine).GetRuntimeMethod("Update", new Type[] { typeof(double) }).MethodHandle); + // typeof(TEngine).GetMethod("Update", new Type[] { typeof(double) }).MethodHandle.GetFunctionPointer(); + return engine; } @@ -367,5 +370,21 @@ namespace Encompass return world; } + + /// + /// 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. + /// + private void PreloadJIT(IEnumerable componentTypes) + { + var dummyWorldBuilder = new WorldBuilder(); + + dummyWorldBuilder.AddEngine(new UberEngine()); + + var dummyWorld = dummyWorldBuilder.Build(); + + dummyWorld.Update(1); + dummyWorld.Draw(); + } } } diff --git a/test/test.csproj b/test/test.csproj index 5e554ea..8f6a401 100644 --- a/test/test.csproj +++ b/test/test.csproj @@ -15,4 +15,4 @@ - \ No newline at end of file +