I'd like a (platform independent) way to list all classes from a package.
A possible way would be get a list of all classes known by Haxe, then filtering through it.
I'd like a (platform independent) way to list all classes from a package.
A possible way would be get a list of all classes known by Haxe, then filtering through it.
This is one way to store and retrieve the information: https://gist.github.com/back2dos/c9410ed3ed476ecc1007
Beyond that you could use haxe -xml
to get the type information you want, then transform it as needed (use the parser from haxe.rtti
to handle the data) and embed the JSON encoded result with -resource theinfo.json
(accessed through haxe.Resource
).
As a side note: there are chances you'll be better off not having any automation and just add the classes to an array manually. Imagine you have somepackage.ClassA
, somepackage.ClassB
, ... then you can do
import somepackage.*;
//...
static var CLASSES:Array<Class<Dynamic>> = [ClassA, ClassB, ...];
It gives you more flexibility as whatever you want to do, you can always add 3rd party classes, which may not necessarily be in the same package and you can also choose to not use a class without having to delete it.
ClassList.ALL_CLASSES.filter(~/^mypackage\./.match)
and you've got all that. As you've said yourself, that is one way to do it. Jason's solution works pretty much that way under the hood. If that API is convenient, use it. If not, use my example as a basis to build your own. –
Escargot ClassList
in your example? –
Hypoglycemia ClassList
. –
Escargot I made a macro to help with just this. It's in the compiletime haxelib.
haxelib install compiletime
And then add it to your build (hxml file):
-lib compiletime
And then use it to import your classes:
// All classes in this package, including sub packages.
var testcases = CompileTime.getAllClasses("my.package");
// All classes in this package, not including sub packages.
var testcases = CompileTime.getAllClasses("my.package",false);
// All classes that extend (or implement) TestCase
var testcases = CompileTime.getAllClasses(TestCase);
// All classes in a package that extend TestCase
var testcases = CompileTime.getAllClasses("my.package",TestCase);
And then you can iterate over them:
for ( testClass in testcases ) {
var test = Type.createInstance( testClass, [] );
}
Please note, if you never have "import some.package.SomeClass" in your code, that class will never be included, because of dead code elimination. So if you want to make sure it gets included, even if you never explicitly call it in your code, you can do something like this:
CompileTime.importPackage( "mygame.levels" );
CompileTime.getAllClasses( "mygame.levels", GameLevel );
How it works
CompileTime.getAllClasses
is a macro, and what it does is:
@classLists(...)
metadata on the CompileTimeClassList
file, containing the names of all the matching classes.Type.resolveClass(...)
to create a list of all matching types.m.classLists
(used in CompileTimeClassList.hx) documnted somewhere? –
Hypoglycemia m
there is the metadata on the CompileTimeClassList
class. m.classLists
is getting the @classLists(...)
metadata that the macro created, which contains the names of all the relevant classes. I haven't got any further documentation on the exact structure of the metadata, but you could add a trace()
in if you are curious :) –
Leelah This is one way to store and retrieve the information: https://gist.github.com/back2dos/c9410ed3ed476ecc1007
Beyond that you could use haxe -xml
to get the type information you want, then transform it as needed (use the parser from haxe.rtti
to handle the data) and embed the JSON encoded result with -resource theinfo.json
(accessed through haxe.Resource
).
As a side note: there are chances you'll be better off not having any automation and just add the classes to an array manually. Imagine you have somepackage.ClassA
, somepackage.ClassB
, ... then you can do
import somepackage.*;
//...
static var CLASSES:Array<Class<Dynamic>> = [ClassA, ClassB, ...];
It gives you more flexibility as whatever you want to do, you can always add 3rd party classes, which may not necessarily be in the same package and you can also choose to not use a class without having to delete it.
ClassList.ALL_CLASSES.filter(~/^mypackage\./.match)
and you've got all that. As you've said yourself, that is one way to do it. Jason's solution works pretty much that way under the hood. If that API is convenient, use it. If not, use my example as a basis to build your own. –
Escargot ClassList
in your example? –
Hypoglycemia ClassList
. –
Escargot © 2022 - 2024 — McMap. All rights reserved.