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