如何在Haxe宏函数中声明实例化

马克·克诺尔

我想创建一个为我生成此代码的宏:

if (myEntity.get(Attack) == null) myEntity.add(new Attack());
if (myEntity.get(Confused) == null) myEntity.add(new Confused());
if (myEntity.get(Defend) == null) myEntity.add(new Defend());
if (myEntity.get(Offense) == null) myEntity.add(new Offense());

在代码中,我想这样声明/使用它:

EntityMacroUtils.addComponents(myEntity, Attack, Confused, Defend, Offense);

当前的宏函数如下所示:

macro public static function addComponents(entity:ExprOf<Entity>, components:Array<ExprOf<Class<Component>>>):Expr
{
    var exprs:Array<Expr> = [];
    for (componentClass in components)
    {
        var instance = macro $e { new $componentClass() }; // problem is here
        var expr = macro if ($entity.get($componentClass) == null) $entity.add(instance);
        exprs.push(expr);
    }
    return macro $b{ exprs };
}

此宏函数不正确,我得到了错误:

EntityMacroUtils.hx:17:字符22-43:找不到类型:$ componentClass

问题是我不知道如何定义new $componentClass()我该如何解决?

我也想避免Type.createInstance输出代码中使用。

菲利普

以编程方式生成实例化代码的一种方法是使用“老式”枚举AST建筑(兼容Haxe 3.0.1+):

// new pack.age.TheClass()
return {
    expr:ENew({name:"TheClass", pack:["pack", "age"], params:[]}, []),
    pos:Context.currentPos()
};

可以使用修正来改进语法:

// new pack.age.TheClass()
var typePath = { name:"TheClass", pack:["pack", "age"], params:[] };
return macro new $typePath();

现在,为了方便使用“实例化助手”函数语法,我们需要进行一些扭曲,以从宏函数中接收的表达式中提取类型路径:

// new Foo(), new pack.Bar(), new pack.age.Baz()
instantiate(Foo, pack.Bar, pack.age.Baz);

macro static function instantiate(list:Array<Expr>)
{
    var news = [for (what in list) {
        var tp = makeTypePath(what);
        macro new $tp();
    }];
    return macro $b{news};
}

#if macro
static function makeTypePath(of:Expr, ?path:Array<String>):TypePath 
{
    switch (of.expr)
    {
        case EConst(CIdent(name)):
            if (path != null) {
                path.unshift(name);
                name = path.pop();
            }
            else path = [];
            return { name:name, pack:path, params:[] };

        case EField(e, field):
            if (path == null) path = [field];
            else path.unshift(field);
            return makeTypePath(e, path);

        default:
            throw "nope";
    }
}
#end

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

我应该在声明中还是在构造函数中实例化实例变量?

如何在golang中实例化函数类型?

如何在Go中返回通过多个函数调用的函数调用实例化多个变量?

如何在AndroidX中实例化ViewModel?

如何在Scala中实例化Unit?

如何在Python中向前声明/原型化函数?

类如何在Java中实例化?

如何在PHP中实例化具有参数化构造函数的.NET类?

如何在haxe中以宏模式获取导入列表?

如何在JavaScript中定义实例化函数的行为

如何在angularjs中声明函数

如何创建一个宏,该宏生成在Haxe中按名称动态已知的构造函数数组?

如何在模板化的函数指针声明中读取这么多的星星和括号?

使用Haxe宏实例化带有参数的类

如何在MVC中实例化服务

如何从Typescript中的构造函数动态声明类的实例属性?

如何在系统Verilog中实例化

如何在React中的无状态函数组件中初始化类实例?

如何使用CMake声明类似宏的函数

如何在Laravel中声明ResourceCollection的实例?

如何在带参数的函数中声明

如何在工厂中为延迟实例化指定具体类/如何延迟构造函数调用

如何在Haxe中编写相互递归函数

如何在类函数中声明const

在Haxe中,如何在宏中读取变量名?

每次创建实例时,实例化函数中的私有函数声明都会重新实例化吗?

如何在java中实例化类型

如何在 Inox 中声明抽象函数

如何在 Unity 中实例化对象?