槽类型 (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;
}

更多推荐