信号与槽是QT的一个概念,原版C++里并没有
先声明一些类
Receiver负责接收信号,Emitter2则是负责发送
class Receiver : public ntl::Reflectible
{
public:
void received(int num)
{
std::cout << "received:" << num << std::endl;
}
};
class Emitter2 : public ntl::Signalable
{
public:
Emitter2()
{
m_signals.insert(
ntl::Signalable::SignalMap::value_type(
"signal",
ntl::Signal(1)));
}
public:
void emit_signal()
{
emit("signal", 123);
}
};
接着连接信号
说明一下信号的名称、接收对象与方法
emitter2.connect("signal", "receiver", &receiver, &Receiver::received);
最后发送信号
emitter2.emit_signal();
没错的话应该输出以下字符
received:123
说明Receiver成功接收到了Emitter2发出的信号
此物需要借助上篇文章的力量
并位于github之中,尔等可观赏其细节
Slot需要与对象绑定
用void*说明对象的位置
NonStaticMethod如其名,是一个用于调用的非静态方法
/// @brief 槽
class NTL_ALIGN Slot : public BasicObject
{
public:
using SelfType = Slot;
using ParentType = BasicObject;
protected:
/// @brief 槽的对象
void *m_object = nullptr;
/// @brief 方法
NonStaticMethod m_method;
public:
Slot() = default;
explicit Slot(void *object, const NonStaticMethod &method);
explicit Slot(const SelfType &from) = default;
~Slot() = default;
public:
SelfType &operator=(const SelfType &from) = default;
public:
void *get_object() const;
const NonStaticMethod &get_method() const;
public:
template <typename... ArgsType>
void received(ArgsType &&...args) const;
};
Signal可以连接多个Slot,并允许删改
/// @brief 信号
class NTL_ALIGN Signal : public BasicObject
{
public:
using SelfType = Signal;
using ParentType = BasicObject;
/// @brief 槽容器
using SlotContainer = std::map<String, Slot>;
protected:
/// @brief 槽
SlotContainer m_slots;
/// @brief 参数总数
SizeT m_args_count = 0;
public:
Signal() = default;
explicit Signal(SizeT args_count);
explicit Signal(const SelfType &from) = default;
~Signal() = default;
public:
SelfType &operator=(const SelfType &from) = default;
public:
const SlotContainer &get_slots() const;
SizeT get_args_count() const;
bool has_slot(const String &name) const;
public:
template <typename MethodType>
void connect(const String &name, void *object, MethodType method);
void connect(const String &name, const Slot &slot);
void disconnect(const String &name);
template <typename... ArgsType>
void emit(ArgsType &&...args) const;
};
Signalable是一个可以发送/接收信号的对象,继承自Reflectible
/// @brief 可发送/接收信号的对象
class NTL_ALIGN Signalable : public Reflectible
{
public:
using SelfType = Signalable;
using ParentType = Reflectible;
/// @brief 信号列表
using SignalMap = std::map<String, Signal>;
protected:
/// @brief 信号列表
SignalMap m_signals;
public:
Signalable() = default;
explicit Signalable(const SelfType &from) = default;
~Signalable() = default;
public:
SelfType &operator=(const SelfType &from) = default;
public:
const SignalMap &get_signals() const;
bool has_signal(const String &signal) const;
public:
template <typename MethodType>
void connect(const String &signal, const String &name, void *object, MethodType method);
void connect(const String &signal, const String &name, const Slot &slot);
void disconnect(const String &signal, const String &name);
template <typename... ArgsType>
void emit(const String &signal, ArgsType &&...args) const;
public:
static OutOfRangeException unable_to_find_signal(const String &signal, const String &where);
};