Refactor signal connection handling in EventDispatcher
authorMikko Rasa <tdb@tdb.fi>
Fri, 27 Sep 2019 19:24:07 +0000 (22:24 +0300)
committerMikko Rasa <tdb@tdb.fi>
Fri, 27 Sep 2019 19:39:13 +0000 (22:39 +0300)
Connect the signals to functions on the Slot object to make them easier
to disconnect.

source/io/eventdispatcher.cpp
source/io/eventdispatcher.h

index cf37c1e7e1fbd81155608895bd14ebe9bd882e10..47aafa52818eacf85fbd815c17db31697314255a 100644 (file)
@@ -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<Slot>::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<Slot>::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
index b542d67e74d3fa896811b4a04263e9554e4f8902..f95f477daac5199df5995698a217baa64e6e3f99 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef MSP_IO_EVENTDISPATCHER_H_
 #define MSP_IO_EVENTDISPATCHER_H_
 
-#include <sigc++/connection.h>
+#include <set>
 #include <sigc++/trackable.h>
 #include <msp/time/timedelta.h>
 #include <msp/time/timer.h>
@@ -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<EventObject *, Slot> SlotMap;
+               bool operator<(const Slot &o) const { return &obj<&o.obj; }
+       };
 
        Poller poller;
-       SlotMap objects;
+       std::set<Slot> 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();
 };