diff --git a/source/Main.hx b/source/Main.hx index e48765854..1b88cd75e 100644 --- a/source/Main.hx +++ b/source/Main.hx @@ -145,6 +145,7 @@ class Main extends Sprite #if FEATURE_DEBUG_FUNCTIONS game.debugger.interaction.addTool(new funkin.util.TrackerToolButtonUtil()); + funkin.util.macro.ConsoleMacro.init(); #end #if !html5 diff --git a/source/funkin/save/Save.hx b/source/funkin/save/Save.hx index db98cc3ba..3449b5df2 100644 --- a/source/funkin/save/Save.hx +++ b/source/funkin/save/Save.hx @@ -11,6 +11,7 @@ import funkin.ui.debug.charting.ChartEditorState.ChartEditorLiveInputStyle; import funkin.ui.debug.charting.ChartEditorState.ChartEditorTheme; import funkin.ui.debug.stageeditor.StageEditorState.StageEditorTheme; import funkin.util.FileUtil; +import funkin.util.macro.ConsoleMacro; import funkin.util.SerializerUtil; import funkin.mobile.ui.FunkinHitbox; import thx.semver.Version; @@ -20,7 +21,7 @@ import funkin.api.newgrounds.Leaderboards; #end @:nullSafety -class Save +class Save implements ConsoleClass { public static final SAVE_DATA_VERSION:thx.semver.Version = "2.1.1"; public static final SAVE_DATA_VERSION_RULE:thx.semver.VersionRule = ">=2.1.0 <2.2.0"; diff --git a/source/funkin/util/macro/ConsoleMacro.hx b/source/funkin/util/macro/ConsoleMacro.hx new file mode 100644 index 000000000..96fe5112a --- /dev/null +++ b/source/funkin/util/macro/ConsoleMacro.hx @@ -0,0 +1,68 @@ +package funkin.util.macro; + +import haxe.macro.Context; +import haxe.macro.Expr; +#if !macro +import flixel.FlxG; +#end + +using haxe.macro.TypeTools; +using haxe.macro.ComplexTypeTools; + +class ConsoleMacro +{ + #if !macro + /** + * Gets called in `Main.hx` after FlxGame is initalized, and is what we use to easy add debug functions to flixel console + */ + public static function init():Void + { + for (className in classes) + { + var classInstance = Type.resolveClass(className); + if (classInstance != null) FlxG.console.registerClass(classInstance); + } + } + #end + + // Runtime-accessible array of console classes + static var classes:Array = []; + + /** + * Called at runtime to register a class with the console + */ + public static function registerClass(className:String):Void + { + classes.push(className); + trace("Registered console class: " + className); + } + + #if macro + static macro function buildConsoleClass():Array + { + var cl = Context.getLocalClass().toString(); + var fields = Context.getBuildFields(); + + // Generate a static field with initialization expression that runs at class load time + var initFieldName = "__consoleRegistration_" + StringTools.replace(cl, ".", "_"); + var initField = + { + name: initFieldName, + access: [AStatic, APrivate], + kind: FVar(macro :Bool, macro + { + funkin.util.macro.ConsoleMacro.registerClass($v{cl}); + true; + }), + pos: Context.currentPos() + }; + + fields.push(initField); + trace("Generated console registration for: " + cl); + return fields; + } + #end +} + +@:autoBuild(funkin.util.macro.ConsoleMacro.buildConsoleClass()) +interface ConsoleClass {}