From: Leandro Lucarella Date: Wed, 21 Mar 2007 21:31:43 +0000 (+0000) Subject: Add mem_cb functor to use an arbitrary memeber function as an event handler. X-Git-Tag: 0.3~6 X-Git-Url: https://git.llucax.com/software/eventxx.git/commitdiff_plain/c584f2e4d45ee21a00dae09f4be54144eafef7ac?ds=sidebyside Add mem_cb functor to use an arbitrary memeber function as an event handler. --- diff --git a/eventxx b/eventxx index 6287659..94ee113 100644 --- a/eventxx +++ b/eventxx @@ -180,6 +180,12 @@ * callbacks. */ +/** @example wrapped-functor-way.cpp + * + * This is a simple example illustrating the usage with an arbitrary member + * function as an event handler callbacks. + */ + /** @example mixed-way.cpp * * This is a simple example illustrating the usage with a mix of C-like callbacks @@ -373,6 +379,9 @@ struct time: ::timeval * function objects (see eventxx::event, eventxx::timer and eventxx::signal * templates). The former are just typedef'ed specialization of the later. * + * A member function wrapper functor (eventxx::mem_cb) is also included, + * so you can use any member function (method) as an event handler. + * * All events derive from a plain class (not template) eventxx::basic_event, one * of the main utilities of it (besides containing common code ;) is to be used * in STL containers. @@ -689,6 +698,38 @@ typedef eventxx::timer< ccallback_type > ctimer; /// Shortcut to C-style signal handler. typedef eventxx::signal< ccallback_type > csignal; +/** + * Helper functor to use an arbitrary member function as an event handler. + * + * With this wrapper, you can use any object method, which accepts the right + * parameters (int, short) and returns void, as an event handler. This way you + * don't have to overload the operator() which can be confusing depending on the + * context. + * + * You can see an usage example in the Examples Section. + */ +template < typename O, typename M > +struct mem_cb +{ + /** + * Member function callback constructor. + * + * It expects to receive a class as the first parameter (O), and a + * member function (of that class O) as the second parameter. + * + * When this instance is called with fd and ev as function arguments, + * object.method(fd, ev) will be called. + * + * @param object Object to be used. + * @param method Method to be called. + */ + mem_cb(O& object, M method) throw(): + _object(object), _method(method) {} + void operator() (int fd, short ev) { (_object.*_method)(fd, ev); } + protected: + O& _object; + M _method; +}; // struct mem_cb //@} @@ -957,8 +998,7 @@ struct dispatcher }; // struct dispatcher - -} // namespace event +} // namespace eventxx #endif // _EVENTXX_HPP_ diff --git a/test/Makefile b/test/Makefile index 4beddbf..477a591 100644 --- a/test/Makefile +++ b/test/Makefile @@ -6,7 +6,7 @@ CXXFLAGS=-I.. -g -Wall LDFLAGS=-levent targets=bench test-eof test-time test-weof trivial c-way functor-way \ - prio-test mixed-way + wrapped-functor-way prio-test mixed-way all: $(targets) diff --git a/test/wrapped-functor-way.cpp b/test/wrapped-functor-way.cpp new file mode 100644 index 0000000..9664b8a --- /dev/null +++ b/test/wrapped-functor-way.cpp @@ -0,0 +1,36 @@ +#include +#include +#include + +using eventxx::dispatcher; + +struct handler +{ + dispatcher& d; + int i; + handler(dispatcher& d): d(d), i(0) {} + void handle_event(int signum, short event) + { + std::cout << ++i << " interrupts, "; + if (i < 5) std::cout << "keep going...\n"; + else + { + std::cout << "done!\n"; + d.exit(); + } + } +}; + +typedef eventxx::mem_cb< handler, void (handler::*)(int, short) > cb_type; + +int main() +{ + dispatcher d; + handler h(d); + cb_type cb(h, &handler::handle_event); + eventxx::signal< cb_type > e(SIGINT, cb); + d.add(e); + d.dispatch(); + return 0; +} +