C++模拟QT信号槽
- 测试代码
//创建信号
Events<bool> event1{};
//注册信号槽,使用Lambda
event1 += [](bool flag) {MyLog << "slot1:" << flag; return true; };
//信号发送
event1(false);
MyLog << "--------------------------------------------------------";
//创建信号2
auto event2 = MakeEvents<bool>();
//注册信号槽,使用函数指针
event2->RegisterLastObserver(Slot2);
//信号发送
event2->Emit(true);
MyLog << "--------------------------------------------------------";
//连接信号
event1.AddLastPipeLine(event2);
//信号发送
event1.Emit(false);
MyLog << "--------------------------------------------------------";
- 测试结果
- 代码实现
template<typename ...Args>
class Events :
protected NoCopiable
{
using EventsWeakPtr = std::weak_ptr<Events>;
using EventsSharedPtr = std::shared_ptr<Events>;
public:
//true 事件放行
using stl_func_type = std::function <bool(Args...)>;
template<typename Fn>
void operator+=(Fn &&func)
{
observers_.push_back(std::forward<Fn>(func));
}
template<typename Fn>
void operator-=(Fn &&func)
{
observers_.push_front(std::forward<Fn>(func));
}
template<typename Fn>
void RegisterLastObserver(Fn &&func)
{
operator +=(std::forward<Fn>(func));
}
template<typename Fn>
void RegisterFirstObserver(Fn &&func)
{
operator -=(std::forward<Fn>(func));
}
void AddLastPipeLine(EventsWeakPtr e_other)
{
observers_.push_back([e_other](Args&&...args)
{
if (auto sp = e_other.lock()) {
return (*sp)(std::forward<Args>(args)...);
} else {
return true;
}
});
}
void AddFirstPipeLine(EventsWeakPtr e_other)
{
observers_.push_front([e_other](Args&&...args)
{
if (auto sp = e_other.lock()) {
return (*sp)(std::forward<Args>(args)...);
} else {
return true;
}
});
}
void operator+=(EventsWeakPtr e_other) { AddLastPipeLine(e_other); }
void operator-=(EventsWeakPtr e_other) { AddFirstPipeLine(e_other); }
void operator+=(EventsSharedPtr e_other) { AddLastPipeLine(e_other); }
void operator-=(EventsSharedPtr e_other) { AddFirstPipeLine(e_other); }
template<typename..._Args>
bool operator()(_Args&&...args)
{
return Emit(std::forward<Args>(args)...);
}
template<typename..._Args>
bool Emit(_Args&&...args)
{
return std::find_if(observers_.begin(), observers_.end(), [&](stl_func_type const&fn) {
return !fn(std::forward<Args>(args)...);
}) == observers_.end();
}
private:
std::list<stl_func_type> observers_;
};
template<typename ...Args>
using EventsPtr = std::shared_ptr<Events<Args...>>;
template<typename ...Args>
inline decltype(auto) MakeEvents()
{
return std::make_shared<Events<Args...>>();
}
更多内容详见 helper/event_observer.h