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