C++17 通用信号-槽
·
槽类型 (int signal_type,void* sender,void* user_data)
参数1 信号 ID 用来区分信号
参数2 sender 表示信号发送者/如果你在 A类调用信号,sender传入 A的指针 this
参数3 user_data 代表用户数据 (可以是类指针 或者结构体指针,异步信号注意参数的作用域,最好使用智能指针)
#pragma once
#include <functional>
#include <memory>
#include <mutex>
#include <vector>
#include <unordered_map>
enum class SignalType {
E_SIGNAL_DEFAULT = 0,
E_SIGNAL_SYSTEM_OUT,
E_SIGNAL_SHOW_MESSAGE,
E_SIGNAL_SYS_OUT_CLEARN,
};
class BaseSignal {
public:
std::error_code connect(int signal_id, const std::function<void(int, void*, void*)>& slot) {
auto* ctx = context();
std::lock_guard<std::mutex> lg(ctx->m_);
ctx->slots_[signal_id].push_back(slot);
return {};
}
template <typename T>
std::error_code connect(int signal_id, T* obj, void (T::*mf)(int, void*, void*)){
return connect(signal_id, [obj, mf](int id, void* sender, void* data) {
(obj->*mf)(id, sender, data);
});
}
int sync(int signal_id, void* sender, void* user_data) const {
return context()->fire_impl(signal_id, sender, user_data, false);
}
void async(int signal_id, void* sender, void* user_data) const {
auto* ctx = context();
std::thread([ctx, signal_id, sender, user_data] {
ctx->fire_impl(signal_id, sender, user_data, true);
}).detach();
}
struct Context {
using Slot = std::function<void(int, void*, void*)>;
mutable std::mutex m_;
std::unordered_map<int, std::vector<Slot>> slots_; // 按信号 ID 分组管理
int fire_impl(int signal_id, void* sender, void* user_data, bool async) {
int ec = 0;
std::vector<Slot> local;
{
std::lock_guard<std::mutex> lg(m_);
auto it = slots_.find(signal_id);
if (it != slots_.end()) {
local = it->second;
}
}
for (const auto& f : local) {
try {
f(signal_id, sender, user_data);
} catch (...) {
if (!async) return -1;
}
}
return ec;
}
};
static Context* context() {
static Context inst;
return &inst;
}
};
struct Widget {
void print(int x, const std::string& s) {
std::cout << "Widget: " << x << " " << s <<" "<< __func__ <<" thread: "<<std::this_thread::get_id() << std::endl;
}
void print1(int a,int b, int c) {
int d = a+b+c;
std::cout << "c: " << d <<" "<< __func__ <<" thread: "<<std::this_thread::get_id() << std::endl;
}
void test_slot(int id, void* sender, void* data){
std::cout<<"Test::test_slot"<<std::endl;
}
};
int main(){
std::cout << __func__<<" " <<std::this_thread::get_id() << std::endl;
Widget w;
BaseSignal sig;
//连接信号槽
sig.connect(1,&w,&Widget::test_slot);
//发送信号槽
sig.sync(1, nullptr, nullptr);
return 0;
}
更多推荐

所有评论(0)