Edit RegistryMacro to automatically populate baseGameEntryIds list.
This commit is contained in:
committed by
Cameron Taylor
parent
14975212a9
commit
963e2ecd63
@@ -190,6 +190,19 @@ abstract class BaseRegistry<T:(IRegistryEntry<J> & Constructible<EntryConstructo
|
||||
return entries.get(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* A list of all entries included in the base game.
|
||||
* The actual function exists and is auto-generated on each registry at build time.
|
||||
* @return Array<String>
|
||||
*/
|
||||
// public function listBaseGameEntryIds():Array<String> {}
|
||||
|
||||
/**
|
||||
* A list of all entries that are not included in the base game.
|
||||
* @return Array<String>
|
||||
*/
|
||||
// public function listModdedEntryIds():Array<String> {}
|
||||
|
||||
public function toString():String
|
||||
{
|
||||
return 'Registry(' + registryId + ', ${countEntries()} entries)';
|
||||
|
||||
@@ -18,8 +18,6 @@ class PlayerRegistry extends BaseRegistry<PlayableCharacter, PlayerData> impleme
|
||||
|
||||
public static final PLAYER_DATA_VERSION_RULE:thx.semver.VersionRule = "1.0.x";
|
||||
|
||||
static final baseGamePlayerIds:Array<String> = funkin.util.macro.DataMacro.listBaseGamePlayerIds();
|
||||
|
||||
/**
|
||||
* A mapping between stage character IDs and Freeplay playable character IDs.
|
||||
*/
|
||||
@@ -125,22 +123,4 @@ class PlayerRegistry extends BaseRegistry<PlayableCharacter, PlayerData> impleme
|
||||
{
|
||||
return ownedCharacterIds.exists(characterId);
|
||||
}
|
||||
|
||||
/**
|
||||
* A list of all the playable characters from the base game, in order.
|
||||
*/
|
||||
public function listBaseGamePlayerIds():Array<String>
|
||||
{
|
||||
return baseGamePlayerIds;
|
||||
}
|
||||
|
||||
/**
|
||||
* A list of all installed playable characters that are not from the base game.
|
||||
*/
|
||||
public function listModdedPlayerIds():Array<String>
|
||||
{
|
||||
return listEntryIds().filter(function(id:String):Bool {
|
||||
return listBaseGamePlayerIds().indexOf(id) == -1;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,8 +42,6 @@ class SongRegistry extends BaseRegistry<Song, SongMetadata> implements ISingleto
|
||||
return '${Constants.TITLE} - ${Constants.VERSION}';
|
||||
}
|
||||
|
||||
static final baseGameSongIds:Array<String> = funkin.util.macro.DataMacro.listBaseGameSongIds();
|
||||
|
||||
public function new()
|
||||
{
|
||||
super('SONG', 'songs', SONG_METADATA_VERSION_RULE);
|
||||
@@ -484,24 +482,6 @@ class SongRegistry extends BaseRegistry<Song, SongMetadata> implements ISingleto
|
||||
return chartData;
|
||||
}
|
||||
|
||||
/**
|
||||
* A list of all the story weeks from the base game, in order.
|
||||
*/
|
||||
public function listBaseGameSongIds():Array<String>
|
||||
{
|
||||
return baseGameSongIds;
|
||||
}
|
||||
|
||||
/**
|
||||
* A list of all installed story weeks that are not from the base game.
|
||||
*/
|
||||
public function listModdedSongIds():Array<String>
|
||||
{
|
||||
return listEntryIds().filter(function(id:String):Bool {
|
||||
return listBaseGameSongIds().indexOf(id) == -1;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* A list of all difficulties for a specific character.
|
||||
*/
|
||||
|
||||
@@ -16,28 +16,8 @@ class StageRegistry extends BaseRegistry<Stage, StageData> implements ISingleton
|
||||
|
||||
public static final STAGE_DATA_VERSION_RULE:thx.semver.VersionRule = ">=1.0.0 <1.1.0";
|
||||
|
||||
static final baseGameStageIds:Array<String> = 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<String>
|
||||
{
|
||||
return baseGameStageIds;
|
||||
}
|
||||
|
||||
/**
|
||||
* A list of all installed story weeks that are not from the base game.
|
||||
*/
|
||||
public function listModdedStageIds():Array<String>
|
||||
{
|
||||
return listEntryIds().filter(function(id:String):Bool {
|
||||
return listBaseGameStageIds().indexOf(id) == -1;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,8 +17,6 @@ class LevelRegistry extends BaseRegistry<Level, LevelData> implements ISingleton
|
||||
|
||||
public static final LEVEL_DATA_VERSION_RULE:thx.semver.VersionRule = ">=1.0.0 <1.1.0";
|
||||
|
||||
static final baseGameLevelIds:Array<String> = funkin.util.macro.DataMacro.listBaseGameLevelIds();
|
||||
|
||||
public function new()
|
||||
{
|
||||
super('LEVEL', 'levels', LEVEL_DATA_VERSION_RULE);
|
||||
@@ -26,26 +24,34 @@ class LevelRegistry extends BaseRegistry<Level, LevelData> implements ISingleton
|
||||
|
||||
/**
|
||||
* A list of all the story weeks from the base game, in order.
|
||||
* @return Array<String>
|
||||
*/
|
||||
public function listBaseGameLevelIds():Array<String>
|
||||
public function listBaseGameEntryIds():Array<String>
|
||||
{
|
||||
return baseGameLevelIds;
|
||||
}
|
||||
|
||||
public function listSortedLevelIds():Array<String>
|
||||
{
|
||||
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<String>
|
||||
*/
|
||||
public function listModdedLevelIds():Array<String>
|
||||
public function listSortedLevelIds():Array<String>
|
||||
{
|
||||
return listEntryIds().filter(function(id:String):Bool {
|
||||
return listBaseGameLevelIds().indexOf(id) == -1;
|
||||
});
|
||||
var result:Array<String> = listEntryIds();
|
||||
result.sort(SortUtil.defaultsThenAlphabetically.bind(listBaseGameEntryIds()));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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<String> = StageRegistry.instance.listBaseGameEntryIds();
|
||||
defaultStages.sort(funkin.util.SortUtil.alphabetically);
|
||||
|
||||
for (stage in defaultStages)
|
||||
|
||||
@@ -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<Expr> = [];
|
||||
|
||||
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<Expr> = [];
|
||||
|
||||
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<Expr> = [];
|
||||
|
||||
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<Expr> = [];
|
||||
|
||||
for (file in files)
|
||||
players.push(macro $v{file.replace(".json", "")});
|
||||
|
||||
return macro $a{players};
|
||||
}
|
||||
}
|
||||
@@ -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<Expr> = listBaseGameEntryIds('${DATA_FILE_BASE_PATH}/${dataFilePath}/');
|
||||
|
||||
return (macro class TempClass
|
||||
{
|
||||
public function listBaseGameEntryIds():Array<String>
|
||||
{
|
||||
return $a{baseGameEntryIds};
|
||||
}
|
||||
|
||||
public function listModdedEntryIds():Array<String>
|
||||
{
|
||||
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<Field>):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<Expr>
|
||||
{
|
||||
var result:Array<Expr> = [];
|
||||
var files:Array<String> = 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.
|
||||
|
||||
Reference in New Issue
Block a user