X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=src%2Fmoof%2Fdispatcher.cc;fp=src%2Fmoof%2Fdispatcher.cc;h=96babe48194eb1d91243ccad2fa412cf10207e72;hb=831f04d4bc19a390415ac0bbac4331c7a65509bc;hp=0000000000000000000000000000000000000000;hpb=299af4f2047e767e5d79501c26444473bda64c64;p=chaz%2Fyoink diff --git a/src/moof/dispatcher.cc b/src/moof/dispatcher.cc new file mode 100644 index 0000000..96babe4 --- /dev/null +++ b/src/moof/dispatcher.cc @@ -0,0 +1,150 @@ + +/*] 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 "dispatcher.hh" + + +namespace moof { + + +class dispatcher::impl +{ +public: + + impl(dispatcher* dispatcher) : + dispatcher_(dispatcher), + id_(0) {} + + dispatcher::handle getNewHandle() + { + ++id_; + dispatcher::handle handle(dispatcher_->impl_, id_); + return handle; + } + + typedef std::pair callback; + typedef std::multimap callback_lookup; + typedef callback_lookup::iterator callback_it; + + typedef std::multimap handle_lookup; + typedef handle_lookup::iterator handle_it; + + + handle add_target(const std::string& event, + const function& callback, + handle handle) + { + callbacks_.insert(std::make_pair(event, std::make_pair(handle.id(), + callback))); + handles_.insert(std::make_pair(handle.id(), event)); + + return handle; + } + + void remove_target(unsigned id) + { + std::pair matching(handles_.equal_range(id)); + + for (handle_it it = matching.first; it != matching.second; ++it) + { + callback_it first = callbacks_.find((*it).second); + callback_it last = callbacks_.end(); + + for (callback_it jt = first; jt != last; ++jt) + { + if ((*jt).second.first == id) + { + callbacks_.erase(jt); + break; + } + } + } + + handles_.erase(id); + } + + void dispatch(const std::string& event) + { + std::pair + callbacks(callbacks_.equal_range(event)); + + for (callback_it it = callbacks.first; it != callbacks.second; ++it) + { + function callback = (*it).second.second; + callback(); + } + } + + + dispatcher* dispatcher_; + + unsigned id_; + + callback_lookup callbacks_; + handle_lookup handles_; +}; + + +void dispatcher::handle::clear() +{ + boost::shared_ptr dispatcher; + if (id_ && (dispatcher = dispatcher_.lock())) + { + dispatcher->remove_target(id_); + id_ = 0; + } +} + + +dispatcher::dispatcher() : + impl_(new dispatcher::impl(this)) {} + + +dispatcher::handle dispatcher::add_target(const std::string& event, + const function& callback) +{ + return add_target(event, callback, impl_->getNewHandle()); +} + +dispatcher::handle dispatcher::add_target(const std::string& event, + const function& callback, + handle handle) +{ + // pass through + return impl_->add_target(event, callback, handle); +} + + +void dispatcher::remove_target(unsigned id) +{ + // pass through + return impl_->remove_target(id); +} + + +void dispatcher::dispatch(const std::string& event) +{ + // pass through + impl_->dispatch(event); +} + + +dispatcher& dispatcher::global() +{ + static dispatcher dispatcher; + return dispatcher; +} + + +} // namespace moof +