用户类中的多重签名信号管理
我对 Qt 非常熟悉,并且我知道我们不能有类似的合成,因为我们这里没有 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<> 解决“SIGNAL_ARGS”部分,但我不知道如何绕过抽象信号类型。
1/ 我想要的东西可能实现吗?
2/这是一个好方法吗? (我知道由于 unordered_map.find,我会产生一些开销,特别是当我使用 this->call("signalname", ...) 时,但我认为它不应该太重要)
3/如果这是不可能或不是一个好方法,您还有其他建议吗?
I'm very familiar with Qt and I know that we cannot have a similar synthax because we don't have the MOC part here. However I'm trying to have a signal creation management to simplify the declaration of a signal and the connection to it, inside my classes.
this is schematicly what I'm doing now
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;
};
and this is basicaly what I would like to do (UPPERCASE = missing part)
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)
{
/* ... */
}
};
I think I could resolve the "SIGNAL_ARGS" part with boost::functions_traits<>, but i don't know how to go around the abstract signal type.
1/ Is what I want even possible ?
2/ Is this a good approach ? (I know I will have some overhead due to the unordered_map.find, esspecily when I use this->call("signalname", ...), but I think it shouldn't be too significant)
3/ If this is not possible or not a good approach, do you have any other suggestions ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我通过包装
boost::signals
并使用boost::shared_ptr
而不是我的GENERIC_SIGNAL
解决了我的问题。参数问题也使用
boost::function_traits::arg_type
得到解决。我不知道这是否是最好的方法,但它工作得很好,而且用户在继承此
SignalManager
的类中声明信号更加简单。I resolved my problem by wrapping
boost::signals
and having aboost::shared_ptr<IWrapperSignal>
instead of myGENERIC_SIGNAL
.The arguments probnlem was also resolved using
boost::function_traits<T>::arg_type
.I don't know if it's the best way to do that, but it's working fine, and it is more simple for the user to declare signals in the classes that inherit this
SignalManager
.