refactor(godot): report subroutines via GodotTraceSink, not the IHost queue
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -42,12 +42,6 @@ public sealed class GodotAdvHost : IHost
|
|||||||
// called from the main thread (click) or the selftest auto-clicker
|
// called from the main thread (click) or the selftest auto-clicker
|
||||||
public void SignalInput() { if (_gate.CurrentCount == 0) _gate.Release(); }
|
public void SignalInput() { if (_gate.CurrentCount == 0) _gate.Release(); }
|
||||||
|
|
||||||
// Records each call-script the VM dispatches (runs on the VM thread, so collect thread-safely and
|
|
||||||
// let the main thread report it — Godot drops GD.Print from background threads).
|
|
||||||
public readonly System.Collections.Concurrent.ConcurrentQueue<long> Dispatched = new();
|
|
||||||
public void CallScript(long id) => Dispatched.Enqueue(id);
|
|
||||||
public void OnStub(int opcode) { }
|
|
||||||
|
|
||||||
// ---- texture ops (run on the VM thread; marshal Godot node work to the main thread) ----
|
// ---- texture ops (run on the VM thread; marshal Godot node work to the main thread) ----
|
||||||
public void CreateTexture(int slot, int width, int height) { _slotBmp[slot] = null; _slotDims[slot] = (width, height); }
|
public void CreateTexture(int slot, int width, int height) { _slotBmp[slot] = null; _slotDims[slot] = (width, height); }
|
||||||
|
|
||||||
|
|||||||
16
godot/GodotTraceSink.cs
Normal file
16
godot/GodotTraceSink.cs
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
using System.Collections.Concurrent;
|
||||||
|
using Age.Engine.Diagnostics;
|
||||||
|
|
||||||
|
// Frontend-side trace consumer. Runs on the VM background thread, so it just queues the dispatched
|
||||||
|
// call-script ids; the main thread drains them (Godot drops GD.Print from background threads). This
|
||||||
|
// replaces the old IHost.CallScript -> GodotAdvHost.Dispatched hack: subroutine visibility is now an
|
||||||
|
// engine fact delivered over the trace seam.
|
||||||
|
public sealed class GodotTraceSink : ITraceSink
|
||||||
|
{
|
||||||
|
public bool TracingSteps => false;
|
||||||
|
public readonly ConcurrentQueue<long> CallScripts = new();
|
||||||
|
public void Emit(in TraceEvent e)
|
||||||
|
{
|
||||||
|
if (e.Kind == TraceEventKind.CallScript) CallScripts.Enqueue(e.Id);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,6 +19,7 @@ public partial class Main : Godot.Control
|
|||||||
private AudioStreamPlayer _voice = null!; // interrupt-on-new voice
|
private AudioStreamPlayer _voice = null!; // interrupt-on-new voice
|
||||||
private VirtualMachine _vm = null!;
|
private VirtualMachine _vm = null!;
|
||||||
private GodotAdvHost _host = null!;
|
private GodotAdvHost _host = null!;
|
||||||
|
private GodotTraceSink _trace = null!;
|
||||||
private volatile bool _done;
|
private volatile bool _done;
|
||||||
private bool _ended;
|
private bool _ended;
|
||||||
private bool _selftest;
|
private bool _selftest;
|
||||||
@@ -102,7 +103,8 @@ public partial class Main : Godot.Control
|
|||||||
if (_selftest) (script, provider) = BuildSelfTestScene(table);
|
if (_selftest) (script, provider) = BuildSelfTestScene(table);
|
||||||
else { script = Sys4Loader.Load(Paths.Scripts()[scene.ToUpperInvariant() + ".BIN"], table); provider = Sys4ScriptProvider.Load(table); }
|
else { script = Sys4Loader.Load(Paths.Scripts()[scene.ToUpperInvariant() + ".BIN"], table); provider = Sys4ScriptProvider.Load(table); }
|
||||||
_host = new GodotAdvHost(this, ResourceMap.Load(), scene);
|
_host = new GodotAdvHost(this, ResourceMap.Load(), scene);
|
||||||
_vm = new VirtualMachine(script, table, _host, null, provider);
|
_trace = new GodotTraceSink();
|
||||||
|
_vm = new VirtualMachine(script, table, _host, null, provider, _trace);
|
||||||
foreach (var (addr, val) in seeds) _vm.Globals[addr] = val; // seed initial state before running
|
foreach (var (addr, val) in seeds) _vm.Globals[addr] = val; // seed initial state before running
|
||||||
_ = Task.Run(() => { _vm.Run(); _done = true; });
|
_ = Task.Run(() => { _vm.Run(); _done = true; });
|
||||||
|
|
||||||
@@ -203,7 +205,7 @@ public partial class Main : Godot.Control
|
|||||||
private void ReportSubroutines()
|
private void ReportSubroutines()
|
||||||
{
|
{
|
||||||
var ids = new List<long>();
|
var ids = new List<long>();
|
||||||
while (_host.Dispatched.TryDequeue(out var id)) ids.Add(id);
|
while (_trace.CallScripts.TryDequeue(out var id)) ids.Add(id);
|
||||||
if (ids.Count == 0) { GD.Print("[subroutines] none dispatched on this path"); return; }
|
if (ids.Count == 0) { GD.Print("[subroutines] none dispatched on this path"); return; }
|
||||||
var distinct = new List<string>();
|
var distinct = new List<string>();
|
||||||
foreach (var id in ids) { var h = "0x" + id.ToString("x"); if (!distinct.Contains(h)) distinct.Add(h); }
|
foreach (var id in ids) { var h = "0x" + id.ToString("x"); if (!distinct.Contains(h)) distinct.Add(h); }
|
||||||
|
|||||||
Reference in New Issue
Block a user