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.

All of those classes have these methods:

-
ev::TYPE::TYPE (object *, object::method *)
-
ev::TYPE::TYPE (object *, object::method *, struct ev_loop *)
+
ev::TYPE::TYPE ()
+
ev::TYPE::TYPE (struct ev_loop *)
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 -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

+
  struct myclass
+  {
+    void io_cb (ev::io &w, int revents) { }
+  }
+
+  myclass obj;
+  ev::io iow;
+  iow.set <myclass, &myclass::io_cb> (&obj);
+
+
+
+
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 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