]> git.llucax.com Git - software/libev.git/blob - ev++.h
*** empty log message ***
[software/libev.git] / ev++.h
1 #ifndef EVPP_H__
2 #define EVPP_H__
3
4 #include "ev.h"
5
6 namespace ev {
7
8   template<class ev_watcher, class watcher>
9   struct base : ev_watcher
10   {
11     #if EV_MULTIPLICITY
12       EV_P;
13
14       void set (EV_P)
15       {
16         this->EV_A = EV_A;
17       }
18     #endif
19
20     base ()
21     {
22       ev_init (this, 0);
23     }
24
25     void set_ (void *data, void (*cb)(EV_P_ ev_watcher *w, int revents))
26     {
27       this->data = data;
28       ev_set_cb (static_cast<ev_watcher *>(this), cb);
29     }
30
31     // method callback
32     template<class K, void (K::*method)(watcher &w, int)>
33     void set (K *object)
34     {
35       set_ (object, method_thunk<K, method>);
36     }
37
38     template<class K, void (K::*method)(watcher &w, int)>
39     static void method_thunk (EV_P_ ev_watcher *w, int revents)
40     {
41       K *obj = static_cast<K *>(w->data);
42       (obj->*method) (*static_cast<watcher *>(w), revents);
43     }
44
45     // const method callback
46     template<class K, void (K::*method)(watcher &w, int) const>
47     void set (const K *object)
48     {
49       set_ (object, const_method_thunk<K, method>);
50     }
51
52     template<class K, void (K::*method)(watcher &w, int) const>
53     static void const_method_thunk (EV_P_ ev_watcher *w, int revents)
54     {
55       K *obj = static_cast<K *>(w->data);
56       (static_cast<K *>(w->data)->*method) (*static_cast<watcher *>(w), revents);
57     }
58
59     // function callback
60     template<void (*function)(watcher &w, int)>
61     void set (void *data = 0)
62     {
63       set_ (data, function_thunk<function>);
64     }
65
66     template<void (*function)(watcher &w, int)>
67     static void function_thunk (EV_P_ ev_watcher *w, int revents)
68     {
69       function (*static_cast<watcher *>(w), revents);
70     }
71
72     // simple callback
73     template<class K, void (K::*method)()>
74     void set (K *object)
75     {
76       set_ (object, method_noargs_thunk<K, method>);
77     }
78
79     template<class K, void (K::*method)()>
80     static void method_noargs_thunk (EV_P_ ev_watcher *w, int revents)
81     {
82       K *obj = static_cast<K *>(w->data);
83       (obj->*method) ();
84     }
85
86     void operator ()(int events = EV_UNDEF)
87     {
88       return ev_cb (static_cast<ev_watcher *>(this))
89         (static_cast<ev_watcher *>(this), events);
90     }
91
92     bool is_active () const
93     {
94       return ev_is_active (static_cast<const ev_watcher *>(this));
95     }
96
97     bool is_pending () const
98     {
99       return ev_is_pending (static_cast<const ev_watcher *>(this));
100     }
101   };
102
103   enum {
104     UNDEF    = EV_UNDEF,
105     NONE     = EV_NONE,
106     READ     = EV_READ,
107     WRITE    = EV_WRITE,
108     TIMEOUT  = EV_TIMEOUT,
109     PERIODIC = EV_PERIODIC,
110     SIGNAL   = EV_SIGNAL,
111     CHILD    = EV_CHILD,
112     STAT     = EV_STAT,
113     IDLE     = EV_IDLE,
114     CHECK    = EV_CHECK,
115     PREPARE  = EV_PREPARE,
116     FORK     = EV_FORK,
117     EMBED    = EV_EMBED,
118     ERROR    = EV_ERROR,
119   };
120
121   typedef ev_tstamp tstamp;
122
123   inline ev_tstamp now (EV_P)
124   {
125     return ev_now (EV_A);
126   }
127
128   #if EV_MULTIPLICITY
129     #define EV_CONSTRUCT                                                                \
130       (EV_P = EV_DEFAULT)                                                               \
131       {                                                                                 \
132         set (EV_A);                                                                     \
133       }
134   #else
135     #define EV_CONSTRUCT                                                                \
136       ()                                                                                \
137       {                                                                                 \
138       }
139   #endif
140
141   /* using a template here would require quite a bit more lines,
142    * so a macro solution was chosen */
143   #define EV_BEGIN_WATCHER(cppstem,cstem)                                               \
144                                                                                         \
145   struct cppstem : base<ev_ ## cstem, cppstem>                                          \
146   {                                                                                     \
147     void start ()                                                                       \
148     {                                                                                   \
149       ev_ ## cstem ## _start (EV_A_ static_cast<ev_ ## cstem *>(this));                 \
150     }                                                                                   \
151                                                                                         \
152     void stop ()                                                                        \
153     {                                                                                   \
154       ev_ ## cstem ## _stop (EV_A_ static_cast<ev_ ## cstem *>(this));                  \
155     }                                                                                   \
156                                                                                         \
157     cppstem EV_CONSTRUCT                                                                \
158                                                                                         \
159     ~cppstem ()                                                                         \
160     {                                                                                   \
161       stop ();                                                                          \
162     }                                                                                   \
163                                                                                         \
164     using base<ev_ ## cstem, cppstem>::set;                                             \
165                                                                                         \
166   private:                                                                              \
167                                                                                         \
168     cppstem (const cppstem &o)                                                          \
169     { /* disabled */ }                                                                  \
170                                                                                         \
171     void operator =(const cppstem &o) { /* disabled */ }                                \
172                                                                                         \
173   public:
174
175   #define EV_END_WATCHER(cppstem,cstem)                                                 \
176   };
177
178   EV_BEGIN_WATCHER (io, io)
179     void set (int fd, int events)
180     {
181       int active = is_active ();
182       if (active) stop ();
183       ev_io_set (static_cast<ev_io *>(this), fd, events);
184       if (active) start ();
185     }
186
187     void set (int events)
188     {
189       int active = is_active ();
190       if (active) stop ();
191       ev_io_set (static_cast<ev_io *>(this), fd, events);
192       if (active) start ();
193     }
194
195     void start (int fd, int events)
196     {
197       set (fd, events);
198       start ();
199     }
200   EV_END_WATCHER (io, io)
201
202   EV_BEGIN_WATCHER (timer, timer)
203     void set (ev_tstamp after, ev_tstamp repeat = 0.)
204     {
205       int active = is_active ();
206       if (active) stop ();
207       ev_timer_set (static_cast<ev_timer *>(this), after, repeat);
208       if (active) start ();
209     }
210
211     void start (ev_tstamp after, ev_tstamp repeat = 0.)
212     {
213       set (after, repeat);
214       start ();
215     }
216
217     void again ()
218     {
219       ev_timer_again (EV_A_ static_cast<ev_timer *>(this));
220     }
221   EV_END_WATCHER (timer, timer)
222
223   #if EV_PERIODIC_ENABLE
224   EV_BEGIN_WATCHER (periodic, periodic)
225     void set (ev_tstamp at, ev_tstamp interval = 0.)
226     {
227       int active = is_active ();
228       if (active) stop ();
229       ev_periodic_set (static_cast<ev_periodic *>(this), at, interval, 0);
230       if (active) start ();
231     }
232
233     void start (ev_tstamp at, ev_tstamp interval = 0.)
234     {
235       set (at, interval);
236       start ();
237     }
238
239     void again ()
240     {
241       ev_periodic_again (EV_A_ static_cast<ev_periodic *>(this));
242     }
243   EV_END_WATCHER (periodic, periodic)
244   #endif
245
246   EV_BEGIN_WATCHER (sig, signal)
247     void set (int signum)
248     {
249       int active = is_active ();
250       if (active) stop ();
251       ev_signal_set (static_cast<ev_signal *>(this), signum);
252       if (active) start ();
253     }
254
255     void start (int signum)
256     {
257       set (signum);
258       start ();
259     }
260   EV_END_WATCHER (sig, signal)
261
262   EV_BEGIN_WATCHER (child, child)
263     void set (int pid)
264     {
265       int active = is_active ();
266       if (active) stop ();
267       ev_child_set (static_cast<ev_child *>(this), pid);
268       if (active) start ();
269     }
270
271     void start (int pid)
272     {
273       set (pid);
274       start ();
275     }
276   EV_END_WATCHER (child, child)
277
278   #if EV_STAT_ENABLE
279   EV_BEGIN_WATCHER (stat, stat)
280     void set (const char *path, ev_tstamp interval = 0.)
281     {
282       int active = is_active ();
283       if (active) stop ();
284       ev_stat_set (static_cast<ev_stat *>(this), path, interval);
285       if (active) start ();
286     }
287
288     void start (const char *path, ev_tstamp interval = 0.)
289     {
290       stop ();
291       set (path, interval);
292       start ();
293     }
294
295     void update ()
296     {
297       ev_stat_stat (EV_A_ static_cast<ev_stat *>(this));
298     }
299   EV_END_WATCHER (stat, stat)
300   #endif
301
302   EV_BEGIN_WATCHER (idle, idle)
303     void set () { }
304   EV_END_WATCHER (idle, idle)
305
306   EV_BEGIN_WATCHER (prepare, prepare)
307     void set () { }
308   EV_END_WATCHER (prepare, prepare)
309
310   EV_BEGIN_WATCHER (check, check)
311     void set () { }
312   EV_END_WATCHER (check, check)
313
314   #if EV_EMBED_ENABLE
315   EV_BEGIN_WATCHER (embed, embed)
316     void start (struct ev_loop *embedded_loop)
317     {
318       stop ();
319       ev_embed_set (static_cast<ev_embed *>(this), embedded_loop);
320       start ();
321     }
322
323     void sweep ()
324     {
325       ev_embed_sweep (EV_A_ static_cast<ev_embed *>(this));
326     }
327   EV_END_WATCHER (embed, embed)
328   #endif
329
330   #if EV_FORK_ENABLE
331   EV_BEGIN_WATCHER (fork, fork)
332     void set () { }
333   EV_END_WATCHER (fork, fork)
334   #endif
335
336   #undef EV_CONSTRUCT
337   #undef EV_BEGIN_WATCHER
338   #undef EV_END_WATCHER
339 }
340
341 #endif
342