diff --git a/source/funkin/util/macro/ClassMacro.hx b/source/funkin/util/macro/ClassMacro.hx index d014619a9..69d4b2537 100644 --- a/source/funkin/util/macro/ClassMacro.hx +++ b/source/funkin/util/macro/ClassMacro.hx @@ -13,6 +13,11 @@ import haxe.macro.Type.ClassType; @:nullSafety class ClassMacro { + /** + * The name for the Haxe resource that stores Generation Metadata. + */ + static inline final METADATA_RESOURCE_NAME:String = 'Funkin_CompiledClassList'; + /** * Gets a list of `Class` for all classes in a specified package. * @@ -42,7 +47,7 @@ class ClassMacro * * Example: `var list:Array> = listSubclassesOf(FlxSprite);` * - * @param targetClass The class to query for subclasses. + * @param targetClassExpr The class to query for subclasses. * @return A list of classes matching the specified criteria. */ public static macro function listSubclassesOf(targetClassExpr:ExprOf>):ExprOf>> @@ -122,31 +127,31 @@ class ClassMacro */ static function compileClassLists() { - var compiledClassList:ClassType = MacroUtil.getClassType("funkin.util.macro.CompiledClassList"); + var compiledClassList:ClassType = MacroUtil.getClassType('funkin.util.macro.CompiledClassList'); - if (compiledClassList == null) throw "Could not find CompiledClassList class."; + if (compiledClassList == null) throw 'Could not find CompiledClassList class.'; // Reset outdated metadata. if (compiledClassList.meta.has('classLists')) compiledClassList.meta.remove('classLists'); - var classLists:Array = []; + var classLists:Array> = []; // Generate classLists. for (request in classListsToGenerate) { // Expression contains String, [Class...] - var classListEntries:Array = [macro $v{request}]; + var classListEntries:Array = [request]; for (i in classListsRaw.get(request)) { // TODO: Boost performance by making this an Array> instead of an Array // How to perform perform macro reificiation to types given a name? - classListEntries.push(macro $v{i}); + classListEntries.push(i); } - classLists.push(macro $a{classListEntries}); + classLists.push(classListEntries); } - // Insert classLists into metadata. - compiledClassList.meta.add('classLists', classLists, Context.currentPos()); + var classListsHXSF = haxe.Serializer.run(classLists); + Context.addResource(METADATA_RESOURCE_NAME, haxe.io.Bytes.ofString(classListsHXSF)); } static function doesClassMatchRequest(classType:ClassType, request:String):Bool diff --git a/source/funkin/util/macro/CompiledClassList.hx b/source/funkin/util/macro/CompiledClassList.hx index becb21ec3..ff6b69f14 100644 --- a/source/funkin/util/macro/CompiledClassList.hx +++ b/source/funkin/util/macro/CompiledClassList.hx @@ -10,6 +10,11 @@ using funkin.util.AnsiUtil; @:nullSafety class CompiledClassList { + /** + * The name for the Haxe resource that stores Generation Metadata. + */ + static inline final METADATA_RESOURCE_NAME:String = 'Funkin_CompiledClassList'; + static var classLists:Map>> = []; static var initialized:Bool = false; @@ -21,25 +26,21 @@ class CompiledClassList { initialized = true; - // Meta.getType returns Dynamic>. - var metaData = Meta.getType(CompiledClassList); + var metadata:Array> = fetchMetadata(); - if (metaData.classLists != null) + if (metadata != null) { - for (list in metaData.classLists) + for (data in metadata) { - var data:Array = cast list; - // First element is the list ID. - var id:String = cast data[0]; + var id:String = data[0]; // All other elements are class types. var classes:List> = new List(); for (i in 1...data.length) { - var className:String = cast data[i]; - // var classType:Class = cast data[i]; - var classType:Class = cast Type.resolveClass(className); + var className:String = data[i]; + var classType:Class = Type.resolveClass(className); classes.push(classType); } @@ -48,10 +49,27 @@ class CompiledClassList } else { - throw "Class lists not properly generated. Try cleaning out your export folder, restarting your IDE, and rebuilding your project."; + throw 'Class lists not properly generated. Try cleaning out your export folder, restarting your IDE, and rebuilding your project.'; } } + static var _metadata:Dynamic = null; + + static function fetchMetadata():Dynamic + { + if (_metadata != null) return _metadata; + + var classListsHXSF:String = haxe.Resource.getString(METADATA_RESOURCE_NAME); + _metadata = haxe.Unserializer.run(classListsHXSF); + return _metadata; + } + + /** + * Request a list of classes that match the specified criteria. + * + * @param request The request. See `ClassMacro` for more information. + * @return The list of matching classes. + */ public static function get(request:String):List> { if (!initialized) init(); @@ -67,6 +85,14 @@ class CompiledClassList return classLists.get(request); } + /** + * Request a list of classes that match the specified criteria. + * Casts the list to match the specified type. + * + * @param request The request. See `ClassMacro` for more information. + * @param type The type of classes to cast the list to. + * @return The list of matching classes. + */ public static inline function getTyped(request:String, type:Class):List> { return cast get(request);