RSB  0.19.0
ScopeDispatcher.h
Go to the documentation of this file.
1 /* ============================================================
2  *
3  * This file is part of the RSB project
4  *
5  * Copyright (C) 2018 Jan Moringen <jmoringe@techfak.uni-bielefeld.de>
6  *
7  * This file may be licensed under the terms of the
8  * GNU Lesser General Public License Version 3 (the ``LGPL''),
9  * or (at your option) any later version.
10  *
11  * Software distributed under the License is distributed
12  * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
13  * express or implied. See the LGPL for the specific language
14  * governing rights and limitations.
15  *
16  * You should have received a copy of the LGPL along with this
17  * program. If not, go to http://www.gnu.org/licenses/lgpl.html
18  * or write to the Free Software Foundation, Inc.,
19  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  *
21  * The development of this software was supported by:
22  * CoR-Lab, Research Institute for Cognition and Robotics
23  * Bielefeld University
24  *
25  * ============================================================ */
26 
27 #pragma once
28 
29 #include <vector>
30 #include <list>
31 #include <map>
32 #include <stdexcept>
33 
34 #include <boost/shared_ptr.hpp>
35 #include <boost/function.hpp>
36 
37 #include "../../rsb/Scope.h"
38 
39 namespace rsb {
40 namespace eventprocessing {
41 
50 template <typename T>
52 public:
59  bool empty() const {
60  return this->sinks.empty();
61  }
62 
68  size_t size() const {
69  return this->sinks.size();
70  }
71 
79  void addSink(const Scope& scope, const T& sink) {
80  this->sinks[scope].push_back(sink);
81  }
82 
90  void removeSink(const Scope& scope, const T& sink) {
91  typename SinkMap::iterator it = this->sinks.find(scope);
92  if (it == this->sinks.end()) {
93  throw std::logic_error("Should not happen");
94  }
95  SinkList& sinks = it->second;
96  sinks.remove(sink);
97  if (sinks.empty()) {
98  this->sinks.erase(it);
99  }
100  }
101 
112  void mapSinks(const Scope& scope,
113  boost::function<void (const T&)> function) const {
114  std::vector<Scope> scopes = scope.superScopes(true);
115  for (std::vector<Scope>::const_iterator it = scopes.begin(); it != scopes.end(); ++it) {
116  typename SinkMap::const_iterator it_ = this->sinks.find(*it);
117  if (it_ != this->sinks.end()) {
118  const SinkList& sinks = it_->second;
119 
120  for (typename SinkList::const_iterator it__ = sinks.begin();
121  it__ != sinks.end(); ++it__) {
122  function(*it__);
123  }
124  }
125  }
126  }
127 
134  void mapAllSinks(boost::function<void (const T&)> function) const {
135  for (typename SinkMap::const_iterator it = this->sinks.begin();
136  it != this->sinks.end(); ++it) {
137  const SinkList& sinks = it->second;
138  for (typename SinkList::const_iterator it_ = sinks.begin();
139  it_ != sinks.end(); ++it_) {
140  function(*it_);
141  }
142  }
143  }
144 protected:
145  typedef std::list<T> SinkList;
146  typedef std::map<Scope, SinkList> SinkMap;
147 
148  SinkMap sinks;
149 };
150 
156 template <typename T>
157 class WeakScopeDispatcher : public ScopeDispatcher< boost::weak_ptr<T> > {
158 public:
159  void removeSink(const Scope& scope, const T* sink) {
160  typename WeakScopeDispatcher::SinkMap::iterator it = this->sinks.find(scope);
161  if (it == this->sinks.end()) {
162  throw std::logic_error("Should not happen");
163  }
164  typename WeakScopeDispatcher::SinkList& sinks = it->second;
165  for (typename WeakScopeDispatcher::SinkList::iterator it
166  = sinks.begin(); it != sinks.end();) {
167  boost::shared_ptr<T> pointer = it->lock();
168  // If the weak pointer is dangling, clean it up.
169  if (!pointer) {
170  it = sinks.erase(it);
171  } else if (pointer.get() == sink) {
172  it = sinks.erase(it);
173  } else {
174  ++it;
175  }
176  }
177  if (sinks.empty()) {
178  this->sinks.erase(it);
179  }
180  }
181 
182  void mapSinks(const Scope& scope,
183  boost::function<void (T&)> function) const {
184  std::vector<Scope> scopes = scope.superScopes(true);
185  for (std::vector<Scope>::const_iterator it = scopes.begin(); it != scopes.end(); ++it) {
186  typename WeakScopeDispatcher::SinkMap::const_iterator it_ = this->sinks.find(*it);
187  if (it_ != this->sinks.end()) {
188  const typename WeakScopeDispatcher::SinkList& sinks = it_->second;
189 
190  for (typename WeakScopeDispatcher::SinkList::const_iterator it__
191  = sinks.begin(); it__ != sinks.end(); ++it__) {
192  boost::shared_ptr<T> pointer = it__->lock();
193  if (pointer) {
194  function(*pointer);
195  }
196  }
197  }
198  }
199  }
200 
201  void mapAllSinks(boost::function<void (T&)> function) const {
202  for (typename WeakScopeDispatcher::SinkMap::const_iterator it
203  = this->sinks.begin(); it != this->sinks.end(); ++it) {
204  const typename WeakScopeDispatcher::SinkList& sinks = it->second;
205  for (typename WeakScopeDispatcher::SinkList::const_iterator it_
206  = sinks.begin(); it_ != sinks.end(); ++it_) {
207  boost::shared_ptr<T> pointer = it_->lock();
208  if (pointer) {
209  function(*pointer);
210  }
211  }
212  }
213  }
214 };
215 
216 }
217 }
void removeSink(const Scope &scope, const T &sink)
Removes sink from the list of sinks associated to scope.
A variant of ScopeDispatcher that references sinks weakly.
void mapAllSinks(boost::function< void(const T &)> function) const
Calls function for each sink in the dispatcher.
bool empty() const
Indicates whether there are scopes with associated sinks.
Maps scopes to sets of sinks of type T.
void mapSinks(const Scope &scope, boost::function< void(const T &)> function) const
Calls function for each sink associated to scope-scopes of scope.
size_t size() const
Returns number of scopes with associated sinks.
void addSink(const Scope &scope, const T &sink)
Associates sink with scope.
std::map< Scope, SinkList > SinkMap
void mapSinks(const Scope &scope, boost::function< void(T &)> function) const
std::vector< Scope > superScopes(const bool &includeSelf=false) const
Generates all super scopes of this scope including the root scope "/".
Definition: Scope.cpp:208
Scope is a descriptor for a hierarchical channel of the unified bus.
Definition: Scope.h:46
void removeSink(const Scope &scope, const T *sink)
void mapAllSinks(boost::function< void(T &)> function) const