From 963e2ecd630fae24dae4206d315618cf4c4be6db Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Sun, 13 Apr 2025 03:39:31 -0400 Subject: [PATCH] Edit RegistryMacro to automatically populate baseGameEntryIds list. --- source/funkin/data/BaseRegistry.hx | 13 ++++ .../data/freeplay/player/PlayerRegistry.hx | 20 ------ source/funkin/data/song/SongRegistry.hx | 20 ------ source/funkin/data/stage/StageRegistry.hx | 20 ------ .../funkin/data/story/level/LevelRegistry.hx | 38 +++++----- .../ui/debug/results/ResultsDebugSubState.hx | 2 +- .../stageeditor/components/WelcomeDialog.hx | 2 +- source/funkin/util/macro/DataMacro.hx | 59 --------------- source/funkin/util/macro/RegistryMacro.hx | 72 +++++++++++++++++++ 9 files changed, 109 insertions(+), 137 deletions(-) delete mode 100644 source/funkin/util/macro/DataMacro.hx diff --git a/source/funkin/data/BaseRegistry.hx b/source/funkin/data/BaseRegistry.hx index 882ba9695..dad238478 100644 --- a/source/funkin/data/BaseRegistry.hx +++ b/source/funkin/data/BaseRegistry.hx @@ -190,6 +190,19 @@ abstract class BaseRegistry & Constructible + */ + // public function listBaseGameEntryIds():Array {} + + /** + * A list of all entries that are not included in the base game. + * @return Array + */ + // public function listModdedEntryIds():Array {} + public function toString():String { return 'Registry(' + registryId + ', ${countEntries()} entries)'; diff --git a/source/funkin/data/freeplay/player/PlayerRegistry.hx b/source/funkin/data/freeplay/player/PlayerRegistry.hx index b6c3af152..d584398e1 100644 --- a/source/funkin/data/freeplay/player/PlayerRegistry.hx +++ b/source/funkin/data/freeplay/player/PlayerRegistry.hx @@ -18,8 +18,6 @@ class PlayerRegistry extends BaseRegistry impleme public static final PLAYER_DATA_VERSION_RULE:thx.semver.VersionRule = "1.0.x"; - static final baseGamePlayerIds:Array = funkin.util.macro.DataMacro.listBaseGamePlayerIds(); - /** * A mapping between stage character IDs and Freeplay playable character IDs. */ @@ -125,22 +123,4 @@ class PlayerRegistry extends BaseRegistry impleme { return ownedCharacterIds.exists(characterId); } - - /** - * A list of all the playable characters from the base game, in order. - */ - public function listBaseGamePlayerIds():Array - { - return baseGamePlayerIds; - } - - /** - * A list of all installed playable characters that are not from the base game. - */ - public function listModdedPlayerIds():Array - { - return listEntryIds().filter(function(id:String):Bool { - return listBaseGamePlayerIds().indexOf(id) == -1; - }); - } } diff --git a/source/funkin/data/song/SongRegistry.hx b/source/funkin/data/song/SongRegistry.hx index b1a5c0333..fcdabc91f 100644 --- a/source/funkin/data/song/SongRegistry.hx +++ b/source/funkin/data/song/SongRegistry.hx @@ -42,8 +42,6 @@ class SongRegistry extends BaseRegistry implements ISingleto return '${Constants.TITLE} - ${Constants.VERSION}'; } - static final baseGameSongIds:Array = funkin.util.macro.DataMacro.listBaseGameSongIds(); - public function new() { super('SONG', 'songs', SONG_METADATA_VERSION_RULE); @@ -484,24 +482,6 @@ class SongRegistry extends BaseRegistry implements ISingleto return chartData; } - /** - * A list of all the story weeks from the base game, in order. - */ - public function listBaseGameSongIds():Array - { - return baseGameSongIds; - } - - /** - * A list of all installed story weeks that are not from the base game. - */ - public function listModdedSongIds():Array - { - return listEntryIds().filter(function(id:String):Bool { - return listBaseGameSongIds().indexOf(id) == -1; - }); - } - /** * A list of all difficulties for a specific character. */ diff --git a/source/funkin/data/stage/StageRegistry.hx b/source/funkin/data/stage/StageRegistry.hx index 7ff63efde..72c8cb002 100644 --- a/source/funkin/data/stage/StageRegistry.hx +++ b/source/funkin/data/stage/StageRegistry.hx @@ -16,28 +16,8 @@ class StageRegistry extends BaseRegistry implements ISingleton public static final STAGE_DATA_VERSION_RULE:thx.semver.VersionRule = ">=1.0.0 <1.1.0"; - static final baseGameStageIds:Array = funkin.util.macro.DataMacro.listBaseGameStageIds(); - public function new() { super('STAGE', 'stages', STAGE_DATA_VERSION_RULE); } - - /** - * A list of all the stages from the base game, in order. - */ - public function listBaseGameStageIds():Array - { - return baseGameStageIds; - } - - /** - * A list of all installed story weeks that are not from the base game. - */ - public function listModdedStageIds():Array - { - return listEntryIds().filter(function(id:String):Bool { - return listBaseGameStageIds().indexOf(id) == -1; - }); - } } diff --git a/source/funkin/data/story/level/LevelRegistry.hx b/source/funkin/data/story/level/LevelRegistry.hx index 07e18f9a5..4e4f66019 100644 --- a/source/funkin/data/story/level/LevelRegistry.hx +++ b/source/funkin/data/story/level/LevelRegistry.hx @@ -17,8 +17,6 @@ class LevelRegistry extends BaseRegistry implements ISingleton public static final LEVEL_DATA_VERSION_RULE:thx.semver.VersionRule = ">=1.0.0 <1.1.0"; - static final baseGameLevelIds:Array = funkin.util.macro.DataMacro.listBaseGameLevelIds(); - public function new() { super('LEVEL', 'levels', LEVEL_DATA_VERSION_RULE); @@ -26,26 +24,34 @@ class LevelRegistry extends BaseRegistry implements ISingleton /** * A list of all the story weeks from the base game, in order. + * @return Array */ - public function listBaseGameLevelIds():Array + public function listBaseGameEntryIds():Array { - return baseGameLevelIds; - } - - public function listSortedLevelIds():Array - { - var result = listEntryIds(); - result.sort(SortUtil.defaultsThenAlphabetically.bind(listBaseGameLevelIds())); - return result; + // This MUST be hard-coded (overriding the auto-generated method) + // because the auto-generated method spits out values in alphabetical order. + return [ + 'tutorial', + 'week1', + 'week2', + 'week3', + 'week4', + 'week5', + 'week6', + 'week7', + 'weekend1' + ]; } /** - * A list of all installed story weeks that are not from the base game. + * A list of all the story weeks in the game, in order. + * Modded levels are in alphabetical order at the end of the list. + * @return Array */ - public function listModdedLevelIds():Array + public function listSortedLevelIds():Array { - return listEntryIds().filter(function(id:String):Bool { - return listBaseGameLevelIds().indexOf(id) == -1; - }); + var result:Array = listEntryIds(); + result.sort(SortUtil.defaultsThenAlphabetically.bind(listBaseGameEntryIds())); + return result; } } diff --git a/source/funkin/ui/debug/results/ResultsDebugSubState.hx b/source/funkin/ui/debug/results/ResultsDebugSubState.hx index 1d4245258..39dd19d55 100644 --- a/source/funkin/ui/debug/results/ResultsDebugSubState.hx +++ b/source/funkin/ui/debug/results/ResultsDebugSubState.hx @@ -54,7 +54,7 @@ class ResultsDebugSubState extends MusicBeatSubState FlxG.switchState(() -> new funkin.play.ResultState(resultsParams)); }); }); - createToggleListItem("Character", PlayerRegistry.instance.listBaseGamePlayerIds(), function(result:String) { + createToggleListItem("Character", PlayerRegistry.instance.listBaseGameEntryIds(), function(result:String) { resultsParams.characterId = result; }); createToggleListItem("Results Mode", ["Debug", "Story", "Freeplay"], function(result:String) { diff --git a/source/funkin/ui/debug/stageeditor/components/WelcomeDialog.hx b/source/funkin/ui/debug/stageeditor/components/WelcomeDialog.hx index 2794da465..5cc07fbe9 100644 --- a/source/funkin/ui/debug/stageeditor/components/WelcomeDialog.hx +++ b/source/funkin/ui/debug/stageeditor/components/WelcomeDialog.hx @@ -56,7 +56,7 @@ class WelcomeDialog extends Dialog boxDrag.onClick = function(_) FileUtil.browseForSaveFile([FileUtil.FILE_FILTER_FNFS], loadFromFilePath, null, null, "Open Stage Data"); - var defaultStages = StageRegistry.instance.listBaseGameStageIds(); + var defaultStages:Array = StageRegistry.instance.listBaseGameEntryIds(); defaultStages.sort(funkin.util.SortUtil.alphabetically); for (stage in defaultStages) diff --git a/source/funkin/util/macro/DataMacro.hx b/source/funkin/util/macro/DataMacro.hx deleted file mode 100644 index c5898044b..000000000 --- a/source/funkin/util/macro/DataMacro.hx +++ /dev/null @@ -1,59 +0,0 @@ -package funkin.util.macro; - -import haxe.macro.Expr; -#if macro -import sys.FileSystem; -#end - -using StringTools; - -class DataMacro -{ - public static macro function listBaseGameStageIds():Expr - { - var folder = "assets/preload/data/stages/"; - var files = FileSystem.readDirectory(folder); - var stages:Array = []; - - for (file in files) - stages.push(macro $v{file.replace(".json", "")}); - - return macro $a{stages}; - } - - public static macro function listBaseGameSongIds():Expr - { - var folder = "assets/songs/"; - var files = FileSystem.readDirectory(folder); - var songs:Array = []; - - for (file in files) - songs.push(macro $v{file}); - - return macro $a{songs}; - } - - public static macro function listBaseGameLevelIds():Expr - { - var folder = "assets/preload/data/levels/"; - var files = FileSystem.readDirectory(folder); - var levels:Array = []; - - for (file in files) - levels.push(macro $v{file.replace(".json", "")}); - - return macro $a{levels}; - } - - public static macro function listBaseGamePlayerIds():Expr - { - var folder = "assets/preload/data/players/"; - var files = FileSystem.readDirectory(folder); - var players:Array = []; - - for (file in files) - players.push(macro $v{file.replace(".json", "")}); - - return macro $a{players}; - } -} diff --git a/source/funkin/util/macro/RegistryMacro.hx b/source/funkin/util/macro/RegistryMacro.hx index e11687001..bc16e92be 100644 --- a/source/funkin/util/macro/RegistryMacro.hx +++ b/source/funkin/util/macro/RegistryMacro.hx @@ -8,6 +8,7 @@ import haxe.macro.Expr.TypeDefKind; import haxe.macro.Expr.MetadataEntry; import haxe.macro.Type; import haxe.macro.Type.ClassType; +import sys.FileSystem; using Lambda; using haxe.macro.ExprTools; @@ -38,6 +39,8 @@ typedef RegistryTypeParams = */ class RegistryMacro { + static final DATA_FILE_BASE_PATH:String = 'assets/preload/data'; + /** * Builds the registry class. * @@ -139,8 +142,24 @@ class RegistryMacro var createScriptedEntry:String = '${scriptedEntryClsName}.init(clsName, "unknown")'; var newJsonParser:String = 'new json2object.JsonParser<${dataType.module}.${dataType.name}>()'; + + var dataFilePath:String = getRegistryDataFilePath(cls, fields); + var baseGameEntryIds:Array = listBaseGameEntryIds('${DATA_FILE_BASE_PATH}/${dataFilePath}/'); + return (macro class TempClass { + public function listBaseGameEntryIds():Array + { + return $a{baseGameEntryIds}; + } + + public function listModdedEntryIds():Array + { + return listEntryIds().filter(function(id:String):Bool { + return listBaseGameEntryIds().indexOf(id) == -1; + }); + } + function getScriptedClassNames() { return ${Context.parse(getScriptedClassName, Context.currentPos())}.listScriptClasses(); @@ -300,6 +319,59 @@ class RegistryMacro }); } + static function getRegistryDataFilePath(cls:ClassType, fields:Array):String + { + for (field in fields) + { + if (field.name == 'new') + { + // We found a field called `new`, it's probably the constructor. + switch (field.kind) + { + case FFun(f): + // Inside the function. + switch (f.expr.expr) + { + // Inside the block. + case EBlock(exprs): + var superCall:Expr = exprs[0]; + switch (superCall.expr) + { + // Inside the super() call. + case ECall(_, args): + // var registryId:String = args[0].toString(); + var dataPath:String = args[1].toString().replace('"', '').replace("'", ''); + // var versionRule = args[2].toString(); + + return dataPath; + default: + Context.error('${cls.name}.new: RegistryMacro expected super call', field.pos); + } + default: + Context.error('${cls.name}.new: RegistryMacro expected super call', field.pos); + } + default: + // Continue looking for the actual constructor. + } + } + } + + return ''; + } + + static function listBaseGameEntryIds(dataFilePath:String):Array + { + var result:Array = []; + var files:Array = FileSystem.readDirectory(dataFilePath); + + for (file in files) + { + result.push(macro $v{file.replace('.json', '')}); + } + + return result; + } + /** * Check whether this class has already been processed by the RegistryMacro, * as indicated by the `@:funkinProcessed` meta.