diff options
| -rw-r--r-- | ev++.C | 15 | ||||
| -rw-r--r-- | ev++.h | 238 | ||||
| -rw-r--r-- | ev.h | 4 | 
3 files changed, 257 insertions, 0 deletions
| @@ -0,0 +1,15 @@ +#include "ev++.h" + +namespace ev { +  extern "C" { +    void cb_io       (struct ev_io       *w, int revents) { (*static_cast<io       *>(w))(revents); } +    void cb_timer    (struct ev_timer    *w, int revents) { (*static_cast<timer    *>(w))(revents); } +    void cb_periodic (struct ev_periodic *w, int revents) { (*static_cast<periodic *>(w))(revents); } +    void cb_idle     (struct ev_idle     *w, int revents) { (*static_cast<idle     *>(w))(revents); } +    void cb_prepare  (struct ev_prepare  *w, int revents) { (*static_cast<prepare  *>(w))(revents); } +    void cb_check    (struct ev_check    *w, int revents) { (*static_cast<check    *>(w))(revents); } +    void cb_sig      (struct ev_signal   *w, int revents) { (*static_cast<sig      *>(w))(revents); } +    void cb_child    (struct ev_child    *w, int revents) { (*static_cast<child    *>(w))(revents); } +  } +} + @@ -0,0 +1,238 @@ +#ifndef EVPP_H__ +#define EVPP_H__ + +/* work in progress, don't use unless you know what you are doing */ + +namespace ev { + +  template<class watcher> +  class callback +  { +    struct object { }; + +    void *obj; +    void (object::*meth)(watcher &, int); + +    /* a proxy is a kind of recipe on how to call a specific class method */ +    struct proxy_base { +      virtual void call (void *obj, void (object::*meth)(watcher &, int), watcher &w, int) const = 0; +    }; +    template<class O1, class O2> +    struct proxy : proxy_base { +      virtual void call (void *obj, void (object::*meth)(watcher &, int), watcher &w, int e) const +      { +        ((reinterpret_cast<O1 *>(obj)) ->* (reinterpret_cast<void (O2::*)(watcher &, int)>(meth))) +          (w, e); +      } +    }; + +    proxy_base *prxy; + +  public: +    template<class O1, class O2> +    explicit callback (O1 *object, void (O2::*method)(watcher &, int)) +    { +      static proxy<O1,O2> p; +      obj  = reinterpret_cast<void *>(object); +      meth = reinterpret_cast<void (object::*)(watcher &, int)>(method); +      prxy = &p; +    } + +    void call (watcher *w, int e) const +    { +      return prxy->call (obj, meth, *w, e); +    } +  }; + +  #include "ev.h" + +  typedef ev_tstamp tstamp; + +  inline ev_tstamp now (EV_P) +  { +    return ev_now (EV_A); +  } + +  #if EV_MULTIPLICITY + +    #define EV_CONSTRUCT(cppstem)							\ +      EV_P;                                                                             \ +                                                                                        \ +      void set (EV_P)                                                                   \ +      {                                                                                 \ +        this->EV_A = EV_A;                                                              \ +      }                                                                                 \ +                                                                                        \ +      template<class O1, class O2>                                                      \ +      explicit cppstem (O1 *object, void (O2::*method)(cppstem &, int), EV_P = ev_default_loop (0)) \ +      : callback<cppstem> (object, method), EV_A (EV_A) + +  #else + +    #define EV_CONSTRUCT(cppstem)							\ +      template<class O1, class O2>							\ +      explicit cppstem (O1 *object, void (O2::*method)(cppstem &, int))                 \ +      : callback<cppstem> (object, method) + +  #endif + +  /* using a template here would require quite a bit more lines, +   * so a macro solution was chosen */ +  #define EV_DECLARE_WATCHER(cppstem,cstem)	                                        \ +                                                                                        \ +  extern "C" void cb_ ## cppstem (struct ev_ ## cstem *w, int revents);                 \ +                                                                                        \ +  struct cppstem : ev_ ## cstem, callback<cppstem>                                      \ +  {                                                                                     \ +    EV_CONSTRUCT (cppstem)                                                              \ +    {                                                                                   \ +      ev_init (static_cast<ev_ ## cstem *>(this), cb_ ## cppstem);                      \ +    }                                                                                   \ +                                                                                        \ +    bool is_active () const                                                             \ +    {                                                                                   \ +      return ev_is_active (static_cast<const ev_ ## cstem *>(this));                    \ +    }                                                                                   \ +                                                                                        \ +    bool is_pending () const                                                            \ +    {                                                                                   \ +      return ev_is_pending (static_cast<const ev_ ## cstem *>(this));                   \ +    }                                                                                   \ +                                                                                        \ +    void start ()                                                                       \ +    {                                                                                   \ +      ev_ ## cstem ## _start (EV_A_ static_cast<ev_ ## cstem *>(this));                 \ +    }                                                                                   \ +                                                                                        \ +    void stop ()                                                                        \ +    {                                                                                   \ +      ev_ ## cstem ## _stop (EV_A_ static_cast<ev_ ## cstem *>(this));                  \ +    }                                                                                   \ +                                                                                        \ +    void operator ()(int events = EV_UNDEF)                                             \ +    {                                                                                   \ +      return call (this, events);                                                       \ +    }                                                                                   \ +                                                                                        \ +  private:                                                                              \ +                                                                                        \ +    cppstem (const cppstem &o)								\ +    : callback<cppstem> (this, (void (cppstem::*)(cppstem &, int))0)                    \ +    { /* disabled */ }                                        				\ +    void operator =(const cppstem &o) { /* disabled */ }                                \ +                                                                                        \ +  public: + +  EV_DECLARE_WATCHER (io, io) +    void set (int fd, int events) +    { +      int active = is_active (); +      if (active) stop (); +      ev_io_set (static_cast<ev_io *>(this), fd, events); +      if (active) start (); +    } + +    void set (int events) +    { +      int active = is_active (); +      if (active) stop (); +      ev_io_set (static_cast<ev_io *>(this), fd, events); +      if (active) start (); +    } + +    void start (int fd, int events) +    { +      set (fd, events); +      start (); +    } +  }; + +  EV_DECLARE_WATCHER (timer, timer) +    void set (ev_tstamp after, ev_tstamp repeat = 0.) +    { +      int active = is_active (); +      if (active) stop (); +      ev_timer_set (static_cast<ev_timer *>(this), after, repeat); +      if (active) start (); +    } + +    void start (ev_tstamp after, ev_tstamp repeat = 0.) +    { +      set (after, repeat); +      start (); +    } + +    void again () +    { +      ev_timer_again (EV_A_ static_cast<ev_timer *>(this)); +    } +  }; + +  EV_DECLARE_WATCHER (periodic, periodic) +    void set (ev_tstamp at, ev_tstamp interval = 0.) +    { +      int active = is_active (); +      if (active) stop (); +      ev_periodic_set (static_cast<ev_periodic *>(this), at, interval, 0); +      if (active) start (); +    } + +    void start (ev_tstamp at, ev_tstamp interval = 0.) +    { +      set (at, interval); +      start (); +    } + +    void again () +    { +      ev_periodic_again (EV_A_ static_cast<ev_periodic *>(this)); +    } +  }; + +  EV_DECLARE_WATCHER (idle, idle) +  }; + +  EV_DECLARE_WATCHER (prepare, prepare) +  }; + +  EV_DECLARE_WATCHER (check, check) +  }; + +  EV_DECLARE_WATCHER (sig, signal) +    void set (int signum) +    { +      int active = is_active (); +      if (active) stop (); +      ev_signal_set (static_cast<ev_signal *>(this), signum); +      if (active) start (); +    } + +    void start (int signum) +    { +      set (signum); +      start (); +    } +  }; + +  EV_DECLARE_WATCHER (child, child) +    void set (int pid) +    { +      int active = is_active (); +      if (active) stop (); +      ev_child_set (static_cast<ev_child *>(this), pid); +      if (active) start (); +    } + +    void start (int pid) +    { +      set (pid); +      start (); +    } +  }; + +  #undef EV_CONSTRUCT +  #undef EV_DECLARE_WATCHER +} + +#endif + @@ -55,11 +55,15 @@ struct ev_loop;  # define EV_P_ EV_P,  # define EV_A loop  # define EV_A_ EV_A, +# define EV_DEFAULT_A ev_default_loop (0) +# define EV_DEFAULT_A_ EV_DEFAULT_A,  #else  # define EV_P void  # define EV_P_  # define EV_A  # define EV_A_ +# define EV_DEFAULT_A +# define EV_DEFAULT_A_  #endif  /* eventmask, revents, events... */ | 
