[OK]を、ここではhaXeのに非常に単純なwith() {...}
エミュレーションを実装するためのコードは次のとおりです。
//simple.hx
class Simple
{
@:macro public static function with(subject:Expr, block:Expr)
{
return with_impl(subject, block);
}
#if macro
static function with_impl(subject:Expr, block:Expr)
{
function mk(e, pos) return { expr:e, pos:pos };
//this is the main function here. It's going to find a variable the expression so it uses our subject
function changeIdent(identExpr:Expr, changeExpr)
{
return switch(identExpr.expr)
{
case EConst(c):
switch(c)
{
case CIdent(s):
mk(EField(changeExpr, s), identExpr.pos);
default:
identExpr;
}
case EField(e, f):
mk(EField(changeIdent(e, changeExpr), f), identExpr.pos);
case EType(e, f):
mk(EType(changeIdent(e, changeExpr), f), identExpr.pos);
default: //fallba
identExpr;
}
}
return switch(block.expr)
{
case EBlock(exprs):
var newblock = [];
for (statement in exprs)
{
switch(statement.expr)
{
case ECall(e, params):
newblock.push(mk(ECall(changeIdent(e, subject), params), statement.pos));
default:
newblock.push(statement);
}
}
mk(EBlock(newblock), block.pos);
case EDisplay(e, iscall):
mk(EDisplay(with_impl(subject, e), iscall), block.pos);
default:
changeIdent(block, subject);
}
}
#end
}
あなたはこのようにそれを使用します。
//Main.hx
class Main
{
static function main()
{
Simple.with (Lib.current.graphics,
{
beginFill(0xC0FFEE, 1);
drawRect(-10, -10, 20, 20);
endFill();
});
}
}
代わりの範囲を変更する、それがされます呼び出し式を探し、すべての式に含める関数(サブジェクト)の最初の引数を追加するだけです。上のコードは次のコードと同等です:
{
Lib.current.graphics.beginFill(0xC0FFEE, 1);
Lib.current.graphics.drawRect(-10, -10, 20, 20);
Lib.current.graphics.endFill();
}
マクロはとても楽しいです!
このスニペットの要点はここにあります:https://gist.github.com/1057674 – Waneck
ねえ、ありがとう!これは本当によく見えます。私はHaXeでもこれを利用できるようにしたいと思う人がいると確信しています。今日は後で試してみると、マクロを理解しようとする必要があります。 – user479887
私が正しく理解している場合、 "使用する"例の問題は、HaXeの内部クラスが存在しないため、各クラスのSpriteの別々のインスタンス内で使用されなければならないということでした。このメソッドでは、元の質問(細心の注意)にその詳細を指定したとは思えませんが、複数のクラスで1つのGraphicsインスタンスを使用することができます。 – user479887