CppCallback -- an open source library for C++ callback, signal, slot, delegate, observer patten, event system
Note: Though you can still download the callback library here, it should be out of date.
Now CppCallback is released as part of cpgf library, please go to cgpf library main page to download the cpgf library. It's guaranteed up to date.
CppCallback won't be maintained as an independent library.
Tutorial (a sample code with detailed comment)
Update on 2011, Jul. 3, changes:
- Fix a bug that compiles error "invalid value-initialization of reference types" in GCC when the callback function return reference. Now when calling an empty callback that return a reference, a reference to NULL address will be returned.
- Now callback will assert false when trying to pass a callback with member function but the object is NULL to another callback.
CppCallback is a callback system for C++. It's written using heavily C++ templates and preprocess macros.
With this library, C++ programmers can easily do:
- Define a callback object (also called slot in Qt, boost::Signals and libsigc++) to hold any functions and functor object with any parameters and return type.
- Pass and store the callback object anywhere for any later invoke.
- Define a callback list (also called signal in Qt, boost::Signals and libsigc++) to hold any number of callbacks together.
- Call multiple callbacks at once via callback list.
Features:
- Pure C++ template code. No extra preprocessor or meta object compiler is required.
- Support arbitrary number of parameters.
- Support any type of functions. Static (global) function, member function (virtual, const, volatile, const volatile), functor object ( () operator).
- Support any calling conventions. cdecl, stdcall, fastcall, etc.
- Comparable. Callbacks can be compared via == operator.
- Auto disconnection management. A connection can be auto disconnected when host object is destroyed. Use GCallbackTrackable. Even better, your object doesn't need to inherit from GCallbackTrackable. This feature was not tested thoroughly.
- Customized connection type to make any extension. For instance, GCallbackExtendedConnection supports tag and auto remove features.
- Fast and compact memory usage.
- Better handling empty callback (no function is bound). Unlike boost::function and boost::signal (which either forbid empty signal or throw exception when calling an empty function), also unlike libsigc++ (silent for empty slot but cause compile error "invalid value-initialization of reference types" when the function type returns reference in GCC), CppCallback keeps silent on empty callback and no compile error.
- Same idea as signals and slots. GCallback is the slot and GCallbackList is the signal.
- Quite easy use of syntax. Most time you can forget the template <> and use normal function address as the callback (implicitly converting).
- Can work with const, volatile and const volatile member functions.
- Can be invoked recursively.
- Disconnect/delete immediately, no lazy deletion.
- Can be used cross exe and dll, or cross different modules.
- A number of auxiliary functions to ease the creating of callbacks (makeCallback and makeCallbackN).
- Easy to use override functions with different count of parameters (use makeCallbackN).
- Header only. No library or source code to link with. Just include and start using it.
- Not thread safe for now.
- Test compiled on MS VC 2008 Express, GCC 4.4.0 and GCC 4.5.2.
Here is a piece of code that the callback looks like,
GCallback<void (int)> cb = someObj;
cb.invoke(66);
TestObject test;
GCallbackList<int (const string &)> cbList;
cbList.add(SampleFunctor()); // functor object
cbList.add(&test, &TestObject::objectFunction); // a member function
cbList.add(&TestObject::staticFunction); // static class function
cbList.add(&globalFunction); // global function
cbList.dispatch("dispatch"); // call all callbacks
How may the callback library help your development?
- It helps to loose couple your code. A module may only emit certain events (callbacks) and doesn't need to care about who will response them. Another module may only response to certain events without caring who emits them.
- It helps to implement Observer pattern.
- It's quite easy to develop an event system basing on the callback library.
- Raw C style function pointer callbacks can be replaced with the library and get benefits of type safe.
This library is not to compete with boost::Signals and libsigc++.
The latter two libraries are quite sophisticated and well tested, while CppCallback is new and may have bugs.
And CppCallback can work together with boost and libsigc++ too. You can use boost bind or libsigc++ adaptors as functor object in CppCallback.
License:
Apache License 2.0
http://www.apache.org/licenses/LICENSE-2.0.html
It's open source freeware.
However, if you need a different license, just contact the original author, with the information that: who are you, how do you want to use of the code, what license would you like, and then I will decide to or not to give you a suitable license.
Changes log:
Update on 2011, May. 4, changes:
- Fixed a bug that cause arbitrary callback can be assigned to different type of callback. Just removed a wrong constructor from GCallback.
Update on 2011, Apr. 9, changes:
- Added plain callback to support using C++ member functions and functor objects as C callback.
Update on 2011, Apr. 4, changes:
- Optimized to eliminate unnecessary functor copies.
- Optimized the performance a little bit.
- A benchmark is created to compare CppCallback, ligsigc++, and boost signal.
- Fixed bugs about constant correctness.
Update on 2011, Mar. 12, changes:
- Optimized function parameter to avoid unnecessary object copy.
- Cleared warnings when warning setting is strict (-w4 on VC, -Wall and -Wextra on GCC).
Update on 2011, Mar. 6, changes:
- Replaced previous mutiple template parameters (result and arguments type) with current single parameter (signature).
- Support customized connection.
- Optimized a little bit.
-
Bug fix.
Posts: 3
Reply #3 on : Sat July 30, 2011, 17:29:17
Posts: 3
Reply #2 on : Tue July 12, 2011, 05:48:19
Posts: 3
Reply #1 on : Tue July 12, 2011, 05:22:32
Write a comment
- Required fields are marked with *
- Security Code is case sensitive, 'A' is different with 'a'.
Posts: 1
Reply #4 on : Sun July 31, 2011, 01:47:54