Code/Extensions/DebugOverlaySystemExtensions.cs
using System.IO;
using System.Runtime.CompilerServices;

namespace Nodebox.Extensions;

public static class DebugOverlaySystemExtensions {
    private static Dictionary<int, (string key, RealTimeUntil time)> slots = [];

    private static int FindSlotFor(string key) {
        var slot = -1;
        foreach (var pair in slots) {
            if (pair.Value.key == key) {
                slot = pair.Key;
            }
        }

        if (slot < 0) {
            slot++;
            while (slots.ContainsKey(slot)) {
                var entry = slots[slot];
                if (entry.time) {
                    break;
                }

                slot++;

                if (slot > 64) {
                    slot = -1;
                    break;
                }
            }
        }

        if (slot < 0) {
            return -1;
        }

        return slot;
    }

    public static void DebugText(this DebugOverlaySystem dbg,
        string text,
        Color color = default,
        [CallerFilePath] string file = "",
        [CallerMemberName] string member = "",
        [CallerLineNumber] int line = 0
    ) {
        var key = $"{Path.GetFileName(file)}_{member}({line}): {text}";
        var slot = FindSlotFor(key);
        dbg.ScreenText(new(32, 32 + slot * 16), key, 14, TextFlag.Left, color);
    }

    public static void Variable(
        this DebugOverlaySystem dbg,
        string name,
        object value,
        Color color = default,
        [CallerFilePath] string file = "",
        [CallerMemberName] string member = "",
        [CallerLineNumber] int line = 0
    ) {
        var key = $"{Path.GetFileName(file)}_{member}({line}): {name}";
        var slot = FindSlotFor(key);
        slots[slot] = (key, (RealTimeUntil)1f);
        dbg.ScreenText(new(32, 32 + slot * 16), $"{key} = {value}", 14, TextFlag.Left, color);
    }

    public static void Transform(this DebugOverlaySystem dbg, in Transform transform, float size = 5f, bool overlay = false, string text = null) {
        dbg.Line(Vector3.Zero, Vector3.Forward * size, Color.Red, transform: transform, overlay: overlay);
        dbg.Line(Vector3.Zero, Vector3.Left * size, Color.Green, transform: transform, overlay: overlay);
        dbg.Line(Vector3.Zero, Vector3.Up * size, Color.Blue, transform: transform, overlay: overlay);
        if (text != null) {
            dbg.Text(transform.Position, text, size, overlay: overlay);
        }
    }
}