Add hero runtime
This commit is contained in:
@@ -5,5 +5,6 @@ public enum DebugBootMode
|
||||
Menu,
|
||||
Smoke,
|
||||
ContentBrowser,
|
||||
DebugSandbox
|
||||
DebugSandbox,
|
||||
HeroSandbox
|
||||
}
|
||||
@@ -32,6 +32,12 @@ public partial class DebugOverlay : CanvasLayer
|
||||
Refresh();
|
||||
}
|
||||
|
||||
public void SetHeroSummary(string summary)
|
||||
{
|
||||
m_HeroSummary = summary;
|
||||
Refresh();
|
||||
}
|
||||
|
||||
private void Refresh()
|
||||
{
|
||||
Label label = EnsureLabel();
|
||||
@@ -42,7 +48,8 @@ public partial class DebugOverlay : CanvasLayer
|
||||
|
||||
DebugRuntimeState state = m_Service.State;
|
||||
Visible = state.OverlayVisible;
|
||||
label.Text = $"Debug boot: {m_Settings.BootMode}\n" + $"Scene: {m_LoadedSceneId}\n" + $"Seed: {state.Seed}\n" + $"Difficulty: {state.ActiveDifficultyId}\n" + $"Paused: {state.IsPaused}\n" + $"Time scale: {state.TimeScale.ToString(CultureInfo.InvariantCulture)}\n" + $"Marker: {DisplayOrNone(state.CurrentMarkerId)}\n" + $"Spawned: {state.SpawnedActorCount} ({DisplayOrNone(state.LastSpawnedActorId)})\n" + $"Flags: invuln={state.Invulnerable}, ammo={state.InfiniteSpecialAmmo}, nofire={state.NoEnemyFire}\n" + $"Debug draw: collisions={state.ShowCollisionShapes}, bounds={state.ShowGameplayBounds}";
|
||||
string heroLine = string.IsNullOrWhiteSpace(m_HeroSummary) ? string.Empty : $"\nHero: {m_HeroSummary}";
|
||||
label.Text = $"Debug boot: {m_Settings.BootMode}\n" + $"Scene: {m_LoadedSceneId}\n" + $"Seed: {state.Seed}\n" + $"Difficulty: {state.ActiveDifficultyId}\n" + $"Paused: {state.IsPaused}\n" + $"Time scale: {state.TimeScale.ToString(CultureInfo.InvariantCulture)}\n" + $"Marker: {DisplayOrNone(state.CurrentMarkerId)}\n" + $"Spawned: {state.SpawnedActorCount} ({DisplayOrNone(state.LastSpawnedActorId)})\n" + $"Flags: invuln={state.Invulnerable}, ammo={state.InfiniteSpecialAmmo}, nofire={state.NoEnemyFire}\n" + $"Debug draw: collisions={state.ShowCollisionShapes}, bounds={state.ShowGameplayBounds}" + heroLine;
|
||||
}
|
||||
|
||||
private Label EnsureLabel()
|
||||
@@ -74,4 +81,5 @@ public partial class DebugOverlay : CanvasLayer
|
||||
private DebugCommandService? m_Service;
|
||||
private DebugSettings? m_Settings;
|
||||
private string m_LoadedSceneId = "none";
|
||||
private string m_HeroSummary = string.Empty;
|
||||
}
|
||||
364
godot/scripts/debug/HeroSandboxController.cs
Normal file
364
godot/scripts/debug/HeroSandboxController.cs
Normal file
@@ -0,0 +1,364 @@
|
||||
#nullable enable
|
||||
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Godot;
|
||||
using SideScrollerGame.Content.Samples;
|
||||
using SideScrollerGame.Debug.Commands;
|
||||
using SideScrollerGame.Hero;
|
||||
using SideScrollerGame.Hero.Rules;
|
||||
|
||||
namespace SideScrollerGame.Debug;
|
||||
|
||||
public partial class HeroSandboxController : Control
|
||||
{
|
||||
public override void _Ready()
|
||||
{
|
||||
ProcessMode = ProcessModeEnum.Always;
|
||||
m_CommandNode = GetNodeOrNull<DebugCommandNode>("/root/GameRoot/DebugCommandNode");
|
||||
m_Overlay = GetNodeOrNull<DebugOverlay>("/root/GameRoot/DebugOverlay");
|
||||
if (m_CommandNode is null)
|
||||
{
|
||||
GD.PushError("Hero sandbox needs /root/GameRoot/DebugCommandNode.");
|
||||
return;
|
||||
}
|
||||
|
||||
BindSceneNodes();
|
||||
RegisterHeroCommands();
|
||||
CreateHeroRuntime();
|
||||
CreateButtons();
|
||||
|
||||
m_CommandNode.Service.CommandExecuted += HandleCommandExecuted;
|
||||
m_CommandNode.Service.RegisterRestartHandler(RestartSandbox);
|
||||
|
||||
if (ShouldRunHeroSmoke())
|
||||
{
|
||||
_ = RunHeroSmokeAsync();
|
||||
}
|
||||
}
|
||||
|
||||
public override void _UnhandledInput(InputEvent @event)
|
||||
{
|
||||
if (@event.IsActionPressed("debug_damage_hero"))
|
||||
{
|
||||
Execute(DebugCommandId.DamageHero);
|
||||
}
|
||||
else if (@event.IsActionPressed("debug_kill_hero"))
|
||||
{
|
||||
Execute(DebugCommandId.KillHero);
|
||||
}
|
||||
else if (@event.IsActionPressed("debug_rebirth_hero"))
|
||||
{
|
||||
Execute(DebugCommandId.RebirthHero);
|
||||
}
|
||||
else if (@event.IsActionPressed("debug_add_points"))
|
||||
{
|
||||
Execute(DebugCommandId.AddHeroPoints, "100");
|
||||
}
|
||||
else if (@event.IsActionPressed("debug_add_shield"))
|
||||
{
|
||||
Execute(DebugCommandId.AddHeroShield);
|
||||
}
|
||||
else if (@event.IsActionPressed("debug_remove_shield"))
|
||||
{
|
||||
Execute(DebugCommandId.RemoveHeroShield);
|
||||
}
|
||||
else if (@event.IsActionPressed("debug_toggle_primary_slot"))
|
||||
{
|
||||
Execute(DebugCommandId.TogglePrimaryWeaponSlot);
|
||||
}
|
||||
else if (@event.IsActionPressed("debug_clear_hero_inventory"))
|
||||
{
|
||||
Execute(DebugCommandId.ClearHeroInventory);
|
||||
}
|
||||
else if (@event.IsActionPressed("debug_toggle_invulnerability"))
|
||||
{
|
||||
Execute(DebugCommandId.ToggleInvulnerability);
|
||||
}
|
||||
else if (@event.IsActionPressed("pause_game") || @event.IsActionPressed("debug_pause"))
|
||||
{
|
||||
Execute(DebugCommandId.TogglePause);
|
||||
}
|
||||
else if (@event.IsActionPressed("debug_frame_step"))
|
||||
{
|
||||
Execute(DebugCommandId.FrameStep);
|
||||
}
|
||||
else if (@event.IsActionPressed("quick_restart"))
|
||||
{
|
||||
Execute(DebugCommandId.RestartMission);
|
||||
}
|
||||
}
|
||||
|
||||
private void BindSceneNodes()
|
||||
{
|
||||
m_Hero = GetNodeOrNull<HeroActor>("Playfield/Hero");
|
||||
m_Hud = GetNodeOrNull<HeroStateHudController>("HudPanel");
|
||||
m_LogLabel = GetNodeOrNull<Label>("LogPanel/LogScroll/LogLabel");
|
||||
m_ButtonContainer = GetNodeOrNull<VBoxContainer>("ButtonPanel/Scroll/Buttons");
|
||||
m_PlayBoundsRect = GetNodeOrNull<ColorRect>("Playfield/PlayBounds");
|
||||
}
|
||||
|
||||
private void RegisterHeroCommands()
|
||||
{
|
||||
if (m_CommandNode is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (DebugCommandId commandId in s_HeroCommandIds)
|
||||
{
|
||||
m_CommandNode.Service.RegisterCommandHandler(commandId, argument => ExecuteHeroCommand(commandId, argument));
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateHeroRuntime()
|
||||
{
|
||||
if (m_CommandNode is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
string difficultyId = m_CommandNode.Service.State.ActiveDifficultyId;
|
||||
m_Runtime = new HeroRuntimeService(SampleContent.CreateRegistry(), HeroRuleConfig.CreateDefault(), difficultyId);
|
||||
m_Runtime.StateChanged += _ => RefreshHeroViews();
|
||||
m_Hero?.SetRuntime(m_Runtime);
|
||||
m_Hero?.SetPlayBounds(PlayBounds);
|
||||
if (m_Hero is not null)
|
||||
{
|
||||
m_Hero.GlobalPosition = PlayBounds.GetCenter();
|
||||
}
|
||||
|
||||
if (m_PlayBoundsRect is not null)
|
||||
{
|
||||
m_PlayBoundsRect.GlobalPosition = PlayBounds.Position;
|
||||
m_PlayBoundsRect.Size = PlayBounds.Size;
|
||||
}
|
||||
|
||||
m_Hud?.Bind(m_Runtime);
|
||||
RefreshHeroViews();
|
||||
}
|
||||
|
||||
private void CreateButtons()
|
||||
{
|
||||
if (m_ButtonContainer is null || m_ButtonContainer.GetChildCount() > 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
AddHeader("Hero");
|
||||
AddButton("Damage", DebugCommandId.DamageHero);
|
||||
AddButton("Heal", DebugCommandId.HealHero);
|
||||
AddButton("Kill", DebugCommandId.KillHero);
|
||||
AddButton("Rebirth", DebugCommandId.RebirthHero);
|
||||
AddButton("+100 pts", DebugCommandId.AddHeroPoints, "100");
|
||||
AddButton("+500 pts", DebugCommandId.AddHeroPoints, "500");
|
||||
AddButton("Level 1", DebugCommandId.SetHeroLevel, "1");
|
||||
AddButton("Level 4", DebugCommandId.SetHeroLevel, "4");
|
||||
AddButton("+Shield", DebugCommandId.AddHeroShield);
|
||||
AddButton("-Shield", DebugCommandId.RemoveHeroShield);
|
||||
AddButton("Retries 0", DebugCommandId.SetHeroRetries, "0");
|
||||
AddButton("Retries 3", DebugCommandId.SetHeroRetries, "3");
|
||||
AddButton("Primary slot", DebugCommandId.TogglePrimaryWeaponSlot);
|
||||
AddButton("Give primary", DebugCommandId.GivePrimaryWeapon, "weapon.primary.basic");
|
||||
AddButton("Give secondary", DebugCommandId.GiveSecondaryWeapon, "weapon.secondary.vertical");
|
||||
AddButton("+3 special", DebugCommandId.GiveSpecialAmmo, "3");
|
||||
AddButton("Give mate", DebugCommandId.GiveSquadronMate, "squadron.orbit");
|
||||
AddButton("Clear inventory", DebugCommandId.ClearHeroInventory);
|
||||
|
||||
AddHeader("Debug");
|
||||
AddButton("Invulnerable", DebugCommandId.ToggleInvulnerability);
|
||||
AddButton("Pause", DebugCommandId.TogglePause);
|
||||
AddButton("Step", DebugCommandId.FrameStep);
|
||||
AddButton("Restart", DebugCommandId.RestartMission);
|
||||
AddButton("Reload", DebugCommandId.ReloadScene);
|
||||
}
|
||||
|
||||
private void AddHeader(string text)
|
||||
{
|
||||
m_ButtonContainer?.AddChild(new Label { Text = text });
|
||||
}
|
||||
|
||||
private void AddButton(string text, DebugCommandId commandId, string? argument = null)
|
||||
{
|
||||
Button button = new() { Text = text };
|
||||
button.Pressed += () => Execute(commandId, argument);
|
||||
m_ButtonContainer?.AddChild(button);
|
||||
}
|
||||
|
||||
private DebugCommandResult ExecuteHeroCommand(DebugCommandId commandId, string? argument)
|
||||
{
|
||||
if (m_Runtime is null)
|
||||
{
|
||||
return DebugCommandResult.Failure(commandId, "Hero runtime is not ready.", argument);
|
||||
}
|
||||
|
||||
HeroRuleResult result = commandId switch
|
||||
{
|
||||
DebugCommandId.DamageHero => m_Runtime.ApplyHit(m_CommandNode?.Service.State.Invulnerable ?? false),
|
||||
DebugCommandId.HealHero => m_Runtime.AddShieldCharge(1),
|
||||
DebugCommandId.KillHero => m_Runtime.Kill(),
|
||||
DebugCommandId.RebirthHero => m_Runtime.Rebirth(),
|
||||
DebugCommandId.AddHeroPoints => m_Runtime.AddPoints(ParseInt(argument, 100)),
|
||||
DebugCommandId.SetHeroLevel => m_Runtime.SetLevel(ParseInt(argument, 1)),
|
||||
DebugCommandId.AddHeroShield => m_Runtime.AddShieldCharge(1),
|
||||
DebugCommandId.RemoveHeroShield => m_Runtime.RemoveShieldCharge(1),
|
||||
DebugCommandId.SetHeroRetries => m_Runtime.SetRetryCount(ParseInt(argument, 3)),
|
||||
DebugCommandId.TogglePrimaryWeaponSlot => m_Runtime.TogglePrimaryWeaponSlot(),
|
||||
DebugCommandId.ClearHeroInventory => m_Runtime.ClearInventory(),
|
||||
DebugCommandId.GivePrimaryWeapon => m_Runtime.ApplyPrimaryWeaponPickup(RequireArgument(argument, "weapon.primary.basic")),
|
||||
DebugCommandId.GiveSecondaryWeapon => m_Runtime.ApplySecondaryWeaponPickup(RequireArgument(argument, "weapon.secondary.vertical")),
|
||||
DebugCommandId.GiveSpecialAmmo => m_Runtime.AddSpecialAmmo(ParseInt(argument, 1)),
|
||||
DebugCommandId.GiveSquadronMate => m_Runtime.ApplySquadronMatePickup(RequireArgument(argument, "squadron.orbit")),
|
||||
_ => HeroRuleResult.Failure($"Unsupported hero command '{commandId}'.", m_Runtime.State)
|
||||
};
|
||||
|
||||
RefreshHeroViews();
|
||||
return result.Succeeded ? DebugCommandResult.Success(commandId, result.Message, argument) : DebugCommandResult.Failure(commandId, result.Message, argument);
|
||||
}
|
||||
|
||||
private DebugCommandResult RestartSandbox()
|
||||
{
|
||||
CreateHeroRuntime();
|
||||
return DebugCommandResult.Success(DebugCommandId.RestartMission, "Hero sandbox restarted");
|
||||
}
|
||||
|
||||
private void HandleCommandExecuted(DebugCommandResult result)
|
||||
{
|
||||
if (s_HeroCommandIds.Contains(result.CommandId))
|
||||
{
|
||||
string suffix = string.IsNullOrWhiteSpace(result.Argument) ? string.Empty : $" {result.Argument}";
|
||||
AppendLog($"Hero command: {result.CommandId}{suffix}");
|
||||
AppendLog($"Hero state: {BuildHeroSummary()}");
|
||||
}
|
||||
else if (result.CommandId is DebugCommandId.ToggleInvulnerability or DebugCommandId.TogglePause or DebugCommandId.FrameStep or DebugCommandId.RestartMission or DebugCommandId.ReloadScene)
|
||||
{
|
||||
string suffix = string.IsNullOrWhiteSpace(result.Argument) ? string.Empty : $" {result.Argument}";
|
||||
AppendLog($"Command executed: {result.CommandId}{suffix}");
|
||||
}
|
||||
|
||||
if (!result.Succeeded)
|
||||
{
|
||||
AppendLog($"Command failed: {result.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
private void RefreshHeroViews()
|
||||
{
|
||||
m_Hud?.Refresh();
|
||||
m_Overlay?.SetHeroSummary(BuildHeroSummary());
|
||||
}
|
||||
|
||||
private string BuildHeroSummary()
|
||||
{
|
||||
if (m_Runtime is null)
|
||||
{
|
||||
return "unbound";
|
||||
}
|
||||
|
||||
HeroRunState state = m_Runtime.State;
|
||||
return $"{state.LifeState} level={state.Level} points={state.Points} shields={state.ShieldCharges} retries={state.RetryCount}";
|
||||
}
|
||||
|
||||
private void Execute(DebugCommandId commandId, string? argument = null)
|
||||
{
|
||||
m_CommandNode?.Execute(commandId, argument);
|
||||
}
|
||||
|
||||
private async Task RunHeroSmokeAsync()
|
||||
{
|
||||
await ToSignal(GetTree(), SceneTree.SignalName.ProcessFrame);
|
||||
AppendLog("Hero sandbox smoke loaded");
|
||||
|
||||
bool succeeded = ExecuteAndRequire(DebugCommandId.SetDifficulty, "difficulty.normal") && ExecuteAndRequire(DebugCommandId.DamageHero) && ExecuteAndRequire(DebugCommandId.AddHeroPoints, "500") && ExecuteAndRequire(DebugCommandId.TogglePrimaryWeaponSlot) && ExecuteAndRequire(DebugCommandId.GivePrimaryWeapon, "weapon.primary.basic") && ExecuteAndRequire(DebugCommandId.GiveSpecialAmmo, "3") && ExecuteAndRequire(DebugCommandId.GiveSquadronMate, "squadron.orbit") && ExecuteAndRequire(DebugCommandId.ToggleInvulnerability) && ExecuteAndRequire(DebugCommandId.DamageHero) && ExecuteAndRequire(DebugCommandId.KillHero) && ExecuteAndRequire(DebugCommandId.RebirthHero) && ExecuteAndRequire(DebugCommandId.SetHeroRetries, "0") && ExecuteAndRequire(DebugCommandId.KillHero) && VerifyHeroSmokeState();
|
||||
|
||||
AppendLog(succeeded ? "Hero sandbox smoke succeeded" : "Hero sandbox smoke failed");
|
||||
GetTree().Quit(succeeded ? 0 : 1);
|
||||
}
|
||||
|
||||
private bool ExecuteAndRequire(DebugCommandId commandId, string? argument = null)
|
||||
{
|
||||
if (m_CommandNode is null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
DebugCommandResult result = m_CommandNode.Execute(commandId, argument);
|
||||
if (result.Succeeded)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
AppendLog(result.Message);
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool VerifyHeroSmokeState()
|
||||
{
|
||||
if (m_Runtime is null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
HeroRunState state = m_Runtime.State;
|
||||
return state.LifeState == HeroLifeState.GameOver && state.Level == 2 && state.Points == 500 && state.ShieldCharges == 0 && state.RetryCount == 0;
|
||||
}
|
||||
|
||||
private void AppendLog(string message)
|
||||
{
|
||||
GD.Print(message);
|
||||
if (m_LogLabel is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_LogLabel.Text = string.IsNullOrWhiteSpace(m_LogLabel.Text) ? message : $"{m_LogLabel.Text}\n{message}";
|
||||
}
|
||||
|
||||
private static int ParseInt(string? value, int defaultValue)
|
||||
{
|
||||
return int.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out int parsedValue) ? parsedValue : defaultValue;
|
||||
}
|
||||
|
||||
private static string RequireArgument(string? argument, string defaultValue)
|
||||
{
|
||||
return string.IsNullOrWhiteSpace(argument) ? defaultValue : argument.Trim();
|
||||
}
|
||||
|
||||
private static bool ShouldRunHeroSmoke()
|
||||
{
|
||||
return DisplayServer.GetName().Equals("headless", StringComparison.OrdinalIgnoreCase) && OS.GetCmdlineUserArgs().Any(argument => argument.Equals("--debug-script=hero-smoke", StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
|
||||
[Export]
|
||||
public Rect2 PlayBounds { get; set; } = new(new Vector2(280.0f, 96.0f), new Vector2(640.0f, 420.0f));
|
||||
|
||||
private static readonly DebugCommandId[] s_HeroCommandIds =
|
||||
[
|
||||
DebugCommandId.DamageHero,
|
||||
DebugCommandId.HealHero,
|
||||
DebugCommandId.KillHero,
|
||||
DebugCommandId.RebirthHero,
|
||||
DebugCommandId.AddHeroPoints,
|
||||
DebugCommandId.SetHeroLevel,
|
||||
DebugCommandId.AddHeroShield,
|
||||
DebugCommandId.RemoveHeroShield,
|
||||
DebugCommandId.SetHeroRetries,
|
||||
DebugCommandId.TogglePrimaryWeaponSlot,
|
||||
DebugCommandId.ClearHeroInventory,
|
||||
DebugCommandId.GivePrimaryWeapon,
|
||||
DebugCommandId.GiveSecondaryWeapon,
|
||||
DebugCommandId.GiveSpecialAmmo,
|
||||
DebugCommandId.GiveSquadronMate
|
||||
];
|
||||
|
||||
private DebugCommandNode? m_CommandNode;
|
||||
private DebugOverlay? m_Overlay;
|
||||
private HeroRuntimeService? m_Runtime;
|
||||
private HeroActor? m_Hero;
|
||||
private HeroStateHudController? m_Hud;
|
||||
private Label? m_LogLabel;
|
||||
private VBoxContainer? m_ButtonContainer;
|
||||
private ColorRect? m_PlayBoundsRect;
|
||||
}
|
||||
1
godot/scripts/debug/HeroSandboxController.cs.uid
Normal file
1
godot/scripts/debug/HeroSandboxController.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://dstsg1pgmok1o
|
||||
@@ -20,5 +20,20 @@ public enum DebugCommandId
|
||||
ToggleGameplayBounds,
|
||||
ToggleInvulnerability,
|
||||
ToggleInfiniteSpecialAmmo,
|
||||
ToggleNoEnemyFire
|
||||
ToggleNoEnemyFire,
|
||||
DamageHero,
|
||||
HealHero,
|
||||
KillHero,
|
||||
RebirthHero,
|
||||
AddHeroPoints,
|
||||
SetHeroLevel,
|
||||
AddHeroShield,
|
||||
RemoveHeroShield,
|
||||
SetHeroRetries,
|
||||
TogglePrimaryWeaponSlot,
|
||||
ClearHeroInventory,
|
||||
GivePrimaryWeapon,
|
||||
GiveSecondaryWeapon,
|
||||
GiveSpecialAmmo,
|
||||
GiveSquadronMate
|
||||
}
|
||||
@@ -37,7 +37,7 @@ public sealed class DebugCommandService
|
||||
DebugCommandId.ToggleInvulnerability => ToggleFlag(commandId, nameof(State.Invulnerable)),
|
||||
DebugCommandId.ToggleInfiniteSpecialAmmo => ToggleFlag(commandId, nameof(State.InfiniteSpecialAmmo)),
|
||||
DebugCommandId.ToggleNoEnemyFire => ToggleFlag(commandId, nameof(State.NoEnemyFire)),
|
||||
_ => DebugCommandResult.Failure(commandId, $"Unsupported debug command '{commandId}'.", argument)
|
||||
_ => ExecuteRegisteredCommand(commandId, argument)
|
||||
};
|
||||
|
||||
CommandExecuted?.Invoke(result);
|
||||
@@ -64,6 +64,16 @@ public sealed class DebugCommandService
|
||||
m_RestartHandler = handler;
|
||||
}
|
||||
|
||||
public void RegisterCommandHandler(DebugCommandId commandId, Func<string?, DebugCommandResult> handler)
|
||||
{
|
||||
m_CommandHandlers[commandId] = handler;
|
||||
}
|
||||
|
||||
public void ClearCommandHandler(DebugCommandId commandId)
|
||||
{
|
||||
m_CommandHandlers.Remove(commandId);
|
||||
}
|
||||
|
||||
public DebugRuntimeState State { get; }
|
||||
|
||||
public event Action<DebugRuntimeState>? StateChanged;
|
||||
@@ -218,6 +228,11 @@ public sealed class DebugCommandService
|
||||
return DebugCommandResult.Success(commandId, message);
|
||||
}
|
||||
|
||||
private DebugCommandResult ExecuteRegisteredCommand(DebugCommandId commandId, string? argument)
|
||||
{
|
||||
return m_CommandHandlers.TryGetValue(commandId, out Func<string?, DebugCommandResult>? handler) ? handler(argument) : DebugCommandResult.Failure(commandId, $"Unsupported debug command '{commandId}'.", argument);
|
||||
}
|
||||
|
||||
private string ToggleShowCollisionShapes()
|
||||
{
|
||||
State.ShowCollisionShapes = !State.ShowCollisionShapes;
|
||||
@@ -276,6 +291,7 @@ public sealed class DebugCommandService
|
||||
private static readonly HashSet<double> s_SupportedTimeScales = [0.25, 0.5, 1.0, 2.0, 4.0];
|
||||
|
||||
private readonly ContentRegistry m_Registry;
|
||||
private readonly Dictionary<DebugCommandId, Func<string?, DebugCommandResult>> m_CommandHandlers = [];
|
||||
private Func<string, DebugCommandResult>? m_SpawnHandler;
|
||||
private Func<string, DebugCommandResult>? m_TimelineJumpHandler;
|
||||
private Func<DebugCommandResult>? m_ReloadHandler;
|
||||
|
||||
Reference in New Issue
Block a user