From: Mikko Rasa Date: Fri, 27 Sep 2019 19:24:07 +0000 (+0300) Subject: Refactor signal connection handling in EventDispatcher X-Git-Url: http://git.tdb.fi/?a=commitdiff_plain;h=df6fc46950e15bb30a92368f34dc2005393b0e5b;p=libs%2Fcore.git Refactor signal connection handling in EventDispatcher Connect the signals to functions on the Slot object to make them easier to disconnect. --- diff --git a/source/io/eventdispatcher.cpp b/source/io/eventdispatcher.cpp index cf37c1e..47aafa5 100644 --- a/source/io/eventdispatcher.cpp +++ b/source/io/eventdispatcher.cpp @@ -4,23 +4,19 @@ #include "eventobject.h" #include "poll.h" +using namespace std; + namespace Msp { namespace IO { -EventDispatcher::EventDispatcher() -{ } - -EventDispatcher::~EventDispatcher() -{ } - void EventDispatcher::add(EventObject &obj) { - SlotMap::iterator i = objects.find(&obj); + Slot slot(*this, obj); + set::iterator i = objects.find(slot); if(i==objects.end()) { - i = objects.insert(SlotMap::value_type(&obj, Slot(&obj))).first; - i->second.evch_conn = obj.signal_events_changed.connect(sigc::bind(sigc::mem_fun(this, &EventDispatcher::object_events_changed), &obj)); - i->second.del_conn = obj.signal_deleted.connect(sigc::bind(sigc::mem_fun(this, &EventDispatcher::object_deleted), &obj)); + i = objects.insert(slot).first; + i->connect_signals(); if(obj.get_events()) poller.set_object(obj, obj.get_events()); @@ -29,11 +25,9 @@ void EventDispatcher::add(EventObject &obj) void EventDispatcher::remove(EventObject &obj) { - SlotMap::iterator i = objects.find(&obj); + set::iterator i = objects.find(Slot(*this, obj)); if(i!=objects.end()) { - i->second.evch_conn.disconnect(); - i->second.del_conn.disconnect(); objects.erase(i); poller.set_object(obj, P_NONE); @@ -67,21 +61,33 @@ void EventDispatcher::tick(const Time::Timer &timer) tick(); } -void EventDispatcher::object_events_changed(PollEvent ev, EventObject *obj) +void EventDispatcher::dispatch() { - poller.set_object(*obj, ev); + const Poller::SlotList &result = poller.get_result(); + for(Poller::SlotList::const_iterator i=result.begin(); i!=result.end(); ++i) + i->object->event(i->events); } -void EventDispatcher::object_deleted(EventObject *obj) + +EventDispatcher::Slot::Slot(EventDispatcher &d, EventObject &o): + disp(d), + obj(o) +{ } + +void EventDispatcher::Slot::connect_signals() const { - remove(*obj); + obj.signal_events_changed.connect(sigc::mem_fun(this, &Slot::events_changed)); + obj.signal_deleted.connect(sigc::mem_fun(this, &Slot::deleted)); } -void EventDispatcher::dispatch() +void EventDispatcher::Slot::events_changed(PollEvent ev) const { - const Poller::SlotList &result = poller.get_result(); - for(Poller::SlotList::const_iterator i=result.begin(); i!=result.end(); ++i) - i->object->event(i->events); + disp.poller.set_object(obj, ev); +} + +void EventDispatcher::Slot::deleted() const +{ + disp.remove(obj); } } // namespace IO diff --git a/source/io/eventdispatcher.h b/source/io/eventdispatcher.h index b542d67..f95f477 100644 --- a/source/io/eventdispatcher.h +++ b/source/io/eventdispatcher.h @@ -1,7 +1,7 @@ #ifndef MSP_IO_EVENTDISPATCHER_H_ #define MSP_IO_EVENTDISPATCHER_H_ -#include +#include #include #include #include @@ -14,27 +14,27 @@ namespace IO { Put your I/O objects inside one of these to get signaled when something happens on some of them. */ -class EventDispatcher: public sigc::trackable +class EventDispatcher { private: - struct Slot + struct Slot: public sigc::trackable { - EventObject *obj; - sigc::connection evch_conn; - sigc::connection del_conn; + EventDispatcher &disp; + EventObject &obj; - Slot(EventObject *o): obj(o) { } - }; + Slot(EventDispatcher &, EventObject &); + + void connect_signals() const; + void events_changed(PollEvent) const; + void deleted() const; - typedef std::map SlotMap; + bool operator<(const Slot &o) const { return &obj<&o.obj; } + }; Poller poller; - SlotMap objects; + std::set objects; public: - EventDispatcher(); - ~EventDispatcher(); - void add(EventObject &); void remove(EventObject &); @@ -51,8 +51,6 @@ public: void tick(const Time::Timer &); private: - void object_events_changed(PollEvent, EventObject *); - void object_deleted(EventObject *); void dispatch(); };