]> git.llucax.com Git - software/libev.git/commitdiff
first rough cut at c++ interface
authorroot <root>
Sat, 10 Nov 2007 21:19:29 +0000 (21:19 +0000)
committerroot <root>
Sat, 10 Nov 2007 21:19:29 +0000 (21:19 +0000)
ev++.C [new file with mode: 0644]
ev++.h [new file with mode: 0644]
ev.h

diff --git a/ev++.C b/ev++.C
new file mode 100644 (file)
index 0000000..f1f6ce0
--- /dev/null
+++ b/ev++.C
@@ -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); }
+  }
+}
+
diff --git a/ev++.h b/ev++.h
new file mode 100644 (file)
index 0000000..95d0a76
--- /dev/null
+++ b/ev++.h
@@ -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
+
diff --git a/ev.h b/ev.h
index cde9da047f6c12c45256d5fa4b826a477738dd6d..369e45c9cde259917977505175303e548a58f00f 100644 (file)
--- a/ev.h
+++ b/ev.h
@@ -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... */