550043f4cffdd99f47144a0af5a7e32686cabad1
[libs/core.git] / source / io / eventdispatcher.cpp
1 #include <msp/time/utils.h>
2 #include "base.h"
3 #include "eventdispatcher.h"
4 #include "eventobject.h"
5 #include "poll.h"
6
7 using namespace std;
8
9 namespace Msp {
10 namespace IO {
11
12 void EventDispatcher::add(EventObject &obj)
13 {
14         Slot slot(*this, obj);
15         set<Slot>::iterator i = objects.find(slot);
16         if(i==objects.end())
17         {
18                 i = objects.insert(slot).first;
19                 i->connect_signals();
20
21                 if(obj.get_events())
22                         poller.set_object(obj, obj.get_events());
23         }
24 }
25
26 void EventDispatcher::remove(EventObject &obj)
27 {
28         set<Slot>::iterator i = objects.find(Slot(*this, obj));
29         if(i!=objects.end())
30         {
31                 objects.erase(i);
32
33                 poller.set_object(obj, P_NONE);
34         }
35 }
36
37 void EventDispatcher::tick()
38 {
39         if(objects.empty())
40                 return;
41
42         if(poller.poll()>0)
43                 dispatch();
44 }
45
46 void EventDispatcher::tick(const Time::TimeDelta &dt)
47 {
48         if(objects.empty())
49                 return;
50
51         if(poller.poll(dt)>0)
52                 dispatch();
53 }
54
55 void EventDispatcher::tick(const Time::Timer &timer)
56 {
57         const Time::TimeStamp &timeout = timer.get_next_timeout();
58         if(timeout)
59                 tick(timeout-Time::now());
60         else
61                 tick();
62 }
63
64 void EventDispatcher::dispatch()
65 {
66         const vector<Poller::Slot> &result = poller.get_result();
67         for(vector<Poller::Slot>::const_iterator i=result.begin(); i!=result.end(); ++i)
68                 i->object->event(i->events);
69 }
70
71
72 EventDispatcher::Slot::Slot(EventDispatcher &d, EventObject &o):
73         disp(d),
74         obj(o)
75 { }
76
77 void EventDispatcher::Slot::connect_signals() const
78 {
79         obj.signal_events_changed.connect(sigc::mem_fun(this, &Slot::events_changed));
80         obj.signal_deleted.connect(sigc::mem_fun(this, &Slot::deleted));
81 }
82
83 void EventDispatcher::Slot::events_changed(PollEvent ev) const
84 {
85         disp.poller.set_object(obj, ev);
86 }
87
88 void EventDispatcher::Slot::deleted() const
89 {
90         disp.remove(obj);
91 }
92
93 } // namespace IO
94 } // namespace Msp