ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/libev/ev++.h
Revision: 1.11
Committed: Tue Nov 27 22:31:52 2007 UTC (16 years, 5 months ago) by root
Content type: text/plain
Branch: MAIN
CVS Tags: rel-1_5
Changes since 1.10: +11 -24 lines
Log Message:
great idea. radically simplify the method callbacks

File Contents

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