c++ - Two way communication with (static) library -
i writing program, bulk of platform independent code compiled static library. writing program using specific platform apis linked static library. calling functions in library actual program easy, unsure of best way (most efficient / cleanest implementation) of communicating program library.
i have looked signals / slots method worried performance (ideally draw calls go through this). otherwise other method can think of form of callbacks using functors implementation, should quicker best design?
edit: main aims / requirements performance , implementable. library written in c++ , uses boost boost signals possibility, performance acceptable?
here options (roughly) flexible least:
signals & slots
several signals , slots implementations listed here (notably boost.signal). these useful implement observer design pattern more 1 object interested in receiving notifications.
boost.function
you can register boost::function
callback. boost::function
wrapper around callable entity: free function, static function, member function, or function object. wrap member function, use boost::bind
shown in example. usage example:
#include <iostream> #include <boost/function.hpp> #include <boost/bind.hpp> typedef boost::function<void (void)> mousecallback; class mouse { public: void registercallback(mousecallback callback) {callback_ = callback;} void notifyclicked() {if (callback_) callback_();} private: mousecallback callback_; }; class foo { public: void mouseclicked() {std::cout << "mouse clicked!";} }; int main() { mouse mouse; foo foo; mouse.registercallback(boost::bind(&foo::mouseclicked, &foo)); mouse.notifyclicked(); }
fast delegate
there delegate implementation, called fastdelegate faster boost::function
. uses "ugly hack" not supported c++ standard, supported practically compilers.
there the impossibly fast c++ delegates supported standard, not compilers.
"listener" interfaces (abstract classes)
as c-smile suggested, can register pointer object derived callback interface (abstract class). traditional java way of doing callbacks. example:
class mouseinputlistener { public: virtual void mouseclicked() = 0; virtual void mousereleased() = 0; }; class mouse { public: mouse() : listener_(0) {} void registerlistener(mouseinputlistener* listener) {listener_ = listener;} void notifyclicked() {if (listener_) listener_->mouseclicked();} void notifyreleased() {if (listener_) listener_->mousereleased();} private: mouseinputlistener* listener_; }; class foo : public mouseinputlistener { public: virtual void mouseclicked() {cout << "mouse clicked!";} virtual void mousereleased() {cout << "mouse released!";} };
c-style callbacks
you register pointer callback free function, plus additional "context" void pointer. in callback function, cast void*
object type handle event, , invoke proper method. example:
typedef void (*mousecallback)(void* context); // callback function pointer type class mouse { public: mouse() : callback_(0), context_(0) {} void registercallback(mousecallback callback, void* context = 0) {callback_ = callback; context_ = context;} void notifyclicked() {if (callback_) callback_(context_);} private: mousecallback callback_; void* context_; }; class foo { public: void mouseclicked() {cout << "mouse clicked!";} static void callback(void* context) {static_cast<foo*>(context)->mouseclicked();} }; int main() { mouse mouse; foo foo; mouse.registercallback(&foo::callback, &foo); mouse.notifyclicked(); }
benchmarks
i have found performance benchmarks:
they should give idea of callback mechanism appropriate.
as can see numbers, have invoking boost signals 10,000 100,000 of times per second before performance becomes issue.
my recommendation
if callbacks not invoked @ blazingly high rate (10-100 thousand times per second), use boost::signal
maximum flexibility , automatic connection lifetime management.
if callbacks invoked @ extremely high rate, start boost::function
maximum flexibility , portability. that's still slow, go fastdelegate, or c-style callbacks.
Comments
Post a Comment