Hello all!
It’s been a while since I touched the OpenFL forums, primarily because most of the time I am able to resolve Haxe-related issues on my own. Macros is very powerful, too powerful in fact, and complex.
Currently, I am attempting to build a macro to read my story files and parsing it into a series of function calls. I have successfully generated a class that contains all of the files interpreted as a Conversation
, which is a class containing update and render calls in my game engine.
The Conversation
also contains functions such as overlay
which takes one argument.
An example of this in the files I interpret looks like this:
~ Cultism has sought to wreak havoc upon humanity.
I would go through each file line by line and generate a function that initialises the Conversation
and calls each of these procedures accordingly.
class Convos
{
// Generated from macro:
public static var ch1_intro:Conversation;
public static function ch1_intro_init():Conversation
{
ch1_intro = new Conversation(); // This is as far as I can generate without needing help
ch1_intro.overlay("Cultism has sought to wreak havoc upon humanity.");
return ch1_intro;
}
}
The code I use to generate this is as follows:
class ConvoBuilder
{
public static macro function build():Array<Field>
{
var fields = Context.getBuildFields();
var path = "D:\\Business\\IT\\Internal\\Story\\Age of Atlantis";
var chapters = FileSystem.readDirectory(path);
for (chapter in chapters)
{
if (FileSystem.isDirectory(path + "\\" + chapter))
{
var files = FileSystem.readDirectory(path + "\\" + chapter);
for (file in files)
{
if (!FileSystem.isDirectory(path + "\\" + chapter + "\\" + file))
{
var name = chapter + "_" + file.split(" ").join("_").toLowerCase();
fields.push({
name: name,
doc: null,
meta: [],
access: [APublic, AStatic],
kind: FVar(macro: render.Conversation, macro null),
pos: Context.currentPos()
});
var initExpr = macro {
$i{name} = new render.Conversation();
return $i{name};
};
fields.push({
name: name + "_init",
doc: null,
meta: [],
access: [APublic , AStatic],
kind: FFun({
ret: Context.toComplexType(Context.getType("render.Conversation")),
params: null,
expr: initExpr,
args: []
}),
pos: Context.currentPos()
});
}
}
}
}
return fields;
}
public static macro function buildProcedures(file:String):Void
{
var contents = File.getContent(file);
var lines = contents.split("\n");
for (line in lines)
{
if (line == "\r")
continue;
if (line.startsWith("~"))
{
var text = line.substr(2);
Context.makeExpr(macro { overlay($v{text}); }, Context.currentPos());
}
}
}
}
The bit I am stuck on is appending the Expr
value initExpr
in the above code such that when I parse the file, I can generate the above example code. I know how to accomplish the code generation, but I am unsure what the procedures are to append an existing Expr, or inject a macro function such as the buildProcedures
function below to generate an Array<Expr>
…
Can anyone help provide their macro expertise? Any help would be appreciated!