]> git.llucax.com Git - software/libev.git/commitdiff
document c++ api
authorroot <root>
Sat, 24 Nov 2007 09:48:37 +0000 (09:48 +0000)
committerroot <root>
Sat, 24 Nov 2007 09:48:37 +0000 (09:48 +0000)
ev++.h
ev.3
ev.c
ev.h
ev.html
ev.pod

diff --git a/ev++.h b/ev++.h
index 82b65b9453f656e687e736306e90fe842e7d76e7..0f51bd5fce2950b807a94a65b25fda12fddb7934 100644 (file)
--- a/ev++.h
+++ b/ev++.h
@@ -1,7 +1,7 @@
 #ifndef EVPP_H__
 #define EVPP_H__
 
-/* work in progress, don't use unless you know what you are doing */
+#include "ev.h"
 
 namespace ev {
 
@@ -44,8 +44,6 @@ namespace ev {
     }
   };
 
-  #include "ev.h"
-
   enum {
     UNDEF    = EV_UNDEF,
     NONE     = EV_NONE,
@@ -219,12 +217,15 @@ namespace ev {
   #endif
 
   EV_BEGIN_WATCHER (idle, idle)
+    void set () { }
   EV_END_WATCHER (idle, idle)
 
   EV_BEGIN_WATCHER (prepare, prepare)
+    void set () { }
   EV_END_WATCHER (prepare, prepare)
 
   EV_BEGIN_WATCHER (check, check)
+    void set () { }
   EV_END_WATCHER (check, check)
 
   EV_BEGIN_WATCHER (sig, signal)
@@ -259,8 +260,34 @@ namespace ev {
     }
   EV_END_WATCHER (child, child)
 
+  #if EV_MULTIPLICITY
+
+  EV_BEGIN_WATCHER (embed, embed)
+    void set (struct ev_loop *loop)
+    {
+      int active = is_active ();
+      if (active) stop ();
+      ev_embed_set (static_cast<ev_embed *>(this), loop);
+      if (active) start ();
+    }
+
+    void start (struct ev_loop *embedded_loop)
+    {
+      set (embedded_loop);
+      start ();
+    }
+
+    void sweep ()
+    {
+      ev_embed_sweep (EV_A_ static_cast<ev_embed *>(this));
+    }
+  EV_END_WATCHER (embed, embed)
+
+  #endif
+
   #undef EV_CONSTRUCT
   #undef EV_BEGIN_WATCHER
+  #undef EV_END_WATCHER
 }
 
 #endif
diff --git a/ev.3 b/ev.3
index d9628a24413ddd93c922508830046521446461c0..46ffd2c1e0ffe1a6930830fbc0d49ca65c521da9 100644 (file)
--- a/ev.3
+++ b/ev.3
@@ -997,8 +997,8 @@ Periodic watchers are also timers of a kind, but they are very versatile
 Unlike \f(CW\*(C`ev_timer\*(C'\fR's, they are not based on real time (or relative time)
 but on wallclock time (absolute time). You can tell a periodic watcher
 to trigger \*(L"at\*(R" some specific point in time. For example, if you tell a
-periodic watcher to trigger in 10 seconds (by specifiying e.g. c<ev_now ()
-+ 10.>) and then reset your system clock to the last year, then it will
+periodic watcher to trigger in 10 seconds (by specifiying e.g. \f(CW\*(C`ev_now ()
++ 10.\*(C'\fR) and then reset your system clock to the last year, then it will
 take a year to trigger the event (unlike an \f(CW\*(C`ev_timer\*(C'\fR, which would trigger
 roughly 10 seconds later and of course not if you reset your system time
 again).
@@ -1434,7 +1434,110 @@ emulate the internals of libevent, so here are some usage hints:
 .PD
 .SH "\*(C+ SUPPORT"
 .IX Header " SUPPORT"
-\&\s-1TBD\s0.
+Libev comes with some simplistic wrapper classes for \*(C+ that mainly allow
+you to use some convinience methods to start/stop watchers and also change
+the callback model to a model using method callbacks on objects.
+.PP
+To use it,
+.PP
+.Vb 1
+\&  #include <ev++.h>
+.Ve
+.PP
+(it is not installed by default). This automatically includes \fIev.h\fR
+and puts all of its definitions (many of them macros) into the global
+namespace. All \*(C+ specific things are put into the \f(CW\*(C`ev\*(C'\fR namespace.
+.PP
+It should support all the same embedding options as \fIev.h\fR, most notably
+\&\f(CW\*(C`EV_MULTIPLICITY\*(C'\fR.
+.PP
+Here is a list of things available in the \f(CW\*(C`ev\*(C'\fR namespace:
+.ie n .IP """ev::READ""\fR, \f(CW""ev::WRITE"" etc." 4
+.el .IP "\f(CWev::READ\fR, \f(CWev::WRITE\fR etc." 4
+.IX Item "ev::READ, ev::WRITE etc."
+These are just enum values with the same values as the \f(CW\*(C`EV_READ\*(C'\fR etc.
+macros from \fIev.h\fR.
+.ie n .IP """ev::tstamp""\fR, \f(CW""ev::now""" 4
+.el .IP "\f(CWev::tstamp\fR, \f(CWev::now\fR" 4
+.IX Item "ev::tstamp, ev::now"
+Aliases to the same types/functions as with the \f(CW\*(C`ev_\*(C'\fR prefix.
+.ie n .IP """ev::io""\fR, \f(CW""ev::timer""\fR, \f(CW""ev::periodic""\fR, \f(CW""ev::idle""\fR, \f(CW""ev::sig"" etc." 4
+.el .IP "\f(CWev::io\fR, \f(CWev::timer\fR, \f(CWev::periodic\fR, \f(CWev::idle\fR, \f(CWev::sig\fR etc." 4
+.IX Item "ev::io, ev::timer, ev::periodic, ev::idle, ev::sig etc."
+For each \f(CW\*(C`ev_TYPE\*(C'\fR watcher in \fIev.h\fR there is a corresponding class of
+the same name in the \f(CW\*(C`ev\*(C'\fR namespace, with the exception of \f(CW\*(C`ev_signal\*(C'\fR
+which is called \f(CW\*(C`ev::sig\*(C'\fR to avoid clashes with the \f(CW\*(C`signal\*(C'\fR macro
+defines by many implementations.
+.Sp
+All of those classes have these methods:
+.RS 4
+.IP "ev::TYPE::TYPE (object *, object::method *)" 4
+.IX Item "ev::TYPE::TYPE (object *, object::method *)"
+.PD 0
+.IP "ev::TYPE::TYPE (object *, object::method *, struct ev_loop *)" 4
+.IX Item "ev::TYPE::TYPE (object *, object::method *, struct ev_loop *)"
+.IP "ev::TYPE::~TYPE" 4
+.IX Item "ev::TYPE::~TYPE"
+.PD
+The constructor takes a pointer to an object and a method pointer to
+the event handler callback to call in this class. The constructor calls
+\&\f(CW\*(C`ev_init\*(C'\fR for you, which means you have to call the \f(CW\*(C`set\*(C'\fR method
+before starting it. If you do not specify a loop then the constructor
+automatically associates the default loop with this watcher.
+.Sp
+The destructor automatically stops the watcher if it is active.
+.IP "w\->set (struct ev_loop *)" 4
+.IX Item "w->set (struct ev_loop *)"
+Associates a different \f(CW\*(C`struct ev_loop\*(C'\fR with this watcher. You can only
+do this when the watcher is inactive (and not pending either).
+.IP "w\->set ([args])" 4
+.IX Item "w->set ([args])"
+Basically the same as \f(CW\*(C`ev_TYPE_set\*(C'\fR, with the same args. Must be
+called at least once.  Unlike the C counterpart, an active watcher gets
+automatically stopped and restarted.
+.IP "w\->start ()" 4
+.IX Item "w->start ()"
+Starts the watcher. Note that there is no \f(CW\*(C`loop\*(C'\fR argument as the
+constructor already takes the loop.
+.IP "w\->stop ()" 4
+.IX Item "w->stop ()"
+Stops the watcher if it is active. Again, no \f(CW\*(C`loop\*(C'\fR argument.
+.ie n .IP "w\->again ()       ""ev::timer""\fR, \f(CW""ev::periodic"" only" 4
+.el .IP "w\->again ()       \f(CWev::timer\fR, \f(CWev::periodic\fR only" 4
+.IX Item "w->again ()       ev::timer, ev::periodic only"
+For \f(CW\*(C`ev::timer\*(C'\fR and \f(CW\*(C`ev::periodic\*(C'\fR, this invokes the corresponding
+\&\f(CW\*(C`ev_TYPE_again\*(C'\fR function.
+.ie n .IP "w\->sweep ()       ""ev::embed"" only" 4
+.el .IP "w\->sweep ()       \f(CWev::embed\fR only" 4
+.IX Item "w->sweep ()       ev::embed only"
+Invokes \f(CW\*(C`ev_embed_sweep\*(C'\fR.
+.RE
+.RS 4
+.RE
+.PP
+Example: Define a class with an \s-1IO\s0 and idle watcher, start one of them in
+the constructor.
+.PP
+.Vb 4
+\&  class myclass
+\&  {
+\&    ev_io   io;   void io_cb   (ev::io   &w, int revents);
+\&    ev_idle idle  void idle_cb (ev::idle &w, int revents);
+.Ve
+.PP
+.Vb 2
+\&    myclass ();
+\&  }
+.Ve
+.PP
+.Vb 6
+\&  myclass::myclass (int fd)
+\&  : io   (this, &myclass::io_cb),
+\&    idle (this, &myclass::idle_cb)
+\&  {
+\&    io.start (fd, ev::READ);
+\&  }
+.Ve
 .SH "AUTHOR"
 .IX Header "AUTHOR"
 Marc Lehmann <libev@schmorp.de>.
diff --git a/ev.c b/ev.c
index 9c5d42ba43f3f498e367981323b9483a80ea0296..1e008e577c20de897833392a59416e384bf6c828 100644 (file)
--- a/ev.c
+++ b/ev.c
@@ -1674,7 +1674,7 @@ ev_child_stop (EV_P_ ev_child *w)
 
 #if EV_MULTIPLICITY
 void
-ev_embed_loop (EV_P_ ev_embed *w)
+ev_embed_sweep (EV_P_ ev_embed *w)
 {
   ev_loop (w->loop, EVLOOP_NONBLOCK);
 }
@@ -1687,7 +1687,7 @@ embed_cb (EV_P_ ev_io *io, int revents)
   if (ev_cb (w))
     ev_feed_event (EV_A_ (W)w, EV_EMBED);
   else
-    ev_embed_loop (loop, w);
+    ev_embed_sweep (loop, w);
 }
 
 void
diff --git a/ev.h b/ev.h
index 00b3baaddf682836c936b52b2b9a60de4a2964f8..0e56875fd34b72a0e3e87834af74f0ad5d2483bd 100644 (file)
--- a/ev.h
+++ b/ev.h
@@ -437,7 +437,7 @@ void ev_child_stop     (EV_P_ ev_child *w);
 /* only supported when loop to be embedded is in fact embeddable */
 void ev_embed_start    (EV_P_ ev_embed *w);
 void ev_embed_stop     (EV_P_ ev_embed *w);
-void ev_embed_loop     (EV_P_ ev_embed *w);
+void ev_embed_sweep    (EV_P_ ev_embed *w);
 # endif
 
 #endif
diff --git a/ev.html b/ev.html
index b6e3e6eb3cc4f89c91dac70c9a8485bb9ffd842f..8c61bc2317085e4acf2642753957e713a4c75a40 100644 (file)
--- a/ev.html
+++ b/ev.html
@@ -6,7 +6,7 @@
        <meta name="description" content="Pod documentation for libev" />
        <meta name="inputfile" content="&lt;standard input&gt;" />
        <meta name="outputfile" content="&lt;standard output&gt;" />
-       <meta name="created" content="Sat Nov 24 08:20:38 2007" />
+       <meta name="created" content="Sat Nov 24 10:48:32 2007" />
        <meta name="generator" content="Pod::Xhtml 1.57" />
 <link rel="stylesheet" href="http://res.tst.eu/pod.css"/></head>
 <body>
@@ -879,8 +879,8 @@ inactivity.</p>
 <p>Unlike <code>ev_timer</code>'s, they are not based on real time (or relative time)
 but on wallclock time (absolute time). You can tell a periodic watcher
 to trigger &quot;at&quot; some specific point in time. For example, if you tell a
-periodic watcher to trigger in 10 seconds (by specifiying e.g. c&lt;ev_now ()
-+ 10.&gt;) and then reset your system clock to the last year, then it will
+periodic watcher to trigger in 10 seconds (by specifiying e.g. <code>ev_now ()
++ 10.</code>) and then reset your system clock to the last year, then it will
 take a year to trigger the event (unlike an <code>ev_timer</code>, which would trigger
 roughly 10 seconds later and of course not if you reset your system time
 again).</p>
@@ -1308,7 +1308,100 @@ to use the libev header file and library.</dt>
 </div>
 <h1 id="C_SUPPORT">C++ SUPPORT</h1><p><a href="#TOP" class="toplink">Top</a></p>
 <div id="C_SUPPORT_CONTENT">
-<p>TBD.</p>
+<p>Libev comes with some simplistic wrapper classes for C++ that mainly allow
+you to use some convinience methods to start/stop watchers and also change
+the callback model to a model using method callbacks on objects.</p>
+<p>To use it,</p>
+<pre>  #include &lt;ev++.h&gt;
+
+</pre>
+<p>(it is not installed by default). This automatically includes <cite>ev.h</cite>
+and puts all of its definitions (many of them macros) into the global
+namespace. All C++ specific things are put into the <code>ev</code> namespace.</p>
+<p>It should support all the same embedding options as <cite>ev.h</cite>, most notably
+<code>EV_MULTIPLICITY</code>.</p>
+<p>Here is a list of things available in the <code>ev</code> namespace:</p>
+<dl>
+       <dt><code>ev::READ</code>, <code>ev::WRITE</code> etc.</dt>
+       <dd>
+               <p>These are just enum values with the same values as the <code>EV_READ</code> etc.
+macros from <cite>ev.h</cite>.</p>
+       </dd>
+       <dt><code>ev::tstamp</code>, <code>ev::now</code></dt>
+       <dd>
+               <p>Aliases to the same types/functions as with the <code>ev_</code> prefix.</p>
+       </dd>
+       <dt><code>ev::io</code>, <code>ev::timer</code>, <code>ev::periodic</code>, <code>ev::idle</code>, <code>ev::sig</code> etc.</dt>
+       <dd>
+               <p>For each <code>ev_TYPE</code> watcher in <cite>ev.h</cite> there is a corresponding class of
+the same name in the <code>ev</code> namespace, with the exception of <code>ev_signal</code>
+which is called <code>ev::sig</code> to avoid clashes with the <code>signal</code> macro
+defines by many implementations.</p>
+               <p>All of those classes have these methods:</p>
+               <p>
+                       <dl>
+                               <dt>ev::TYPE::TYPE (object *, object::method *)</dt>
+                               <dt>ev::TYPE::TYPE (object *, object::method *, struct ev_loop *)</dt>
+                               <dt>ev::TYPE::~TYPE</dt>
+                               <dd>
+                                       <p>The constructor takes a pointer to an object and a method pointer to
+the event handler callback to call in this class. The constructor calls
+<code>ev_init</code> for you, which means you have to call the <code>set</code> method
+before starting it. If you do not specify a loop then the constructor
+automatically associates the default loop with this watcher.</p>
+                                       <p>The destructor automatically stops the watcher if it is active.</p>
+                               </dd>
+                               <dt>w-&gt;set (struct ev_loop *)</dt>
+                               <dd>
+                                       <p>Associates a different <code>struct ev_loop</code> with this watcher. You can only
+do this when the watcher is inactive (and not pending either).</p>
+                               </dd>
+                               <dt>w-&gt;set ([args])</dt>
+                               <dd>
+                                       <p>Basically the same as <code>ev_TYPE_set</code>, with the same args. Must be
+called at least once.  Unlike the C counterpart, an active watcher gets
+automatically stopped and restarted.</p>
+                               </dd>
+                               <dt>w-&gt;start ()</dt>
+                               <dd>
+                                       <p>Starts the watcher. Note that there is no <code>loop</code> argument as the
+constructor already takes the loop.</p>
+                               </dd>
+                               <dt>w-&gt;stop ()</dt>
+                               <dd>
+                                       <p>Stops the watcher if it is active. Again, no <code>loop</code> argument.</p>
+                               </dd>
+                               <dt>w-&gt;again ()       <code>ev::timer</code>, <code>ev::periodic</code> only</dt>
+                               <dd>
+                                       <p>For <code>ev::timer</code> and <code>ev::periodic</code>, this invokes the corresponding
+<code>ev_TYPE_again</code> function.</p>
+                               </dd>
+                               <dt>w-&gt;sweep ()       <code>ev::embed</code> only</dt>
+                               <dd>
+                                       <p>Invokes <code>ev_embed_sweep</code>.</p>
+                               </dd>
+                       </dl>
+               </p>
+       </dd>
+</dl>
+<p>Example: Define a class with an IO and idle watcher, start one of them in
+the constructor.</p>
+<pre>  class myclass
+  {
+    ev_io   io;   void io_cb   (ev::io   &amp;w, int revents);
+    ev_idle idle  void idle_cb (ev::idle &amp;w, int revents);
+
+    myclass ();
+  }
+
+  myclass::myclass (int fd)
+  : io   (this, &amp;myclass::io_cb),
+    idle (this, &amp;myclass::idle_cb)
+  {
+    io.start (fd, ev::READ);
+  }
+
+</pre>
 
 </div>
 <h1 id="AUTHOR">AUTHOR</h1><p><a href="#TOP" class="toplink">Top</a></p>
diff --git a/ev.pod b/ev.pod
index 0bb20746948af48c4e09ce74632570eb3d77a38f..5440be5d550f9dfcc75920231c1843e29d243bfb 100644 (file)
--- a/ev.pod
+++ b/ev.pod
@@ -858,7 +858,7 @@ Periodic watchers are also timers of a kind, but they are very versatile
 Unlike C<ev_timer>'s, they are not based on real time (or relative time)
 but on wallclock time (absolute time). You can tell a periodic watcher
 to trigger "at" some specific point in time. For example, if you tell a
-periodic watcher to trigger in 10 seconds (by specifiying e.g. c<ev_now ()
+periodic watcher to trigger in 10 seconds (by specifiying e.g. C<ev_now ()
 + 10.>) and then reset your system clock to the last year, then it will
 take a year to trigger the event (unlike an C<ev_timer>, which would trigger
 roughly 10 seconds later and of course not if you reset your system time
@@ -1312,7 +1312,109 @@ to use the libev header file and library.
 
 =head1 C++ SUPPORT
 
-TBD.
+Libev comes with some simplistic wrapper classes for C++ that mainly allow
+you to use some convinience methods to start/stop watchers and also change
+the callback model to a model using method callbacks on objects.
+
+To use it,
+   
+  #include <ev++.h>
+
+(it is not installed by default). This automatically includes F<ev.h>
+and puts all of its definitions (many of them macros) into the global
+namespace. All C++ specific things are put into the C<ev> namespace.
+
+It should support all the same embedding options as F<ev.h>, most notably
+C<EV_MULTIPLICITY>.
+
+Here is a list of things available in the C<ev> namespace:
+
+=over 4
+
+=item C<ev::READ>, C<ev::WRITE> etc.
+
+These are just enum values with the same values as the C<EV_READ> etc.
+macros from F<ev.h>.
+
+=item C<ev::tstamp>, C<ev::now>
+
+Aliases to the same types/functions as with the C<ev_> prefix.
+
+=item C<ev::io>, C<ev::timer>, C<ev::periodic>, C<ev::idle>, C<ev::sig> etc.
+
+For each C<ev_TYPE> watcher in F<ev.h> there is a corresponding class of
+the same name in the C<ev> namespace, with the exception of C<ev_signal>
+which is called C<ev::sig> to avoid clashes with the C<signal> macro
+defines by many implementations.
+
+All of those classes have these methods:
+
+=over 4
+
+=item ev::TYPE::TYPE (object *, object::method *)
+
+=item ev::TYPE::TYPE (object *, object::method *, struct ev_loop *)
+
+=item ev::TYPE::~TYPE
+
+The constructor takes a pointer to an object and a method pointer to
+the event handler callback to call in this class. The constructor calls
+C<ev_init> for you, which means you have to call the C<set> method
+before starting it. If you do not specify a loop then the constructor
+automatically associates the default loop with this watcher.
+
+The destructor automatically stops the watcher if it is active.
+
+=item w->set (struct ev_loop *)
+
+Associates a different C<struct ev_loop> with this watcher. You can only
+do this when the watcher is inactive (and not pending either).
+
+=item w->set ([args])
+
+Basically the same as C<ev_TYPE_set>, with the same args. Must be
+called at least once.  Unlike the C counterpart, an active watcher gets
+automatically stopped and restarted.
+
+=item w->start ()
+
+Starts the watcher. Note that there is no C<loop> argument as the
+constructor already takes the loop.
+
+=item w->stop ()
+
+Stops the watcher if it is active. Again, no C<loop> argument.
+
+=item w->again ()       C<ev::timer>, C<ev::periodic> only
+
+For C<ev::timer> and C<ev::periodic>, this invokes the corresponding
+C<ev_TYPE_again> function.
+
+=item w->sweep ()       C<ev::embed> only
+
+Invokes C<ev_embed_sweep>.
+
+=back
+
+=back
+
+Example: Define a class with an IO and idle watcher, start one of them in
+the constructor.
+
+  class myclass
+  {
+    ev_io   io;   void io_cb   (ev::io   &w, int revents);
+    ev_idle idle  void idle_cb (ev::idle &w, int revents);
+
+    myclass ();
+  }
+
+  myclass::myclass (int fd)
+  : io   (this, &myclass::io_cb),
+    idle (this, &myclass::idle_cb)
+  {
+    io.start (fd, ev::READ);
+  }
 
 =head1 AUTHOR