List of assets from project.xml

I’m trying to improve the HaxeFlixel AssetPaths util, currently it enumerates every file in the desired folder and creates a static field with the filepath of each. I would like to add an optional flag that limits this to files that will be included in the build via the Project.xml’s <asset/> tags. I’m planning to check “export/[target]/bin/assets/” rather than “assets/” but I’m wondering if theres a better way, since the exported assets may not exist yet, or might be out of date. There’s also other reasons why I shouldn’t do it this way.

Is there a way (in a macro) to do one or more of the following:

  1. Get a list of files that will be exported
  2. Check whether a specific filepath will be exported
  3. Get a list of asset tags in the Project.xml and their inclide/exclude args
  4. any better ideas you might have

Thanks in advance

I think that you can load project.xml in a macro using sys.io.File.getContent(). Then, pass the string to Xml.parse(), and you have an Xml object that you can query for the assets.

1 Like

It’s possible, I was hoping the data was processed into haxe code somewhere already. That’s fine I’ll just stop being lazy

At runtime, openfl.utils.Assets.list() will return a list of embedded assets, according to the docs.

1 Like

Nice! I need this at compile-time, but that’s a good starting point to see exactly how openfl does what I’m trying to do. Thanks!

Wouldn’t HXProject.assets have the data you need? If you were using HXP format, you could copy the data from there into a text file, and open the text file when running the macro.

I looked into this but I couldn’t figure out how to access the the HProject instance, or the ProjectXMLParser instance that lime uses already. I tried making my own instance with the project xml data, but I ran into some problems and can’t remember what they were. I’ll try again and report back with better info, when I get a chance

Right, sorry, I was thinking of a different use case. Thought you were doing this for a personal project rather than for Flixel. Rereading the opening post cleared that up.

Speaking of the opening post, I’d like to clarify that the exported assets will already exist. It’s true that some could be stale, but the asset manifest won’t be, so that would still be fine. The problem is that neither the manifest nor the files themselves will tell you where they were copied from, or what the filename was prior to being renamed. So it still isn’t a solution.


Anyway, parsing project.xml could work. Just keep in mind that the user can name it anything, so long as the extension is “xml”, “hxp”, “nmml”, or “lime”. You’ll have to search the project directory for files that match, and then parse them.

My suggestion is to base your implementation on CommandLineTools:

if (Path.extension(projectFile) == "lime" || Path.extension(projectFile) == "nmml" || Path.extension(projectFile) == "xml")
{
	project = new ProjectXMLParser(projectFile, Context.getDefines());
}
else if (Path.extension(projectFile) == "hxp")
{
	project = HXProject.fromFile(projectFile, Context.getDefines());
}

I can’t see a way to get includePaths, so you’ll have to do without that. Context.getDefines() is probably close enough to the original set of defines, as long as the project doesn’t do something weird like toggle a define.

not gonna lie, it seems like more work than I can afford right now, a simpler solution would probably be to look at the exported folder, but that means that a project won’t have code completion until the first build, which could add friction to newcomers learning from demos. it also means people will need to prune or clean old files from their export folders routinely. With the current implementation, it works out-of-box, but they need to copy the project.xml’s include/exclude (if desired). another benefit of using the export folder is that it would work with rename arg in assets tags. but the user will need to specify paths of the renamed assets.

Maybe I’ll just have both? but neither is a great solution

Oh wait, you’re willing to work with the renamed asset paths? That makes things somewhat easier.

It would take a little time, but you can generate the assets (and more importantly, the asset manifests) by calling lime update <target>. This is lightning fast compared to lime build, so users might not even notice the delay if you invoked it from a build macro.

The reason I keep telling you to use the asset manifest is because it completely avoids the “users have to prune or clean old files from their export folders” thing. The asset manifest only includes the files that are meant to be there, not the ones that are left over from old builds.

Call fromFile()* to parse, then list() to get asset paths. list(null) gets all assets, or you can pass an AssetType to filter.

*Note that while the manifest can usually be found at Export/$target/bin/manifest/default.json, some targets such as Android use a different path.

Does it matter that this is being called from a lime display call rather than a build? what exactly does lime update do, I can’t find info? While I don’t how how frequently VShaxe calls lime display but I assume it’s a lot. maybe I would only call it if the manifest is missing? Still seems odd to create an export folder as soon as they start messing around with a project in vscode

Edit: update – Copy assets for the specified project and target

I think lime display is only called on startup or when the target changes, so not nearly as often as code completion is triggered. Even so, I’d only call it when the manifest is missing.

I agree, it’s odd to create the export folder that soon, but since it’s only users who actively use AssetPaths with a certain setting, it probably isn’t too intrusive.

Can’t seem to access the AssetLibrary class in macro space without modifying lime, it seems

/src/lime/graphics/opengl/GLBuffer.hx:16: characters 20-40 : You cannot access the js package while in a macro (for js.html.webgl.Buffer)
/src/lime/_internal/backend/native/NativeCFFI.hx:4: characters 8-37 : ... referenced here
/src/lime/system/System.hx:4: characters 8-48 : ... referenced here
/src/lime/app/Future.hx:3: characters 8-26 : ... referenced here
/src/lime/utils/AssetLibrary.hx:5: characters 8-23 : ... referenced here
/flixel/system/macros/FlxAssetPaths.hx:117: characters 13-36 : ... referenced here

Same with AssetManifest

FYI this would be the case for all people using the new AssetPaths, which may be added to the template, not just people who use a rename arg in asset tags

Ugh, yeah, that’ll happen if the class isn’t written for it. Looks like you can do Unserializer.run(Json.parse(File.getContent("manifest/default.json")).assets) instead.

I was referring back to the first post, where you said “I would like to add an optional flag that limits this to files that will be included in the build.” Is that no longer the plan?

I was referring back to the first post, where you said “I would like to add an optional flag that limits this to files that will be included in the build.” Is that no longer the plan?

You’re right I forgot I brought that up, it’s still to be decided. although yeah, maybe this doesn’t have to be the included with the template flixel project, these advanced features probably aren’t needed a majority of the time.

Unserializer.run(Json.parse(File.getContent(“manifest/default.json”)).assets)

I was so very close to trying this, but nonetheless, thanks for this and everything else you’ve helped me with. This is coming along nicely. although this wont be possible to use in flash, since there is no public manifest file in the export folder

Last question, is there an easy way to get the target name for the export path without manually checking all of the compile flags?

Try Compiler.getOutput(). It’ll just need a bit of string manipulation.

1 Like

looks like it’s called every time code completion is triggered

Good to know. Hope this turns out well!