]> Dogcows Code - chaz/yoink/blobdiff - src/moof/dispatcher.cc
the massive refactoring effort
[chaz/yoink] / src / moof / dispatcher.cc
diff --git a/src/moof/dispatcher.cc b/src/moof/dispatcher.cc
new file mode 100644 (file)
index 0000000..96babe4
--- /dev/null
@@ -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 <map>
+
+#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<unsigned,dispatcher::function>        callback;
+       typedef std::multimap<std::string,callback>                     callback_lookup;
+       typedef callback_lookup::iterator                                       callback_it;
+
+       typedef std::multimap<unsigned,std::string>                     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<handle_it,handle_it> 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<callback_it,callback_it>
+                       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<impl> 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
+
This page took 0.024719 seconds and 4 git commands to generate.