0

ロックマンのゲームについては、また私です。オブジェクトをデータ駆動できるように、コンポーネントシステムに切り替えました。うまくいきますが、問題が発生しました。

私のオブジェクトには、入力ファイルで指定された状態があります。これらの状態には、他の状態に移行するためのトリガーがあります。状態変化の条件も入力ファイルにあり、ラムダ式に解析されます。次に、オブジェクトをディープコピーする必要があります。また、元のメンバーではなく、コピーのメンバーを参照するラムダが必要です。オリジナルはプログラムのロード時にファイルからロードされますが、その後いつでもコピーできます(発射物が発射されたと考えてください)。

大幅に簡略化されたコードを次に示します。

class StateComponent
{
    // when the whole entity is cloned, it will get a clone of
    // DependentComponent as well as a clone of this StateComponent.
    private OtherComponent DependentComponent;

    // there is a function to register dependencies. The entity that owns
    // me also owns DependentComponent, and registered it with me.

    public StateComponent Clone()
    {
        // what should I do here to make the lambda deep copied?
    }

    public void LoadFromXml(XElement node)
    {
        State state = new State();
        LambdaExpression lambda = DynamicExpression.ParseLambda(from xml stuff)
        Delegate condition = lambda.Compile();
        Action effect = LoadTriggerEffect();
        state.AddTrigger(condition, effect);

        // add state to my list of states
    }

    private Action LoadTriggerEffect()
    {
        Action action = new Action(() => { });
        if ( some stuff from the input file )
            action += () => { DependentComponent.Foo(); DependentComponent.Bar = 5; }

        return action;
    }
}

それだけではありません。トリガーによって実際に状態が変化し、新しい状態のイニシャライザーがそのアクションを呼び出しますが、ここでは簡略化しました。

したがって、問題は、このコンポーネントをディープコピーするとき、またはとにかくしようとすると、ラムダが元のコンポーネントではなく、コピーのDependentComponentのインスタンスを参照するようにする方法がわからないことです。エンティティのディープコピーが新しいDependentComponentを取得していることをすでに確認しましたが、ラムダは元のコンポーネントを参照しているだけです。デリゲートは、作成されると基本的に特定のインスタンスにロックされますか?新しいものを作成する必要がありますか?ファイルからエンティティ全体を再度ロードする必要はありません。

4

2 に答える 2

0

ラムダの引数にしてみませんか?

Action<OtherComponent> action = new Action<OtherComponent>((null) => { });
if ( some stuff from the input file )
    action += x => { x.Foo(); x.Bar = 5; }

1つ以上の依存コンポーネントが必要な場合は、thisポインターを渡すこともできます。異なるクラスのオブジェクト間でラムダを交換する場合は、インターフェイスを使用してください...

于 2010-01-07T20:49:37.793 に答える
0

式ツリーは不変であるため、オブジェクト参照が含まれている場合は、元のオブジェクトになります。それを深くコピーするには、代わりのある種の訪問者が必要です。どこかに似たようなコードがありますが、大変な作業です。もちろん、オブジェクト固有の参照が含まれていない場合は、「そのまま」安全に使用できます。

LambdaExpression lambdaあなたがフィールドを意味すると仮定します。私はあなたがそれをどのように解析しているのかよく知らないので、それがどれほど簡単かについてコメントすることはできませんが、ここでの一般的なオプションはラムダをパラメーター化することです。ターゲットオブジェクトを引数として渡すと、実行時に複数の異なるオブジェクトでラムダを再利用できます(適切なタイプである限り)。

于 2010-01-07T20:50:41.737 に答える