/*] 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