用户类中的多签名信号管理

时间:2011-12-09 15:29:44

标签: c++ boost-signals

我对Qt非常熟悉,我知道我们不能有类似的synthax,因为我们这里没有MOC部分。但是,我正在尝试进行信号创建管理,以便在我的课程中简化信号声明及其连接。

这是我现在正在做的事情


    class Foo
    {
       public:
          void connectMove(boost::signal<void(int)>::slot_type slot)
          void connectRotate(boost::signal<void(double)>::slot_type slot)

       private:
          boost::signal<void(int)> m_signalMove;
          boost::signal<void(double)> m_signalRotate;
    };

这基本上是我想做的事(大写=缺少部分)



    class SignalManager 
    {
       public:
          typedef boost::unrodered_map<std::string, GENERIC_SIGNAL *> MapSignal;
       public:
          template <typename Sig>
          bool connect(const std::string& strSignalName, boost::signal<Sig>::slot_type slot)
          {
             // simplyfied... :
             (*m_mapSignal.find(strSignalName))->connect(slot);
          }

          template <typename Sig>
          bool disconnect(const std::string& strSignalName, boost::signal<Sig>::slot_type slot)
          {
             // simplyfied... :
             (*m_mapSignal.find(strSignalName))->disconnect(slot);
          }

       protected:
          bool call(const std::string& strSignalName, SIGNAL_ARGS)
          {
             (*m_mapSignal.find(strSignalName))(SIGNAL_ARGS);
          }

          template <typename Sig>
          void delareSignal(const std::string& strSignalName)
          {
             m_mapSignals.insert(MapSignal::value_type(strSignalName, new boost::signal<Sig>()));
          }

          void destroySignal(const std::string& strSignalName)
          {
             // simplyfied... :
             auto it = m_mapSignal.find(strSignalName);
             delete *it;
             m_mapSignal.erase(it);
          }

       private:
          MapSignal m_mapSignals;
    };

    class Foo : public SignalManager
    {
       public:
          Foo(void)
          {
             this->declareSignal<void(int)>("Move");
             this->declareSignal<void(double)>("Rotate");
          }
    };


    class Other : public boost::signals::trackable
    {
       public:
          Other(Foo *p)
          {
             p->connect("Move", &Other::onMove);
             p->connect("Rotate", &Other::onRotate);
          }

          void onMove(int i)
          {
             /* ... */
          }

          void onRotate(double d)
          {
             /* ... */
          }
    };


我想我可以使用boost :: functions_traits&lt;&gt;来解决“SIGNAL_ARGS”部分,但我不知道如何绕过抽象信号类型。

1 /我想要的甚至可能吗?

2 /这是一个好方法吗? (我知道由于unordered_map.find我会有一些开销,特别是当我使用this-&gt; call(“signalname”,...)时,我认为它不应该太重要)

3 /如果这不可能或不是一个好方法,你还有其他建议吗?

1 个答案:

答案 0 :(得分:1)

我通过打包boost::signals并拥有boost::shared_ptr<IWrapperSignal>而不是GENERIC_SIGNAL解决了我的问题。

参数probnlem也使用boost::function_traits<T>::arg_type来解决。

我不知道它是否是最好的方法,但它工作正常,用户在继承此类的类中声明信号更为简单{ {1}}。