c++ - 场景图更新回调设计

标签 c++ oop design-patterns callback openscenegraph

所以我使用 Open Scene graph 来创建一个应用程序,并且我有一个从 OSG 的回调类扩展而来的回调类。它只是在场景图节点的更新事件遍历中调用每一帧的回调。

我需要不同的回调类来对它们所连接的节点执行不同的操作。所以我有一个基础回调类,我称之为 Controller 基础:

class ControllerBase : public osg::NodeCallback
{
public:
    ControllerBase();
private:
    // operator is overridden here from NodeCallback and is called each frame.
    virtual void operator()(osg::Node * n, osg::NodeVisitor * nv);
}

operator() 给我回调也附加的节点和节点访问者。现在取决于节点,它可能是不同的类,例如转换或开关。

所以我需要进行动态转换,但对于节点可能的每种可能类型。所以:

class ControllerBase : public osg::NodeCallback
{
public:
    ControllerBase();
private:
    virtual void operator()(osg::Node * n, osg::NodeVisitor * nv)
    {
      Type1 * t1 = dynamic_cast<Type1*>(node);
      Type2 * t2 = dynamic_cast<Type1*>(node);
      Type3 * t3 = dynamic_cast<Type1*>(node);

    }
}

然后通过一个虚拟方法将它们发送出去,由我将附加到节点的特定 Controller 类继承。

class ControllerBase : public osg::NodeCallback
{
public:
    ControllerBase();
protected:

private:

    virtual void On_Frame(Type1*, osg::NodeVisitor) = 0;
    virtual void On_Frame(Type2*, osg::NodeVisitor) = 0;
    virtual void On_Frame(Type3*, osg::NodeVisitor) = 0;

    virtual void operator()(osg::Node * n, osg::NodeVisitor * nv)
    {
      Type1 * t1 = dynamic_cast<Type1*>(node);
      Type2 * t2 = dynamic_cast<Type1*>(node);
      Type3 * t3 = dynamic_cast<Type1*>(node);

      if(t1)
        On_Frame(t1, nv);
      if(t2)
        On_Frame(t2, nv);
      if(t3)
        On_Frame(t3, nv);

    }
}

class Type1_Controller
{
    public:
        Type1_Controler();
    private:
        virtual void On_Frame(Type1 * type, osg::NodeVisitor *nv) override
        {
            // Do type 1 related stuff here. 
        }
        virtual void On_Frame(Type2 * type, osg::NodeVisitor *nv) override
        {
            // Leave empty, not needed. 
        }

        virtual void On_Frame(Type3 * type, osg::NodeVisitor *nv) override
        {
            // Leave empty, not needed. 
        }
}

所以现在对于我拥有的每种类型的 Controller ,我都必须实现剩余的空方法。这感觉像是糟糕的设计,但我想不出如何编写更好的实现。也许 3 种类型并没有那么糟糕,但随着我的进行,我可能会添加更多。我考虑过使用模板类,但如果我没记错的话,我不能在模板类中使用虚方法。我可以只使用具有空实现的非纯虚拟方法,我想这可以在选择时被覆盖。什么是好的方法或建议?

最佳答案

osg::NodeVisitor 或多或少是访问者设计模式的教科书式实现。 (有关原始“四人帮”或 GoF 书籍的更多信息,请参见 http://en.wikipedia.org/wiki/Design_Patterns)。

您可以在您的 t1 节点类中覆盖 accept(NodeVisitor) 以尝试转换为您的 t1 访问者类型,例如:

 Type1_Visitor* vis = dynamic_cast<NodeVisitor> nv;
 if(vis)
    vis->Type1Apply(*this);
 else
    nv->apply(*this);

当然,还有更多内容,但这是 GoF 书中阐述的双重调度的一般思想。

关于c++ - 场景图更新回调设计,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27837228/

相关文章:

oop - 面向对象设计问题

javascript - 为什么我必须在 OOP Javascript 中使用 constructor.prototype?

c++ - move_iterator 对于返回纯右值的迭代器被破坏并返回悬空引用

C++ - 如何将元素从 std::priority_queue 复制到 std::vector

c++ - MS Visual C++ 通过单击按钮启动功能而不阻塞对话框

oop - 大型嵌套 switch 语句的设计模式

java - 我们可以在 pojo 中放置两个 setter 吗?

c# - 工厂模式的首选实现方式?

c# - SignalR for .net 和观察者模式

c++ - 我的 C++ 合并排序程序有什么问题?