From 7f61bc3d979ef53b867172664694f8fcf9e5bdd0 Mon Sep 17 00:00:00 2001
From: root
Date: Fri, 7 Dec 2007 20:13:08 +0000
Subject: document c++ callbacks!
---
ev++.h | 4 +--
ev.3 | 97 ++++++++++++++++++++++++++++++++++++++++++++++++++---------------
ev.html | 81 +++++++++++++++++++++++++++++++++++++++++-------------
ev.pod | 87 +++++++++++++++++++++++++++++++++++++++++++++-------------
4 files changed, 207 insertions(+), 62 deletions(-)
diff --git a/ev++.h b/ev++.h
index d7b4502..fea0ac1 100644
--- a/ev++.h
+++ b/ev++.h
@@ -56,10 +56,10 @@ namespace ev {
(obj->*method) (*self, revents);
}
- template
+ template
void set ()
{
- set_ (0, function_thunk);
+ set_ (data, function_thunk);
}
template
diff --git a/ev.3 b/ev.3
index dad4e52..4f00179 100644
--- a/ev.3
+++ b/ev.3
@@ -1896,12 +1896,21 @@ To use it,
\& #include
.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.
+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. It should support all the same embedding
+options as \fIev.h\fR, most notably \f(CW\*(C`EV_MULTIPLICITY\*(C'\fR.
+.PP
+Care has been taken to keep the overhead low. The only data member added
+to the C\-style watchers is the event loop the watcher is associated with
+(or no additional members at all if you disable \f(CW\*(C`EV_MULTIPLICITY\*(C'\fR when
+embedding libev).
+.PP
+Currently, functions and static and non-static member functions can be
+used as callbacks. Other types should be easy to add as long as they only
+need one additional pointer for context. If you need support for other
+types of functors please contact the author (preferably after implementing
+it).
.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
@@ -1923,21 +1932,61 @@ 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 *)"
+.IP "ev::TYPE::TYPE ()" 4
+.IX Item "ev::TYPE::TYPE ()"
.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 (struct ev_loop *)" 4
+.IX Item "ev::TYPE::TYPE (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.
+The constructor (optionally) takes an event loop to associate the watcher
+with. If it is omitted, it will use \f(CW\*(C`EV_DEFAULT\*(C'\fR.
+.Sp
+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.
+.Sp
+It will not set a callback, however: You have to call the templated \f(CW\*(C`set\*(C'\fR
+method to set a callback before you can start the watcher.
+.Sp
+(The reason why you have to use a method is a limitation in \*(C+ which does
+not allow explicit template arguments for constructors).
.Sp
The destructor automatically stops the watcher if it is active.
+.IP "w\->set (object *)" 4
+.IX Item "w->set (object *)"
+This method sets the callback method to call. The method has to have a
+signature of \f(CW\*(C`void (*)(ev_TYPE &, int)\*(C'\fR, it receives the watcher as
+first argument and the \f(CW\*(C`revents\*(C'\fR as second. The object must be given as
+parameter and is stored in the \f(CW\*(C`data\*(C'\fR member of the watcher.
+.Sp
+This method synthesizes efficient thunking code to call your method from
+the C callback that libev requires. If your compiler can inline your
+callback (i.e. it is visible to it at the place of the \f(CW\*(C`set\*(C'\fR call and
+your compiler is good :), then the method will be fully inlined into the
+thunking function, making it as fast as a direct C callback.
+.Sp
+Example: simple class declaration and watcher initialisation
+.Sp
+.Vb 4
+\& struct myclass
+\& {
+\& void io_cb (ev::io &w, int revents) { }
+\& }
+.Ve
+.Sp
+.Vb 3
+\& myclass obj;
+\& ev::io iow;
+\& iow.set (&obj);
+.Ve
+.IP "w\->set (void (*function)(watcher &w, int), void *data = 0)" 4
+.IX Item "w->set (void (*function)(watcher &w, int), void *data = 0)"
+Also sets a callback, but uses a static method or plain function as
+callback. The optional \f(CW\*(C`data\*(C'\fR argument will be stored in the watcher's
+\&\f(CW\*(C`data\*(C'\fR member and is free for you to use.
+.Sp
+See the method\-\f(CW\*(C`set\*(C'\fR above for more details.
.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
@@ -1945,12 +1994,13 @@ 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.
+called at least once. Unlike the C counterpart, an active watcher gets
+automatically stopped and restarted when reconfiguring it with this
+method.
.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.
+Starts the watcher. Note that there is no \f(CW\*(C`loop\*(C'\fR argument, as the
+constructor already stores the event 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.
@@ -1986,11 +2036,14 @@ the constructor.
\& }
.Ve
.PP
-.Vb 6
+.Vb 4
\& myclass::myclass (int fd)
-\& : io (this, &myclass::io_cb),
-\& idle (this, &myclass::idle_cb)
\& {
+\& io .set (this);
+\& idle.set (this);
+.Ve
+.PP
+.Vb 2
\& io.start (fd, ev::READ);
\& }
.Ve
diff --git a/ev.html b/ev.html
index 63ddf3b..efd79da 100644
--- a/ev.html
+++ b/ev.html
@@ -6,7 +6,7 @@
-
+
@@ -1738,11 +1738,19 @@ the callback model to a model using method callbacks on objects.
#include <ev++.h>
-
(it is not installed by default). This automatically includes ev.h
-and puts all of its definitions (many of them macros) into the global
-namespace. All C++ specific things are put into the ev namespace.
-
It should support all the same embedding options as ev.h, most notably
-EV_MULTIPLICITY.
+
This automatically includes ev.h and puts all of its definitions (many
+of them macros) into the global namespace. All C++ specific things are
+put into the ev namespace. It should support all the same embedding
+options as ev.h, most notably EV_MULTIPLICITY.
+
Care has been taken to keep the overhead low. The only data member added
+to the C-style watchers is the event loop the watcher is associated with
+(or no additional members at all if you disable EV_MULTIPLICITY when
+embedding libev).
+
Currently, functions and static and non-static member functions can be
+used as callbacks. Other types should be easy to add as long as they only
+need one additional pointer for context. If you need support for other
+types of functors please contact the author (preferably after implementing
+it).
Here is a list of things available in the ev namespace:
ev::READ, ev::WRITE etc.
@@ -1763,17 +1771,50 @@ defines by many implementations.
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
-ev_init for you, which means you have to call the set method
-before starting it. If you do not specify a loop then the constructor
-automatically associates the default loop with this watcher.
+
The constructor (optionally) takes an event loop to associate the watcher
+with. If it is omitted, it will use EV_DEFAULT.
+
The constructor calls ev_init for you, which means you have to call the
+set method before starting it.
+
It will not set a callback, however: You have to call the templated set
+method to set a callback before you can start the watcher.
+
(The reason why you have to use a method is a limitation in C++ which does
+not allow explicit template arguments for constructors).
The destructor automatically stops the watcher if it is active.
+
w->set<class, &class::method> (object *)
+
+
This method sets the callback method to call. The method has to have a
+signature of void (*)(ev_TYPE &, int), it receives the watcher as
+first argument and the revents as second. The object must be given as
+parameter and is stored in the data member of the watcher.
+
This method synthesizes efficient thunking code to call your method from
+the C callback that libev requires. If your compiler can inline your
+callback (i.e. it is visible to it at the place of the set call and
+your compiler is good :), then the method will be fully inlined into the
+thunking function, making it as fast as a direct C callback.
+
Example: simple class declaration and watcher initialisation
Also sets a callback, but uses a static method or plain function as
+callback. The optional data argument will be stored in the watcher's
+data member and is free for you to use.
+
See the method-set above for more details.
+
w->set (struct ev_loop *)
Associates a different struct ev_loop with this watcher. You can only
@@ -1782,13 +1823,14 @@ do this when the watcher is inactive (and not pending either).
w->set ([args])
Basically the same as 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.
+called at least once. Unlike the C counterpart, an active watcher gets
+automatically stopped and restarted when reconfiguring it with this
+method.
w->start ()
-
Starts the watcher. Note that there is no loop argument as the
-constructor already takes the loop.
+
Starts the watcher. Note that there is no loop argument, as the
+constructor already stores the event loop.
w->stop ()
@@ -1822,9 +1864,10 @@ the constructor.
}
myclass::myclass (int fd)
- : io (this, &myclass::io_cb),
- idle (this, &myclass::idle_cb)
{
+ io .set <myclass, &myclass::io_cb > (this);
+ idle.set <myclass, &myclass::idle_cb> (this);
+
io.start (fd, ev::READ);
}
diff --git a/ev.pod b/ev.pod
index 14999b3..c02aca2 100644
--- a/ev.pod
+++ b/ev.pod
@@ -1746,12 +1746,21 @@ To use it,
#include
-(it is not installed by default). This automatically includes F
-and puts all of its definitions (many of them macros) into the global
-namespace. All C++ specific things are put into the C namespace.
-
-It should support all the same embedding options as F, most notably
-C.
+This automatically includes F and puts all of its definitions (many
+of them macros) into the global namespace. All C++ specific things are
+put into the C namespace. It should support all the same embedding
+options as F, most notably C.
+
+Care has been taken to keep the overhead low. The only data member added
+to the C-style watchers is the event loop the watcher is associated with
+(or no additional members at all if you disable C when
+embedding libev).
+
+Currently, functions and static and non-static member functions can be
+used as callbacks. Other types should be easy to add as long as they only
+need one additional pointer for context. If you need support for other
+types of functors please contact the author (preferably after implementing
+it).
Here is a list of things available in the C namespace:
@@ -1777,20 +1786,58 @@ All of those classes have these methods:
=over 4
-=item ev::TYPE::TYPE (object *, object::method *)
+=item ev::TYPE::TYPE ()
-=item ev::TYPE::TYPE (object *, object::method *, struct ev_loop *)
+=item ev::TYPE::TYPE (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 for you, which means you have to call the C method
-before starting it. If you do not specify a loop then the constructor
-automatically associates the default loop with this watcher.
+The constructor (optionally) takes an event loop to associate the watcher
+with. If it is omitted, it will use C.
+
+The constructor calls C for you, which means you have to call the
+C method before starting it.
+
+It will not set a callback, however: You have to call the templated C
+method to set a callback before you can start the watcher.
+
+(The reason why you have to use a method is a limitation in C++ which does
+not allow explicit template arguments for constructors).
The destructor automatically stops the watcher if it is active.
+=item w->set (object *)
+
+This method sets the callback method to call. The method has to have a
+signature of C, it receives the watcher as
+first argument and the C as second. The object must be given as
+parameter and is stored in the C member of the watcher.
+
+This method synthesizes efficient thunking code to call your method from
+the C callback that libev requires. If your compiler can inline your
+callback (i.e. it is visible to it at the place of the C call and
+your compiler is good :), then the method will be fully inlined into the
+thunking function, making it as fast as a direct C callback.
+
+Example: simple class declaration and watcher initialisation
+
+ struct myclass
+ {
+ void io_cb (ev::io &w, int revents) { }
+ }
+
+ myclass obj;
+ ev::io iow;
+ iow.set (&obj);
+
+=item w->set (void (*function)(watcher &w, int), void *data = 0)
+
+Also sets a callback, but uses a static method or plain function as
+callback. The optional C argument will be stored in the watcher's
+C member and is free for you to use.
+
+See the method-C above for more details.
+
=item w->set (struct ev_loop *)
Associates a different C with this watcher. You can only
@@ -1799,13 +1846,14 @@ do this when the watcher is inactive (and not pending either).
=item w->set ([args])
Basically the same as C, with the same args. Must be
-called at least once. Unlike the C counterpart, an active watcher gets
-automatically stopped and restarted.
+called at least once. Unlike the C counterpart, an active watcher gets
+automatically stopped and restarted when reconfiguring it with this
+method.
=item w->start ()
-Starts the watcher. Note that there is no C argument as the
-constructor already takes the loop.
+Starts the watcher. Note that there is no C argument, as the
+constructor already stores the event loop.
=item w->stop ()
@@ -1840,9 +1888,10 @@ the constructor.
}
myclass::myclass (int fd)
- : io (this, &myclass::io_cb),
- idle (this, &myclass::idle_cb)
{
+ io .set (this);
+ idle.set (this);
+
io.start (fd, ev::READ);
}
--
cgit v1.2.3