0

又是我,关于我的《洛克人》游戏。我切换到组件系统,以便对象可以由数据驱动。一切正常,但我遇到了问题。

我的对象有状态,用输入文件指定。这些状态具有将它们转换到其他状态的触发器。状态更改的条件也在输入文件中,并被解析为 lambda 表达式。现在我需要深度复制我的对象,并且我需要 lambdas 来引用副本的成员,而不是原始的成员。程序加载时会从文件中加载原件,但之后可以随时复制(想想发射的弹丸)。

这是一段大大简化的代码:

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;
    }
}

不仅如此,触发器实际上会导致状态更改,然后新状态的初始化程序调用该 Action,但我在这里对其进行了简化。

所以问题是当我深拷贝这个组件时,或者无论如何尝试,我不知道如何让 lambdas 引用副本的 DependentComponent 实例,而不是原始的实例。我已经确保实体的深层副本正在获得一个新的 DependentComponent,但 lambda 只是引用原始组件。委托一旦创建就基本上锁定到特定实例吗?我必须创建一个新的吗?我不想再次从文件中加载整个实体。

4

2 回答 2

0

为什么不把它作为 lambda 的参数呢?

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

如果您需要的不仅仅是一个依赖组件,您还可以传递 this 指针,如果您想在不同类的对象之间交换 lambda,请使用接口...

于 2010-01-07T20:49:37.793 回答
0

表达式树是不可变的,因此如果其中包含对象引用,它们将指向原始对象。要对其进行深度复制,您需要某种具有替代功能的访问者;我在某处有一些类似的代码,但工作量很大。当然,如果它没有特定于对象的引用,您可以非常安全地“按原样”使用它。

假设你的意思是LambdaExpression lambda领域;我不熟悉你是如何解析它的,所以我无法评论它是多么容易,但这里的一个常见选项是参数化 lambda;将目标对象作为参数传入,您可以在运行时将 lambda 与多个不同的对象重用(只要它们属于适当的类型)。

于 2010-01-07T20:50:41.737 回答