samedi 29 août 2015

Moving std::function with member function

I've written a super simple event system using std::function.

It amounts to

std::vector<Delegate<Args ...>*> _delegates;

Where Delegate is a typedef of std::function

template <typename ... Args>
using Delegate = std::function<void(Args ...)>;

With the event's operator(), operator+=, and operator-= overloaded.

operator() calls all of the listening functions.
operator+= adds a listener.
operator-= removes a listener.

Hooking them up looks like this...

Foo::Foo(Bar& bar)
{
    m_bar_ptr = &bar;

    using namespace std::placeholders;

    event_receiver =
    Delegate<const Bar&, const SomeBarData>
    (std::bind(&Foo::OnEventReceived, this, _1, _2));
    bar.BarEvent += event_receiver;
}

Everything works as intended, but when I move the owner of a Delegate I end up having to unhook and duplicate the code for the initial hook up (as expected).

It looks like this...

Foo& Foo::operator=(Foo&& other)
{
    m_bar_ptr = other.m_bar_ptr;
    other.m_bar_ptr = nullptr;

    m_bar_ptr->BarEvent -= other.event_receiver;

    using namespace std::place_holders;

    event_receiver =
    Delegate<const Bar&, const SomeBarData>
    (std::bind(&Foo::OnEventReceived, this, _1, _2));
    bar.BarEvent += event_receiver;
}

Aside from having to keep a handle to Bar, which is acceptable, this is a lot of code to re-target the Delegate...and leaves a lot of room for error.

I like the simplicity of these events (though I am open to suggestions), but what I'm really looking for is a way to keep this event system and simplify moves.

Any suggestions?

Thanks

Aucun commentaire:

Enregistrer un commentaire