feat: integrate composable Godot runtime and EventBus debugger
This commit is contained in:
55 files changed
+1481
-114
No files matched your search
@@ -0,0 +1,96 @@
|
||||
#nullable enable
|
||||
|
||||
using System;
|
||||
using System.Threading;
|
||||
using EntJoy.ECS;
|
||||
using EntJoy.JobSystem;
|
||||
using Godot;
|
||||
using ShrinkSDK.Godot;
|
||||
|
||||
namespace ShrinkSDK.EntJoy.Godot;
|
||||
|
||||
/// <summary>Godot node that owns an EntJoy World and advances its frame boundary.</summary>
|
||||
public partial class ShrinkEntJoyHost : ShrinkGodotHost
|
||||
{
|
||||
private static readonly object SchedulerGate = new();
|
||||
private static int SchedulerUsers;
|
||||
private bool _schedulerAcquired;
|
||||
private bool _worldDisposed;
|
||||
private ulong _lastFrame = ulong.MaxValue;
|
||||
private SceneTree? _tree;
|
||||
|
||||
[Export] public string EntJoyWorldName { get; set; } = "GodotWorld";
|
||||
|
||||
public World? EntJoyWorld { get; private set; }
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
base._Ready();
|
||||
AcquireScheduler();
|
||||
EntJoyWorld = new World(EntJoyWorldName);
|
||||
World.DefaultWorld = EntJoyWorld;
|
||||
_tree = GetTree();
|
||||
_tree.ProcessFrame += OnProcessFrame;
|
||||
TreeExited += OnTreeExited;
|
||||
}
|
||||
|
||||
public override void _Process(double delta)
|
||||
{
|
||||
base._Process(delta);
|
||||
Advance();
|
||||
}
|
||||
|
||||
private void OnProcessFrame() => Advance();
|
||||
|
||||
private void Advance()
|
||||
{
|
||||
if (EntJoyWorld == null || _worldDisposed) return;
|
||||
var frame = Engine.GetProcessFrames();
|
||||
if (frame == _lastFrame) return;
|
||||
_lastFrame = frame;
|
||||
EntJoyWorld.NextFrameEvents();
|
||||
NativeJobScheduler.EndFrame();
|
||||
EntJoyWorld.CurrentFrame++;
|
||||
}
|
||||
|
||||
public override void _ExitTree()
|
||||
{
|
||||
DisposeWorld();
|
||||
base._ExitTree();
|
||||
}
|
||||
|
||||
private void OnTreeExited()
|
||||
{
|
||||
if (_tree != null)
|
||||
_tree.ProcessFrame -= OnProcessFrame;
|
||||
_tree = null;
|
||||
TreeExited -= OnTreeExited;
|
||||
DisposeWorld();
|
||||
}
|
||||
|
||||
private void AcquireScheduler()
|
||||
{
|
||||
lock (SchedulerGate)
|
||||
{
|
||||
if (SchedulerUsers++ == 0)
|
||||
NativeJobScheduler.Initialize();
|
||||
_schedulerAcquired = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void DisposeWorld()
|
||||
{
|
||||
if (_worldDisposed) return;
|
||||
_worldDisposed = true;
|
||||
EntJoyWorld?.Dispose();
|
||||
EntJoyWorld = null;
|
||||
|
||||
if (!_schedulerAcquired) return;
|
||||
lock (SchedulerGate)
|
||||
{
|
||||
_schedulerAcquired = false;
|
||||
if (--SchedulerUsers == 0)
|
||||
NativeJobScheduler.Shutdown();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user