Created
June 6, 2021 15:36
-
-
Save KinoAR/41e8966c3d7907132b464e521985d9a2 to your computer and use it in GitHub Desktop.
Aseprite Build Macro example.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package buildMacros; | |
import Structs.ZoomT; | |
import sys.FileSystem; | |
#if macro | |
import Structs.ChangeColorT; | |
import Structs.ChangeBrushT; | |
import haxe.macro.ExprTools; | |
import haxe.macro.Expr.Field; | |
import haxe.macro.Context; | |
import haxe.macro.Expr; | |
import haxe.macro.Type; | |
using haxe.macro.Tools; | |
using Lambda; | |
using StringTools; | |
import sys.Http; | |
import sys.io.File; | |
#end | |
/** | |
* Loads the Aseprite raw xml and parses it for | |
* creating commands for the command class. | |
* @return Array<Field> | |
*/ | |
inline var FILE_PATH = 'aseprite-gui-link.txt'; | |
//https://raw.githubusercontent.com/aseprite/aseprite/main/data/gui.xml <-- aseprite-gui-link.txt content | |
//Establish macro context with #if | |
#if macro | |
macro function buildAppComands():Array<Field> { | |
var buildFields = Context.getBuildFields(); //Gets the fields on the class we apply the build macro to. | |
// Load Aseprite XML Data | |
var fileContents = File.getContent(FILE_PATH); | |
var result = Http.requestUrl(fileContents); //HTTP request to get XML data for parsing | |
var xmlContent = Xml.parse(result); | |
//Going to the command elements in the gui.xml | |
var keyboardCommandsNode = xmlContent.firstElement() | |
.firstElement() | |
.firstElement(); | |
//Process each command in the XML element list | |
for (command in keyboardCommandsNode.elements()) { | |
//Filter out duplicate fields | |
if (command.exists('command') && !buildFields.exists((field) -> { | |
return field.name == command.get('command'); | |
})) { | |
// Switch Case to determine struct to use as args | |
var args = []; | |
var documentation = null; | |
//Switch case dedicated to creating function arguments for the created function fields | |
documentation = FileSystem.exists('res/${command.get('command')}.hx') ? File.getContent('res/${command.get('command')}.hx') : File.getContent('res/Blank.hx'); | |
var arg:FunctionArg = switch (command.get('command')) { | |
//Creates the type definition for the aseprite ChangeBrush command function and the name of the parameter. | |
case "ChangeBrush": | |
{ | |
name: "ChangeBrush", | |
type: (macro:{ | |
?change:String, | |
?slot:Int | |
}) | |
} | |
case "ChangeColor": | |
{ | |
name: "ChangeColor", | |
type: (macro:{ | |
target:String, | |
change:String | |
}) | |
} | |
case "Scroll": | |
{ | |
name: "Scroll", | |
type: (macro:{ | |
direction:String, | |
units:String, | |
quantity:Int, | |
}) | |
} | |
case "MoveMask": | |
{ | |
name: "MoveMask", | |
type: (macro:{ | |
target:String, | |
direction:String, | |
units:String, | |
quantity:Int | |
}) | |
} | |
case "SymmetryMode": | |
{ | |
name: "SymmetryMode", | |
type: (macro:{ | |
orientation:String | |
}) | |
} | |
case "AutocropSprite": | |
{ | |
name: "AutocropSprite", | |
type: (macro:{ | |
byGrid:Bool | |
}) | |
} | |
case "Screenshot": | |
{ | |
name: "Screenshot", | |
type: (macro:{ | |
srgb:Bool, | |
?save:Bool | |
}) | |
} | |
case "LayerOpacity": | |
{ | |
name: "LayerOpacity", | |
type: macro:{ | |
opacity:Int | |
} | |
} | |
case "Zoom": | |
{ | |
name: "Zoom", | |
type: (macro:{ | |
?action:String, | |
?percentage:Int | |
}) | |
} | |
case "SetInkType": | |
{ | |
name: "SetInkType", | |
type: (macro:{ | |
type:String | |
}) | |
} | |
case "SetColorSelector": | |
{ | |
name: "SetColorSelector", | |
type: (macro:{ | |
type:String | |
}) | |
} | |
case "AddColor": | |
{ | |
name: "AddColor", | |
type: (macro:{ | |
source:String | |
}) | |
} | |
case "SelectTile": | |
{ | |
name: "SelectTile", | |
type: (macro:{ | |
mode:String | |
}) | |
} | |
case _: | |
null; | |
} | |
if (arg != null) { | |
args.push(arg); | |
} | |
// Create Build Field | |
var buildField:Field = { | |
name: command.get('command'), //Name of the field | |
doc: documentation, //Haxe Doc comment that appears next to the command | |
access: [APublic], //Access to the field; in this case it's public | |
kind: FFun({ //Type of the field; this is a function field, which means it takes arguments and a return type | |
args: args, | |
ret: (macro:Void) | |
}), | |
pos: Context.currentPos(), | |
//Metatags that we use in Haxe to make code changes in the output | |
meta: [ | |
{ | |
name: ":luaDotMethod", | |
pos: Context.currentPos() | |
} | |
] | |
} | |
//Add the build field to the list of class fields | |
buildFields.push(buildField); | |
} | |
} | |
//Returns all of the fields associated with the class | |
return buildFields; | |
} | |
#end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment