]> git.tdb.fi Git - libs/core.git/blobdiff - source/io/eventdispatcher.cpp
Check that objects still exist when dispatching events to them
[libs/core.git] / source / io / eventdispatcher.cpp
index 06a594f76d397165789940184f7c1a8d0ab65771..49b28ac78bf436997f74d2d8fecb740aebf47fb5 100644 (file)
@@ -1,35 +1,33 @@
-#include <msp/time/units.h>
+#include <msp/time/utils.h>
 #include "base.h"
 #include "eventdispatcher.h"
+#include "eventobject.h"
 #include "poll.h"
 
+using namespace std;
+
 namespace Msp {
 namespace IO {
 
-EventDispatcher::EventDispatcher()
-{ }
-
-void EventDispatcher::add(Base &obj)
+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());
        }
 }
 
-void EventDispatcher::remove(Base &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);
@@ -54,21 +52,43 @@ void EventDispatcher::tick(const Time::TimeDelta &dt)
                dispatch();
 }
 
-void EventDispatcher::object_events_changed(PollEvent ev, Base *obj)
+void EventDispatcher::tick(const Time::Timer &timer)
 {
-       poller.set_object(*obj, ev);
+       const Time::TimeStamp &timeout = timer.get_next_timeout();
+       if(timeout)
+               tick(timeout-Time::now());
+       else
+               tick();
 }
 
-void EventDispatcher::object_deleted(Base *obj)
+void EventDispatcher::dispatch()
 {
-       remove(*obj);
+       const vector<Poller::PolledObject> &result = poller.get_result();
+       for(vector<Poller::PolledObject>::const_iterator i=result.begin(); i!=result.end(); ++i)
+               if(objects.count(Slot(*this, *i->object)))
+                       i->object->event(i->events);
 }
 
-void EventDispatcher::dispatch()
+
+EventDispatcher::Slot::Slot(EventDispatcher &d, EventObject &o):
+       disp(d),
+       obj(o)
+{ }
+
+void EventDispatcher::Slot::connect_signals() const
+{
+       obj.signal_events_changed.connect(sigc::mem_fun(this, &Slot::events_changed));
+       obj.signal_deleted.connect(sigc::mem_fun(this, &Slot::deleted));
+}
+
+void EventDispatcher::Slot::events_changed(PollEvent ev) const
+{
+       disp.poller.set_object(obj, ev);
+}
+
+void EventDispatcher::Slot::deleted() const
 {
-       const Poller::SlotSeq &result = poller.get_result();
-       for(Poller::SlotSeq::const_iterator i=result.begin(); i!=result.end(); ++i)
-               i->object->event(i->events);
+       disp.remove(obj);
 }
 
 } // namespace IO