HXP Projects

If you look closely at the OpenFL “docs” page, you’ll notice it lists two options under “project files.” The first of the two is the XML format you know and love, or at least know, but what’s up with the second?

Before I answer that question, I have some questions for you to answer.

Is your project file getting out of hand? Do you wish the XML format supported more advanced string manipulation? Do you find yourself typing out multiple <set> tags to simulate the “or” operator? Have you ever tried and failed to copy a directory with the <template> tag?

If you answered “yes” to any of these questions, HXP files may be right for you. Consult your physician today!

So anyway, what are HXP files? The short answer is, they’re HX files with an extra P.

The P stands for “Project,” so the long answer is, they’re project files which let you use Haxe instead of XML. You can write functions, manipulate strings, declare variables, and even access Haxe’s standard library.

Let’s try it out!

Ok, find a sample project that uses an HXP file, and… oh. There aren’t any, are there?

Fine, we’ll use DisplayingABitmap. I’ve created an HXP version of the project file, available here. Save it as project.hxp, delete project.xml, and you’re ready to give it a try.

Lime recognizes the file format, so just run lime test neko and it’ll find the new project file. It should show the OpenFL logo in the middle of the screen.

Congratulations! Through no fault of your own, you have gotten an HXP project file to work!

Converting your XML file to HXP

Running a sample project is all well and good, but what about that much larger project file you want to convert? Or perhaps that large file that you don’t want to convert because it will be so much work, but you have to convert anyway? Sometimes it’s the latter.

To make your job easier, I recommend copying over these functions. With those in place, here’s a conversion guide:

- <set name="godMode" />
+ defines.set("godMode", 1);
+ //Or if you only need it for conditionals:
+ var godMode:Bool = true;

- <setenv name="DARK_AND_STORMY_NIGHT" />
+ setenv("DARK_AND_STORMY_NIGHT", "1");
+ //That second value must be a string and cannot be skipped.

- <setenv name="TRUE" value="FALSE" />
+ setenv("TRUE", "FALSE");
+ //Please do not do this.

- <haxedef name="Robert'); DROP TABLE Students;--" />
+ haxedefs["Robert'); DROP TABLE Students;--"] = 1;
+ //Please do not do this either.

- <haxedef name="dump=pretty" />
+ haxedefs["dump"] = "pretty";

- <haxeflag name="-dce" value="std" />
+ haxeflags.push("-dce std");

- <section if="flash"> </section>
+ if(target == Platform.FLASH) { }

- <section if="godMode" unless="mobile"> </section>
+ if(defines.exists("godMode") && platformType != PlatformType.MOBILE) { }

- <ndll name="regexp" />
+ ndll("regexp");

- <assets path="assets/text" rename="text" include="*.txt|*xml" exclude="*.rtf" />
+ includeAssets("assets/text", "text", ["*.txt", "*.xml"], ["*.rtf"]);

- <certificate path="correcthorse.keystore" password="batterystaple" alias="AzureDiamond" alias-password="hunter2" />
+ certificate = new Keystore("correcthorse.keystore", "batterystaple", "AzureDiamond", "hunter2");

- <dependency name="GooglePlayServices" path="pathtoGooglePlayServices" />
+ dependency("GooglePlayServices", "pathtoGooglePlayServices");

- <dependency name="GameKit.framework" />
+ dependency("GameKit.framework");

- <dependency path="/Library/Frameworks/LameKit.framework" />
+ dependencyByPath("/Library/Frameworks/LameKit.framework");

- <include path="industrial/application.xml" />
+ merge(new ProjectXMLParser("industrial/application.xml", defines));

- <template path="templates/CureForCancer.java" rename="src/com/jir/research/CureForCancer.java" />
+ templateFile("templates/CureForCancer.java", "src/com/jir/research/CureForCancer.java");

- <template path="templates/" rename="src/com/jir/research/" />
+ templatePaths.push("templates/");

Those are most of the existing tags, but if I missed one, you can always refer to the source.

Template directories

I also tossed in a new feature: template directories that actually do what you expect them to do.

If you’ve ever tried passing a folder to <template path="x">, you’ve probably been very disappointed. While Lime is quite good at taking a single file, processing it as a template, and putting it where you want, it absolutely refuses to do that with directories.To be specific, if you specify a directory, Lime expects to find a folder structure exactly matching its own template directory. A subdirectory for each target, and a very specific arrangement of files within those subdirectories.I guess that can be useful, but it really isn’t what you’d expect. If you can copy individual files into place…

<template path="templates/SourceFile0.java" rename="src/com/example/SourceFile0.java" />
<template path="templates/SourceFile1.java" rename="src/com/example/SourceFile1.java" />
<template path="templates/SourceFile2.java" rename="src/com/example/SourceFile2.java" />

…Why can’t you do it in bulk?

<template path="templates/" rename="src/com/example/" />

I honestly don’t know why XML projects work that way, but I do know you can make it work in HXP!

templateDirectory("templates/", "src/com/example/");

One step at a time

If this is too much work to do all at once, then keep your old project file around, and import it into the new one:

merge(new ProjectXMLParser("old_application.xml", defines));

With that done, you’re free to move items over one at a time. Just be warned that some features, such as the <template> tag for folders, may quit working correctly. If this happens, focus on converting them first.

Leave a Reply

Your email address will not be published. Required fields are marked *