]> git.llucax.com Git - software/libev.git/blob - ev++.h
fix bug
[software/libev.git] / ev++.h
1 #ifndef EVPP_H__
2 #define EVPP_H__
3
4 /* work in progress, don't use unless you know what you are doing */
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   #include "ev.h"
48
49   enum {
50     UNDEF    = EV_UNDEF,
51     NONE     = EV_NONE,
52     READ     = EV_READ,
53     WRITE    = EV_WRITE,
54     TIMEOUT  = EV_TIMEOUT,
55     PERIODIC = EV_PERIODIC,
56     SIGNAL   = EV_SIGNAL,
57     IDLE     = EV_IDLE,
58     CHECK    = EV_CHECK,
59     PREPARE  = EV_PREPARE,
60     CHILD    = EV_CHILD,
61     ERROR    = EV_ERROR,
62   };
63
64   typedef ev_tstamp tstamp;
65
66   inline ev_tstamp now (EV_P)
67   {
68     return ev_now (EV_A);
69   }
70
71   #if EV_MULTIPLICITY
72
73     #define EV_CONSTRUCT(cppstem)                                                       \
74       EV_P;                                                                             \
75                                                                                         \
76       void set (EV_P)                                                                   \
77       {                                                                                 \
78         this->EV_A = EV_A;                                                              \
79       }                                                                                 \
80                                                                                         \
81       template<class O1, class O2>                                                      \
82       explicit cppstem (O1 *object, void (O2::*method)(cppstem &, int), EV_P = ev_default_loop (0)) \
83       : callback<cppstem> (object, method), EV_A (EV_A)
84
85   #else
86
87     #define EV_CONSTRUCT(cppstem)                                                       \
88       template<class O1, class O2>                                                      \
89       explicit cppstem (O1 *object, void (O2::*method)(cppstem &, int))                 \
90       : callback<cppstem> (object, method)
91
92   #endif
93
94   /* using a template here would require quite a bit more lines,
95    * so a macro solution was chosen */
96   #define EV_DECLARE_WATCHER(cppstem,cstem)                                             \
97                                                                                         \
98   extern "C" void cb_ ## cppstem (struct ev_ ## cstem *w, int revents);                 \
99                                                                                         \
100   struct cppstem : ev_ ## cstem, callback<cppstem>                                      \
101   {                                                                                     \
102     EV_CONSTRUCT (cppstem)                                                              \
103     {                                                                                   \
104       ev_init (static_cast<ev_ ## cstem *>(this), cb_ ## cppstem);                      \
105     }                                                                                   \
106                                                                                         \
107     bool is_active () const                                                             \
108     {                                                                                   \
109       return ev_is_active (static_cast<const ev_ ## cstem *>(this));                    \
110     }                                                                                   \
111                                                                                         \
112     bool is_pending () const                                                            \
113     {                                                                                   \
114       return ev_is_pending (static_cast<const ev_ ## cstem *>(this));                   \
115     }                                                                                   \
116                                                                                         \
117     void start ()                                                                       \
118     {                                                                                   \
119       ev_ ## cstem ## _start (EV_A_ static_cast<ev_ ## cstem *>(this));                 \
120     }                                                                                   \
121                                                                                         \
122     void stop ()                                                                        \
123     {                                                                                   \
124       ev_ ## cstem ## _stop (EV_A_ static_cast<ev_ ## cstem *>(this));                  \
125     }                                                                                   \
126                                                                                         \
127     void operator ()(int events = EV_UNDEF)                                             \
128     {                                                                                   \
129       return call (this, events);                                                       \
130     }                                                                                   \
131                                                                                         \
132     ~cppstem ()                                                                         \
133     {                                                                                   \
134       stop ();                                                                          \
135     }                                                                                   \
136                                                                                         \
137   private:                                                                              \
138                                                                                         \
139     cppstem (const cppstem &o)                                                          \
140     : callback<cppstem> (this, (void (cppstem::*)(cppstem &, int))0)                    \
141     { /* disabled */ }                                                                  \
142     void operator =(const cppstem &o) { /* disabled */ }                                \
143                                                                                         \
144   public:
145
146   EV_DECLARE_WATCHER (io, io)
147     void set (int fd, int events)
148     {
149       int active = is_active ();
150       if (active) stop ();
151       ev_io_set (static_cast<ev_io *>(this), fd, events);
152       if (active) start ();
153     }
154
155     void set (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 start (int fd, int events)
164     {
165       set (fd, events);
166       start ();
167     }
168   };
169
170   EV_DECLARE_WATCHER (timer, timer)
171     void set (ev_tstamp after, ev_tstamp repeat = 0.)
172     {
173       int active = is_active ();
174       if (active) stop ();
175       ev_timer_set (static_cast<ev_timer *>(this), after, repeat);
176       if (active) start ();
177     }
178
179     void start (ev_tstamp after, ev_tstamp repeat = 0.)
180     {
181       set (after, repeat);
182       start ();
183     }
184
185     void again ()
186     {
187       ev_timer_again (EV_A_ static_cast<ev_timer *>(this));
188     }
189   };
190
191   #if EV_PERIODICS
192   EV_DECLARE_WATCHER (periodic, periodic)
193     void set (ev_tstamp at, ev_tstamp interval = 0.)
194     {
195       int active = is_active ();
196       if (active) stop ();
197       ev_periodic_set (static_cast<ev_periodic *>(this), at, interval, 0);
198       if (active) start ();
199     }
200
201     void start (ev_tstamp at, ev_tstamp interval = 0.)
202     {
203       set (at, interval);
204       start ();
205     }
206
207     void again ()
208     {
209       ev_periodic_again (EV_A_ static_cast<ev_periodic *>(this));
210     }
211   };
212   #endif
213
214   EV_DECLARE_WATCHER (idle, idle)
215   };
216
217   EV_DECLARE_WATCHER (prepare, prepare)
218   };
219
220   EV_DECLARE_WATCHER (check, check)
221   };
222
223   EV_DECLARE_WATCHER (sig, signal)
224     void set (int signum)
225     {
226       int active = is_active ();
227       if (active) stop ();
228       ev_signal_set (static_cast<ev_signal *>(this), signum);
229       if (active) start ();
230     }
231
232     void start (int signum)
233     {
234       set (signum);
235       start ();
236     }
237   };
238
239   EV_DECLARE_WATCHER (child, child)
240     void set (int pid)
241     {
242       int active = is_active ();
243       if (active) stop ();
244       ev_child_set (static_cast<ev_child *>(this), pid);
245       if (active) start ();
246     }
247
248     void start (int pid)
249     {
250       set (pid);
251       start ();
252     }
253   };
254
255   #undef EV_CONSTRUCT
256   #undef EV_DECLARE_WATCHER
257 }
258
259 #endif
260