using MoonTools.ECS; using Nerfed.Editor.Systems; using Nerfed.Runtime; using Nerfed.Runtime.Components; using Nerfed.Runtime.Scheduling; using Nerfed.Runtime.Systems; using Nerfed.Runtime.Systems.Synthetic; using Nerfed.Runtime.Util; using System.Numerics; namespace Nerfed.Editor; internal class Program { private static readonly World world = new World(); private static List systems = new List(); private static SystemScheduler scheduler; public static List editorSystems = new List(); private static bool enableDummySchedulerHarness; private static bool enableParallelSystemExecution; private static void Main(string[] args) { enableDummySchedulerHarness = args.Contains("--dummy-scheduler-test", StringComparer.OrdinalIgnoreCase); enableParallelSystemExecution = args.Contains("--parallel-systems", StringComparer.OrdinalIgnoreCase); scheduler = new SystemScheduler(new SystemSchedulerOptions { EnableParallelSystemExecution = enableParallelSystemExecution, StrictDependencyValidation = true, }); Engine.OnInitialize += HandleOnInitialize; Engine.OnUpdate += HandleOnUpdate; Engine.OnRender += HandleOnRender; Engine.OnQuit += HandleOnQuit; Engine.Run(args); } private static void HandleOnInitialize() { //systems.Add(new ParentSystem(world)); LocalToWorldSystem localToWorldSystem = new LocalToWorldSystem(world); systems.Add(localToWorldSystem); scheduler.Register(localToWorldSystem, SystemSchedulePhase.Simulation); if (enableDummySchedulerHarness) { DummyLongJobSharedState sharedState = new DummyLongJobSharedState(); // Producer starts long work, middle system burns time on main thread, consumer acts as a barrier. DummyLongJobProducerSystem producer = new DummyLongJobProducerSystem( world, sharedState, JobSystem.Default, TimeSpan.FromMilliseconds(6), DummyWorkloadMode.Compute, JobDeadlineMode.FrameCritical); systems.Add(producer); scheduler.Register(producer, SystemSchedulePhase.Simulation); DummyMainThreadWorkSystem mainThreadWork = new DummyMainThreadWorkSystem( world, TimeSpan.FromMilliseconds(2), DummyWorkloadMode.Compute, nameof(DummyMainThreadWorkSystem)); systems.Add(mainThreadWork); scheduler.Register(mainThreadWork, SystemSchedulePhase.Simulation); DummyLongJobConsumerSystem consumer = new DummyLongJobConsumerSystem( world, sharedState, JobSystem.Default, requireCompletion: true); systems.Add(consumer); scheduler.Register(consumer, SystemSchedulePhase.LateSimulation, nameof(DummyLongJobProducerSystem)); } editorSystems.Add(new EditorProfilerWindow(world)); editorSystems.Add(new EditorHierarchyWindow(world)); #if DEBUG editorSystems.Add(new EditorInspectorWindow(world)); #endif Entity ent1 = world.CreateEntity("parent"); world.Set(ent1, new Root()); world.Set(ent1, new LocalTransform(new Vector3(1, 0, 0), Quaternion.Identity, Vector3.One)); Entity ent2 = world.CreateEntity("child"); world.Set(ent2, new LocalTransform(new Vector3(0, 1, 0), Quaternion.Identity, Vector3.One)); Transform.SetParent(world, ent2, ent1); Entity ent3 = world.CreateEntity("entity3"); world.Set(ent3, new Root()); Transform.SetParent(world, ent3, ent2); Entity ent4 = world.CreateEntity("entity4"); world.Set(ent4, new Root()); Entity ent5 = world.CreateBaseEntity("entity5"); for (int i = 0; i < 256; i++) { Entity newEnt = world.CreateBaseEntity(); world.Set(newEnt, new LocalTransform(new Vector3(i, i, i), Quaternion.Identity, Vector3.One)); Entity parent = newEnt; for (int j = 0; j < 2; j++) { Entity newChildEnt = world.CreateEntity(); world.Set(newChildEnt, new LocalTransform(new Vector3(i + j * i, i - j * i, j - i * i), Quaternion.Identity, Vector3.One)); Transform.SetParent(world, newChildEnt, parent); parent = newChildEnt; } } // Open project. // Setip EditorGui. EditorGui.Initialize(); } private static void HandleOnUpdate() { using (new ProfilerScope("SystemScheduler.Execute")) { scheduler.Execute(Engine.Timestep); } using (new ProfilerScope("EditorGui.Update")) { // Editor Update. EditorGui.Update(); } // Try Catch UserCode Update. using (new ProfilerScope("world.FinishUpdate")) { world.FinishUpdate(); } } private static void HandleOnRender() { using (new ProfilerScope("EditorGui.Render")) { EditorGui.Render(); } } private static void HandleOnQuit() { EditorGui.Quit(); } }