/*] Copyright (c) 2009-2010, Charles McGarvey [************************** **] All rights reserved. * * vi:ts=4 sw=4 tw=75 * * Distributable under the terms and conditions of the 2-clause BSD license; * see the file COPYING for a complete text of the license. * **************************************************************************/ #include #include "Dispatch.hh" namespace Mf { class Dispatch::Impl { public: Impl() : mId(0) {} Dispatch::Handler getNewHandler() { ++mId; //return Dispatch::Handler(this, mId); Dispatch::Handler handler(this, mId); return handler; } typedef std::pair Callback; typedef std::multimap CallbackLookup; typedef CallbackLookup::iterator CallbackIter; typedef std::multimap HandlerLookup; typedef HandlerLookup::iterator HandlerIter; inline Handler addHandler(const std::string& event, const Function& callback, Handler handler) { mCallbacks.insert(std::make_pair(event, std::make_pair(handler.getId(), callback))); mHandlers.insert(std::make_pair(handler.getId(), event)); return handler; } inline void removeHandler(unsigned id) { std::pair matching(mHandlers.equal_range(id)); for (HandlerIter it = matching.first; it != matching.second; ++it) { CallbackIter first = mCallbacks.find((*it).second); CallbackIter last = mCallbacks.end(); for (CallbackIter jt = first; jt != last; ++jt) { if ((*jt).second.first == id) { mCallbacks.erase(jt); break; } } } mHandlers.erase(id); } void dispatch(const std::string& event, const Message* message) { std::pair callbacks(mCallbacks.equal_range(event)); for (CallbackIter it = callbacks.first; it != callbacks.second; ++it) { Function callback = (*it).second.second; callback(message); } } unsigned mId; CallbackLookup mCallbacks; HandlerLookup mHandlers; }; Dispatch::Handler::~Handler() { if (mId) { mDispatch->removeHandler(mId); } } Dispatch::Dispatch() : mImpl(new Dispatch::Impl) {} Dispatch::Handler Dispatch::addHandler(const std::string& event, const Function& callback) { return addHandler(event, callback, mImpl->getNewHandler()); } Dispatch::Handler Dispatch::addHandler(const std::string& event, const Function& callback, Handler handler) { // pass through return mImpl->addHandler(event, callback, handler); } void Dispatch::removeHandler(unsigned id) { // pass through return mImpl->removeHandler(id); } void Dispatch::dispatch(const std::string& event, const Message* message) { // pass through mImpl->dispatch(event, message); } } // namespace Mf