Add in-game developer console (MrGameEng.DevConsole)
Core gains a static Log (Debug/Info/Warning/Error + event); the engine logs key events like scene switches. The console captures Log output into a 2048-line ring buffer and executes registered commands with input history (up/down), Tab prefix completion and scrolling (PageUp/PageDown/End/wheel). Built-ins: help, clear, echo, timescale, close, quit; games register their own (sample: stress/main/beep). Console core is pure logic covered by headless tests; the Myra overlay renders a single label rebuilt only when the Revision counter moves - an idle or closed console costs nothing per frame. Toggled with the backquote key; sample gameplay hotkeys are suppressed while open. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
e06f24a319
commit
d498c70660
@@ -0,0 +1,45 @@
|
||||
namespace MrGameEng.Core;
|
||||
|
||||
/// <summary>Severity of a log message.</summary>
|
||||
public enum LogLevel
|
||||
{
|
||||
/// <summary>Verbose diagnostics.</summary>
|
||||
Debug,
|
||||
|
||||
/// <summary>Normal informational message.</summary>
|
||||
Info,
|
||||
|
||||
/// <summary>Something suspicious but recoverable.</summary>
|
||||
Warning,
|
||||
|
||||
/// <summary>An error.</summary>
|
||||
Error,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Engine-wide logger. Messages go to subscribers (the developer console subscribes here)
|
||||
/// and to the debugger output. Logging allocates — do not log every frame from hot paths.
|
||||
/// </summary>
|
||||
public static class Log
|
||||
{
|
||||
/// <summary>Raised for every message. May be invoked from any thread.</summary>
|
||||
public static event Action<LogLevel, string>? MessageLogged;
|
||||
|
||||
/// <summary>Logs a debug message.</summary>
|
||||
public static void Debug(string message) => Write(LogLevel.Debug, message);
|
||||
|
||||
/// <summary>Logs an informational message.</summary>
|
||||
public static void Info(string message) => Write(LogLevel.Info, message);
|
||||
|
||||
/// <summary>Logs a warning.</summary>
|
||||
public static void Warning(string message) => Write(LogLevel.Warning, message);
|
||||
|
||||
/// <summary>Logs an error.</summary>
|
||||
public static void Error(string message) => Write(LogLevel.Error, message);
|
||||
|
||||
private static void Write(LogLevel level, string message)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine($"[{level}] {message}");
|
||||
MessageLogged?.Invoke(level, message);
|
||||
}
|
||||
}
|
||||
@@ -111,6 +111,7 @@ public sealed class SceneManager
|
||||
Current = _pending;
|
||||
_pending = null;
|
||||
Current?.Load(_context);
|
||||
Log.Info($"Scene switched to {Current?.GetType().Name ?? "<none>"}");
|
||||
}
|
||||
|
||||
private static float Advance(float coverage, float direction, float duration, float deltaTime) =>
|
||||
|
||||
Reference in New Issue
Block a user