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