Imgui debug overlay hooks

This commit is contained in:
Maddy Thorson 2021-02-17 22:11:52 -08:00
parent 71d17afa78
commit 6c37bb7af5
3 changed files with 19 additions and 248 deletions

Binary file not shown.

View File

@ -14,7 +14,7 @@ namespace Strawberry
static public Game Game; static public Game Game;
} }
public class Game public abstract class Game
{ {
public readonly List<VirtualInput> VirtualInputs; public readonly List<VirtualInput> VirtualInputs;
public readonly String Title; public readonly String Title;
@ -30,6 +30,7 @@ namespace Strawberry
public PlatformLayer PlatformLayer { get; private set; } public PlatformLayer PlatformLayer { get; private set; }
public Batcher Batcher { get; private set; } public Batcher Batcher { get; private set; }
public Color ClearColor = .Black; public Color ClearColor = .Black;
public bool DebugOverlay = false;
private bool* keyboardState; private bool* keyboardState;
private int32 updateCounter; private int32 updateCounter;
@ -61,7 +62,6 @@ namespace Strawberry
Tracker.[Friend]BuildAssignmentLists(); Tracker.[Friend]BuildAssignmentLists();
Assets.LoadAll(); Assets.LoadAll();
Strawberry.StrwConsole.Init();
} }
public ~this() public ~this()
@ -83,7 +83,6 @@ namespace Strawberry
Assets.DisposeAll(); Assets.DisposeAll();
Input.[Friend]Dispose(); Input.[Friend]Dispose();
Strawberry.StrwConsole.Dispose();
delete Batcher; delete Batcher;
@ -132,6 +131,10 @@ namespace Strawberry
for (var i in VirtualInputs) for (var i in VirtualInputs)
i.Update(); i.Update();
//Debug Overlay
if (Input.KeyPressed(.Grave))
DebugOverlay = !DebugOverlay;
//Switch scenes //Switch scenes
if (switchToScene != scene) if (switchToScene != scene)
{ {
@ -154,8 +157,6 @@ namespace Strawberry
Time.PreviousElapsed = Time.Elapsed; Time.PreviousElapsed = Time.Elapsed;
Time.Elapsed += Time.Delta; Time.Elapsed += Time.Delta;
} }
Strawberry.StrwConsole.[Friend]Update();
} }
private void Render() private void Render()
@ -163,16 +164,20 @@ namespace Strawberry
PlatformLayer.GameRenderBegin(); PlatformLayer.GameRenderBegin();
Draw(); Draw();
PlatformLayer.GameRenderEnd(); PlatformLayer.GameRenderEnd();
if (DebugOverlay)
{
PlatformLayer.EditorRenderBegin();
DebugOverlay();
PlatformLayer.EditorRenderEnd();
}
PlatformLayer.RenderEnd(); PlatformLayer.RenderEnd();
} }
public virtual void Draw() public virtual void Draw()
{ {
Scene?.Draw(); Scene?.Draw();
if (Strawberry.StrwConsole.Enabled)
Strawberry.StrwConsole.[Friend]Draw();
Batcher.Draw(); Batcher.Draw();
} }
@ -190,5 +195,10 @@ namespace Strawberry
switchToScene = value; switchToScene = value;
} }
} }
public virtual void DebugOverlay()
{
}
} }
} }

View File

@ -1,239 +0,0 @@
using System;
using System.Collections;
using System.Reflection;
using Strawberry;
namespace Strawberry
{
[AttributeUsage(.Method, .AlwaysIncludeTarget | .ReflectAttribute)]
public struct CommandAttribute : Attribute
{
public String Name;
public String Help;
public this(String name, String help = "")
{
Name = name;
Help = help;
}
}
[Reflect]
static public class StrwConsole
{
static public bool Open;
static private bool enabled;
static private SDL2.SDLTTF.Font* font;
static private String entry;
static private List<String> commandHistory;
static private List<String> messages;
static private Dictionary<String, CommandInfo> commands;
static public void Init()
{
bool* b = &enabled;
*b = false;
enabled = true;
font = SDL2.SDLTTF.OpenFont("../../../../Strawberry/src/Content/strawberry-seeds.ttf", 8);
entry = new String();
commandHistory = new List<String>();
messages = new List<String>();
commands = new Dictionary<String, CommandInfo>();
//Find commands
for (let type in Type.Types)
{
for (let method in type.GetMethods(.Static | .NonPublic | .Public))
{
let attr = method.GetCustomAttribute<CommandAttribute>();
if (attr != .Err)
commands.Add(attr.Value.Name, new CommandInfo(method, attr.Value));
}
}
}
static public void Dispose()
{
SDL2.SDLTTF.CloseFont(font);
delete entry;
DeleteContainerAndItems!(commandHistory);
DeleteContainerAndItems!(messages);
for (let c in commands.Values)
delete c;
delete commands;
}
static public bool Enabled
{
get => enabled;
set
{
enabled = value;
if (!enabled)
Open = false;
}
}
static public void Log(StringView str)
{
messages.Add(new String(str));
while (messages.Count > MessageRows)
{
delete messages[0];
messages.RemoveAt(0);
}
}
static public void Log(StringView str, params Object[] args)
{
let string = Calc.StringArgs(scope String(str), params args);
Log(string);
}
[Reflect]
[Command("clear", "Clears the console window")]
static public void Clear()
{
ClearAndDeleteItems!(messages);
}
static private void Update()
{
if (enabled)
{
if (Input.KeyPressed(.Grave))
Open = !Open;
if (Open)
{
Input.KeystrokesIntoString(entry, 0.25f, 0.05f);
if (Input.KeyPressed(.Delete))
entry.Clear();
if (Input.KeyPressed(.Return) && entry.Length > 0 && !String.IsNullOrWhiteSpace(entry))
SubmitEntry();
}
}
}
static private void SubmitEntry()
{
let line = new String(entry);
commandHistory.Add(line);
Log(line);
//Parse command and arguments
{
let list = String.StackSplit!(line, ' ');
list.RemoveAll(scope => String.IsNullOrWhiteSpace);
if (commands.ContainsKey(list[0]))
{
Log(line);
let args = scope String[list.Count - 1];
for (let i < args.Count)
args[i] = list[i + 1];
commands[list[0]].Call(args);
}
else
Log("Command '{0}' not recognized.", list[0]);
}
entry.Clear();
}
static private void Draw()
{
if (enabled && Open)
{
Game.Batcher.Rect(0, 0, Game.Width, Game.Height, .Black * 0.6f);
Game.Batcher.Rect(0, Game.Height - 14, Game.Width, 14, .Black * 0.6f);
//Entry
if (entry.Length > 0)
Text(entry, 0, 0, .White);
if (Time.BetweenInterval(0.25f))
Text("_", 0, entry.Length, .White);
//Messages
for (int i = messages.Count - 1; i >= 0; i--)
Text(messages[i], messages.Count - i, 0, .White);
}
}
static private void Text(String str, int row, int col, Color color)
{
Point pos = .(4 + 6 * col, Game.Height - 10 - 10 * row);
if (row > 0)
pos.Y -= 4;
//Draw.Text(font, str, pos + .Down, .Black);
//Draw.Text(font, str, pos, color);
}
static private int MessageRows => (int)Math.Ceiling((Game.Height - 14) / 10f);
private class CommandInfo
{
public String Help;
public String Usage ~ delete _;
public MethodInfo Method;
public this(MethodInfo method, CommandAttribute attr)
{
Help = attr.Help;
Method = method;
}
public void Call(String[] args)
{
if (Method.ParamCount == 0)
Method.Invoke(null);
else
{
let objs = scope Object[Method.ParamCount];
for (let i < objs.Count)
{
if (i < args.Count)
objs[i] = Convert(args[i], Method.GetParamType(i));
else
objs[i] = Method.GetParamType(i).CreateValueDefault();
}
Method.Invoke(null, params objs);
}
}
}
static private Object Convert(String str, Type type)
{
switch (type)
{
case typeof(StringView):
return str;
case typeof(int):
return int.Parse(str).Value;
case typeof(float):
return float.Parse(str).Value;
case typeof(bool):
return bool.Parse(str).Value;
case typeof(String):
Runtime.FatalError("String arguments not supported in commands. Use StringView instead.");
default:
{
let name = scope String();
type.GetName(name);
let error = Calc.StringArgs("{0} type arguments not supported in commands.", scope Object[]({ name }));
Runtime.FatalError(error);
}
}
}
}
}