Mirror of :pserver:anonymous@cvs.schmorp.de/schmorpforge libev http://software.schmorp.de/pkg/libev.html
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

294 lines
10 KiB

14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
  1. #ifndef EVPP_H__
  2. #define EVPP_H__
  3. #include "ev.h"
  4. namespace ev {
  5. template<class watcher>
  6. class callback
  7. {
  8. struct object { };
  9. void *obj;
  10. void (object::*meth)(watcher &, int);
  11. /* a proxy is a kind of recipe on how to call a specific class method */
  12. struct proxy_base {
  13. virtual void call (void *obj, void (object::*meth)(watcher &, int), watcher &w, int) const = 0;
  14. };
  15. template<class O1, class O2>
  16. struct proxy : proxy_base {
  17. virtual void call (void *obj, void (object::*meth)(watcher &, int), watcher &w, int e) const
  18. {
  19. ((reinterpret_cast<O1 *>(obj)) ->* (reinterpret_cast<void (O2::*)(watcher &, int)>(meth)))
  20. (w, e);
  21. }
  22. };
  23. proxy_base *prxy;
  24. public:
  25. template<class O1, class O2>
  26. explicit callback (O1 *object, void (O2::*method)(watcher &, int))
  27. {
  28. static proxy<O1,O2> p;
  29. obj = reinterpret_cast<void *>(object);
  30. meth = reinterpret_cast<void (object::*)(watcher &, int)>(method);
  31. prxy = &p;
  32. }
  33. void call (watcher *w, int e) const
  34. {
  35. return prxy->call (obj, meth, *w, e);
  36. }
  37. };
  38. enum {
  39. UNDEF = EV_UNDEF,
  40. NONE = EV_NONE,
  41. READ = EV_READ,
  42. WRITE = EV_WRITE,
  43. TIMEOUT = EV_TIMEOUT,
  44. PERIODIC = EV_PERIODIC,
  45. SIGNAL = EV_SIGNAL,
  46. IDLE = EV_IDLE,
  47. CHECK = EV_CHECK,
  48. PREPARE = EV_PREPARE,
  49. CHILD = EV_CHILD,
  50. ERROR = EV_ERROR,
  51. };
  52. typedef ev_tstamp tstamp;
  53. inline ev_tstamp now (EV_P)
  54. {
  55. return ev_now (EV_A);
  56. }
  57. #if EV_MULTIPLICITY
  58. #define EV_CONSTRUCT(cppstem) \
  59. EV_P; \
  60. \
  61. void set (EV_P) \
  62. { \
  63. this->EV_A = EV_A; \
  64. } \
  65. \
  66. template<class O1, class O2> \
  67. explicit cppstem (O1 *object, void (O2::*method)(cppstem &, int), EV_P = ev_default_loop (0)) \
  68. : callback<cppstem> (object, method), EV_A (EV_A)
  69. #else
  70. #define EV_CONSTRUCT(cppstem) \
  71. template<class O1, class O2> \
  72. explicit cppstem (O1 *object, void (O2::*method)(cppstem &, int)) \
  73. : callback<cppstem> (object, method)
  74. #endif
  75. /* using a template here would require quite a bit more lines,
  76. * so a macro solution was chosen */
  77. #define EV_BEGIN_WATCHER(cppstem,cstem) \
  78. \
  79. struct cppstem : ev_ ## cstem, callback<cppstem> \
  80. { \
  81. EV_CONSTRUCT (cppstem) \
  82. { \
  83. ev_init (static_cast<ev_ ## cstem *>(this), thunk); \
  84. } \
  85. \
  86. bool is_active () const \
  87. { \
  88. return ev_is_active (static_cast<const ev_ ## cstem *>(this)); \
  89. } \
  90. \
  91. bool is_pending () const \
  92. { \
  93. return ev_is_pending (static_cast<const ev_ ## cstem *>(this)); \
  94. } \
  95. \
  96. void start () \
  97. { \
  98. ev_ ## cstem ## _start (EV_A_ static_cast<ev_ ## cstem *>(this)); \
  99. } \
  100. \
  101. void stop () \
  102. { \
  103. ev_ ## cstem ## _stop (EV_A_ static_cast<ev_ ## cstem *>(this)); \
  104. } \
  105. \
  106. void operator ()(int events = EV_UNDEF) \
  107. { \
  108. return call (this, events); \
  109. } \
  110. \
  111. ~cppstem () \
  112. { \
  113. stop (); \
  114. } \
  115. \
  116. private: \
  117. \
  118. cppstem (const cppstem &o) \
  119. : callback<cppstem> (this, (void (cppstem::*)(cppstem &, int))0) \
  120. { /* disabled */ } \
  121. \
  122. void operator =(const cppstem &o) { /* disabled */ } \
  123. \
  124. static void thunk (EV_P_ struct ev_ ## cstem *w, int revents) \
  125. { \
  126. (*static_cast<cppstem *>(w))(revents); \
  127. } \
  128. \
  129. public:
  130. #define EV_END_WATCHER(cppstem,cstem) \
  131. };
  132. EV_BEGIN_WATCHER (io, io)
  133. void set (int fd, int events)
  134. {
  135. int active = is_active ();
  136. if (active) stop ();
  137. ev_io_set (static_cast<ev_io *>(this), fd, events);
  138. if (active) start ();
  139. }
  140. void set (int events)
  141. {
  142. int active = is_active ();
  143. if (active) stop ();
  144. ev_io_set (static_cast<ev_io *>(this), fd, events);
  145. if (active) start ();
  146. }
  147. void start (int fd, int events)
  148. {
  149. set (fd, events);
  150. start ();
  151. }
  152. EV_END_WATCHER (io, io)
  153. EV_BEGIN_WATCHER (timer, timer)
  154. void set (ev_tstamp after, ev_tstamp repeat = 0.)
  155. {
  156. int active = is_active ();
  157. if (active) stop ();
  158. ev_timer_set (static_cast<ev_timer *>(this), after, repeat);
  159. if (active) start ();
  160. }
  161. void start (ev_tstamp after, ev_tstamp repeat = 0.)
  162. {
  163. set (after, repeat);
  164. start ();
  165. }
  166. void again ()
  167. {
  168. ev_timer_again (EV_A_ static_cast<ev_timer *>(this));
  169. }
  170. EV_END_WATCHER (timer, timer)
  171. #if EV_PERIODICS
  172. EV_BEGIN_WATCHER (periodic, periodic)
  173. void set (ev_tstamp at, ev_tstamp interval = 0.)
  174. {
  175. int active = is_active ();
  176. if (active) stop ();
  177. ev_periodic_set (static_cast<ev_periodic *>(this), at, interval, 0);
  178. if (active) start ();
  179. }
  180. void start (ev_tstamp at, ev_tstamp interval = 0.)
  181. {
  182. set (at, interval);
  183. start ();
  184. }
  185. void again ()
  186. {
  187. ev_periodic_again (EV_A_ static_cast<ev_periodic *>(this));
  188. }
  189. EV_END_WATCHER (periodic, periodic)
  190. #endif
  191. EV_BEGIN_WATCHER (idle, idle)
  192. void set () { }
  193. EV_END_WATCHER (idle, idle)
  194. EV_BEGIN_WATCHER (prepare, prepare)
  195. void set () { }
  196. EV_END_WATCHER (prepare, prepare)
  197. EV_BEGIN_WATCHER (check, check)
  198. void set () { }
  199. EV_END_WATCHER (check, check)
  200. EV_BEGIN_WATCHER (sig, signal)
  201. void set (int signum)
  202. {
  203. int active = is_active ();
  204. if (active) stop ();
  205. ev_signal_set (static_cast<ev_signal *>(this), signum);
  206. if (active) start ();
  207. }
  208. void start (int signum)
  209. {
  210. set (signum);
  211. start ();
  212. }
  213. EV_END_WATCHER (sig, signal)
  214. EV_BEGIN_WATCHER (child, child)
  215. void set (int pid)
  216. {
  217. int active = is_active ();
  218. if (active) stop ();
  219. ev_child_set (static_cast<ev_child *>(this), pid);
  220. if (active) start ();
  221. }
  222. void start (int pid)
  223. {
  224. set (pid);
  225. start ();
  226. }
  227. EV_END_WATCHER (child, child)
  228. #if EV_MULTIPLICITY
  229. EV_BEGIN_WATCHER (embed, embed)
  230. void set (struct ev_loop *loop)
  231. {
  232. int active = is_active ();
  233. if (active) stop ();
  234. ev_embed_set (static_cast<ev_embed *>(this), loop);
  235. if (active) start ();
  236. }
  237. void start (struct ev_loop *embedded_loop)
  238. {
  239. set (embedded_loop);
  240. start ();
  241. }
  242. void sweep ()
  243. {
  244. ev_embed_sweep (EV_A_ static_cast<ev_embed *>(this));
  245. }
  246. EV_END_WATCHER (embed, embed)
  247. #endif
  248. #undef EV_CONSTRUCT
  249. #undef EV_BEGIN_WATCHER
  250. #undef EV_END_WATCHER
  251. }
  252. #endif