Rewrite the CompiledClassList macro to use a resource
This commit is contained in:
@@ -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<T>` for all classes in a specified package.
|
||||
*
|
||||
@@ -42,7 +47,7 @@ class ClassMacro
|
||||
*
|
||||
* Example: `var list:Array<Class<FlxSprite>> = 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<T>(targetClassExpr:ExprOf<Class<T>>):ExprOf<List<Class<T>>>
|
||||
@@ -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<Expr> = [];
|
||||
var classLists:Array<Array<String>> = [];
|
||||
// Generate classLists.
|
||||
for (request in classListsToGenerate)
|
||||
{
|
||||
// Expression contains String, [Class<T>...]
|
||||
var classListEntries:Array<Expr> = [macro $v{request}];
|
||||
var classListEntries:Array<String> = [request];
|
||||
for (i in classListsRaw.get(request))
|
||||
{
|
||||
// TODO: Boost performance by making this an Array<Class<T>> instead of an Array<String>
|
||||
// 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
|
||||
|
||||
@@ -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<String, List<Class<Dynamic>>> = [];
|
||||
static var initialized:Bool = false;
|
||||
|
||||
@@ -21,25 +26,21 @@ class CompiledClassList
|
||||
{
|
||||
initialized = true;
|
||||
|
||||
// Meta.getType returns Dynamic<Array<Dynamic>>.
|
||||
var metaData = Meta.getType(CompiledClassList);
|
||||
var metadata:Array<Array<String>> = fetchMetadata();
|
||||
|
||||
if (metaData.classLists != null)
|
||||
if (metadata != null)
|
||||
{
|
||||
for (list in metaData.classLists)
|
||||
for (data in metadata)
|
||||
{
|
||||
var data:Array<Dynamic> = 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<Class<Dynamic>> = new List();
|
||||
for (i in 1...data.length)
|
||||
{
|
||||
var className:String = cast data[i];
|
||||
// var classType:Class<Dynamic> = cast data[i];
|
||||
var classType:Class<Dynamic> = cast Type.resolveClass(className);
|
||||
var className:String = data[i];
|
||||
var classType:Class<Dynamic> = 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<Class<Dynamic>>
|
||||
{
|
||||
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<T>(request:String, type:Class<T>):List<Class<T>>
|
||||
{
|
||||
return cast get(request);
|
||||
|
||||
Reference in New Issue
Block a user