X-Git-Url: https://git.dogcows.com/gitweb?p=chaz%2Fyoink;a=blobdiff_plain;f=src%2FMoof%2FDispatcher.cc;h=320746485199d227a77dbb4624015969e8bc09b2;hp=fa7b3281818ca6a06a4f07753638c4509209d04a;hb=c9e20ac06383b20ceb5404c9237e319c2e90d157;hpb=c2321281bf12a7efaedde930422c7ddbc92080d4 diff --git a/src/Moof/Dispatcher.cc b/src/Moof/Dispatcher.cc index fa7b328..3207464 100644 --- a/src/Moof/Dispatcher.cc +++ b/src/Moof/Dispatcher.cc @@ -34,18 +34,17 @@ namespace Mf { -Notification::~Notification() {} - - -class Dispatcher::DispatcherImpl +class Dispatcher::Impl { -public: - DispatcherImpl() : id(1) {} + friend class Dispatcher; + + Impl() : + mId(1) {} - Dispatcher::Handler getNewHandlerID() + Dispatcher::Handler getNewHandler() { - id += 4; - return (Dispatcher::Handler)id; + mId += 2; + return (Dispatcher::Handler)mId; } typedef std::pair Callback; @@ -55,82 +54,96 @@ public: typedef std::multimap HandlerLookup; typedef HandlerLookup::iterator HandlerIter; - unsigned long long id; - CallbackLookup callbacks; - HandlerLookup handlers; + inline Handler addHandler(const std::string& message, + const Function& callback, Handler id) + { + mCallbacks.insert(std::make_pair(message, std::make_pair(id, callback))); + mHandlers.insert(std::make_pair(id, message)); + + return id; + } + + inline void removeHandler(Handler 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& message, const Notification* param) + { + std::pair + callbacks(mCallbacks.equal_range(message)); + + for (CallbackIter it = callbacks.first; it != callbacks.second; ++it) + { + Function callback = (*it).second.second; + callback(param); + } + } + + + unsigned long mId; + + CallbackLookup mCallbacks; + HandlerLookup mHandlers; }; Dispatcher::Dispatcher() : - impl_(new Dispatcher::DispatcherImpl) {} + mImpl(new Dispatcher::Impl) {} + +Dispatcher::~Dispatcher() {} -// TODO these methods are ugly +Dispatcher& Dispatcher::getInstance() +{ + static Dispatcher dispatcher; + return dispatcher; +} + Dispatcher::Handler Dispatcher::addHandler(const std::string& message, const Function& callback) { - return addHandler(message, callback, impl_->getNewHandlerID()); + return addHandler(message, callback, mImpl->getNewHandler()); } Dispatcher::Handler Dispatcher::addHandler(const std::string& message, const Function& callback, Handler id) { - std::pair - callbackPair(message, Dispatcher::DispatcherImpl::Callback(id, callback)); - - std::pair handlerPair(id, message); - - impl_->callbacks.insert(callbackPair); - impl_->handlers.insert(handlerPair); - - return id; + // pass through + return mImpl->addHandler(message, callback, id); } void Dispatcher::removeHandler(Handler id) { - std::pair - handlers(impl_->handlers.equal_range(id)); - - Dispatcher::DispatcherImpl::HandlerIter i; - for (i = handlers.first; i != handlers.second; i++) - { - Dispatcher::DispatcherImpl::CallbackIter it = impl_->callbacks.find((*i).second); - Dispatcher::DispatcherImpl::CallbackIter last = impl_->callbacks.end(); - - Dispatcher::DispatcherImpl::CallbackIter j; - for (j = it; j != last; j++) - { - if (((*j).second).first == id) - { - impl_->callbacks.erase(j); - break; - } - } - } - - impl_->handlers.erase(id); + // pass through + return mImpl->removeHandler(id); } -void Dispatcher::dispatch(const std::string& message) +void Dispatcher::dispatch(const std::string& message, const Notification* param) { - dispatch(message, Notification()); -} - -void Dispatcher::dispatch(const std::string& message, const Notification& param) -{ - std::pair - callbacks(impl_->callbacks.equal_range(message)); - - Dispatcher::DispatcherImpl::CallbackIter i; - for (i = callbacks.first; i != callbacks.second; i++) - { - Function callback = ((*i).second).second; - callback(param); - } + // pass through + mImpl->dispatch(message, param); }