信号 - 槽系统:定义信号(需要魔法宏)

时间:2015-09-25 19:53:58

标签: c++ qt macros

我需要有Qt信号/插槽系统的信号/插槽模拟(没有增强)。问题是如果我想调用信号槽,我需要生成一些代码。看看这个例子:

struct Test
{
    void on_mouse_click_event(int x, int y) // #1
    {
        using Function = void (Test::*)(int x, int y); // #2
        auto event_id_receivers_pair = event_id_to_receivers_.find(typeid(Function).hash_code());
        if(event_id_receivers_pair != event_id_to_receivers_.end())
        {
            FunctionArgs<Function> args(x, y); // #3
            for(auto& p_receiver : event_id_receivers_pair->second)
                p_receiver->call(&args);
        }
        on_mouse_click(x, y);
    }

    virtual void on_mouse_click(int x, int y)
    {
        std::cout << "On click: " << x << ", " << y
            << " - " << this << "\n";
    }

    std::unordered_map<
        std::size_t/*Function (event) ID*/,
        std::vector<std::unique_ptr<ICallee>>/*Array of receivers*/>
        event_id_to_receivers_;
 };

struct Foo
{
    void test_click(int x, int y)
    {
        std::cout << "On test click: " << x << ", " << y
            << " - " << this << "\n";
    }
};

template<typename Sender, typename Receiver, typename Signal, typename Slot>
void connect(Sender* sender, Signal signal,
    Receiver* receiver, Slot slot)
{
    auto callee = create_callee<Receiver, Slot>(receiver, slot);
    sender->event_id_to_receivers_[
        typeid(Signal).hash_code()].
            push_back(std::move(callee));
}

int main()
{
    Test test;
    Foo foo;
    Foo foo1;

    connect(&test, &Test::on_mouse_click_event,
        &foo, &Foo::test_click);

    connect(&test, &Test::on_mouse_click_event,
        &foo1, &Foo::test_click);

    test.on_mouse_click_event(10, 20);
}

班级Test有一个事件on_mouse_click()。在main中,我有2个与此事件的连接,最后一行是事件的发射。结果,我想看到这样的事情:

On click: 10, 20 - 009CFC63
On click: 10, 20 - 009CFC57
On test click: 10, 20 - 009CFC6C

问题:有没有办法让我有一些宏来编写这样的代码:

class Test
{
    SIGNAL(on_mouse_click)(int x, int y);
};

我需要:

  1. 指向成员函数的指针类型:void (Test::*)(int x, int y); // #2
  2. 传递它们的函数参数的名称:args(x, y); // #3
  3. 这可能吗?有没有解决方法?

    由于

0 个答案:

没有答案