MIRA
FrameworkGraph.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2012 by
3  * MetraLabs GmbH (MLAB), GERMANY
4  * and
5  * Neuroinformatics and Cognitive Robotics Labs (NICR) at TU Ilmenau, GERMANY
6  * All rights reserved.
7  *
8  * Contact: info@mira-project.org
9  *
10  * Commercial Usage:
11  * Licensees holding valid commercial licenses may use this file in
12  * accordance with the commercial license agreement provided with the
13  * software or, alternatively, in accordance with the terms contained in
14  * a written agreement between you and MLAB or NICR.
15  *
16  * GNU General Public License Usage:
17  * Alternatively, this file may be used under the terms of the GNU
18  * General Public License version 3.0 as published by the Free Software
19  * Foundation and appearing in the file LICENSE.GPL3 included in the
20  * packaging of this file. Please review the following information to
21  * ensure the GNU General Public License version 3.0 requirements will be
22  * met: http://www.gnu.org/copyleft/gpl.html.
23  * Alternatively you may (at your option) use any later version of the GNU
24  * General Public License if such license has been publicly approved by
25  * MLAB and NICR (or its successors, if any).
26  *
27  * IN NO EVENT SHALL "MLAB" OR "NICR" BE LIABLE TO ANY PARTY FOR DIRECT,
28  * INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF
29  * THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF "MLAB" OR
30  * "NICR" HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  *
32  * "MLAB" AND "NICR" SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING,
33  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
34  * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
35  * ON AN "AS IS" BASIS, AND "MLAB" AND "NICR" HAVE NO OBLIGATION TO
36  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS OR MODIFICATIONS.
37  */
38 
47 #ifndef _MIRA_FRAMEWORKGRAPH_H_
48 #define _MIRA_FRAMEWORKGRAPH_H_
49 
50 #include <string>
51 
52 #include <serialization/adapters/std/list>
53 #include <serialization/adapters/boost/shared_ptr.hpp>
54 #include <geometry/Point.h>
55 
57 
58 #include <fw/Framework.h>
59 #include <fw/RemoteModule.h>
60 
61 namespace mira {
62 
64 
65 template <int C, typename T>
66 class FrameworkGraphMixin : public T {};
67 
68 template <int C> // note, the C helps us to generate different classes to avoid compiler warning concerning inaccessible base classes
69 class FrameworkGraphMixin<C,void> {};
70 
96 template <typename NodeMixin = void,
97  typename AuthorityNodeMixin=void,
98  typename ChannelNodeMixin=void,
99  typename NamespaceNodeMixin=void,
100  typename FrameworkNodeMixin=void>
101 class FrameworkGraph : boost::noncopyable
102 {
103  class EmptyMixin {};
104 
105 public:
106 
107  class Node;
108  typedef boost::shared_ptr<Node> NodePtr;
109 
110  class ChannelNode;
111  typedef boost::shared_ptr<ChannelNode> ChannelNodePtr;
112 
114  typedef boost::shared_ptr<AuthorityNode> AuthorityNodePtr;
115 
117  typedef boost::shared_ptr<NamespaceNode> NamespaceNodePtr;
118 
120  typedef boost::shared_ptr<FrameworkNode> FrameworkNodePtr;
121 
125  class Node : public FrameworkGraphMixin<0,NodeMixin>
126  {
127  public:
128  virtual ~Node() {}
129 
131  virtual std::set<NodePtr> getAdjacentNodes() = 0;
132  };
133 
137  class ChannelNode : public Node, public FrameworkGraphMixin<1,ChannelNodeMixin>
138  {
139  public:
140  ChannelNode(const std::string& iID) : id(iID) {}
141  bool operator==(const std::string& id) {
142  return id==this->id;
143  }
144 
145  virtual std::set<NodePtr> getAdjacentNodes()
146  {
147  std::set<NodePtr> nodes;
148  foreach(auto p, mSubscribedAuthorities)
149  nodes.insert(p);
150  foreach(auto p, mPublishingAuthorities)
151  nodes.insert(p);
152  return nodes;
153  }
154 
155  std::set<AuthorityNodePtr> getSubscribedAuthorities() {
156  return mSubscribedAuthorities;
157  }
158 
159  std::set<AuthorityNodePtr> getPublishingAuthorities() {
160  return mPublishingAuthorities;
161  }
162 
165  return mNamespace;
166  }
167 
168  public:
169 
171  std::string id;
172 
173  protected:
174  friend class FrameworkGraph;
175  std::set<AuthorityNodePtr> mSubscribedAuthorities;
176  std::set<AuthorityNodePtr> mPublishingAuthorities;
178  };
179 
183  class AuthorityNode : public Node, public FrameworkGraphMixin<2,AuthorityNodeMixin> {
184  public:
185  AuthorityNode(const AuthorityDescription& iDesc) : desc(iDesc) {}
186  bool operator==(const std::string& id) {
187  return id == (desc.ns / desc.id);
188  }
189 
190  public:
191 
192  virtual std::set<NodePtr> getAdjacentNodes()
193  {
194  std::set<NodePtr> nodes;
195  foreach(auto p, mSubscribedChannels)
196  nodes.insert(p);
197  foreach(auto p, mPublishedChannels)
198  nodes.insert(p);
199  return nodes;
200  }
201 
203  std::set<ChannelNodePtr> getPublishedChannels() {
204  return mPublishedChannels;
205  }
206 
208  std::set<ChannelNodePtr> getSubscribedChannels() {
209  return mSubscribedChannels;
210  }
211 
214  return mNamespace;
215  }
216 
219  return mFramework;
220  }
221 
227  std::map<AuthorityNodePtr, std::set<ChannelNodePtr>> getDependees() {
228  std::map<AuthorityNodePtr, std::set<ChannelNodePtr>> nodes;
229  foreach(auto c, mSubscribedChannels)
230  foreach(auto a, c->getPublishingAuthorities())
231  nodes[a].insert(c);
232  return nodes;
233  }
234 
240  std::map<AuthorityNodePtr, std::set<ChannelNodePtr>> getDependers() {
241  std::map<AuthorityNodePtr, std::set<ChannelNodePtr>> nodes;
242  foreach(auto c, mPublishedChannels)
243  foreach(auto a, c->getSubscribedAuthorities())
244  nodes[a].insert(c);
245  return nodes;
246  }
247 
248 
249  public:
250 
253 
254  protected:
255  friend class FrameworkGraph;
256  std::set<ChannelNodePtr> mSubscribedChannels;
257  std::set<ChannelNodePtr> mPublishedChannels;
260  };
261 
266  class NamespaceNode : public Node, public FrameworkGraphMixin<3,NamespaceNodeMixin> {
267  public:
268  NamespaceNode(const ResourceName& iNs) : ns(iNs) {}
269  bool operator==(const ResourceName& iNs) {
270  return iNs==ns;
271  }
272 
275  assert(parent && child);
276  parent->children.insert(child);
277  child->parent = parent;
278  }
279 
280  public:
281 
282  virtual std::set<NodePtr> getAdjacentNodes()
283  {
284  static std::set<NodePtr> empty;
285  return empty;
286  }
287 
288  public:
289 
292 
295 
297  std::set<NamespaceNodePtr> children;
298 
300  std::set<NodePtr> nodes;
301  };
302 
306  class FrameworkNode : public Node, public FrameworkGraphMixin<4,FrameworkNodeMixin> {
307  public:
308  FrameworkNode(const std::string& iName) : name(iName) {}
309  bool operator==(const std::string& iName) {
310  return iName==name;
311  }
312 
313  public:
314 
315  virtual std::set<NodePtr> getAdjacentNodes()
316  {
317  static std::set<NodePtr> empty;
318  return empty;
319  }
320 
321  public:
322 
324  std::string name;
325 
327  std::set<NodePtr> nodes;
328  };
329 
330 public:
331 
334  // create a root namespace node
335  mRootNamespace = getNamespaceNode(ResourceName("/"));
336  }
337 
346  bool discover(boost::function<void()> changeCb = boost::function<void()>())
347  {
348  mGraphHasChanged = false; // <this variable is reseted several times
349  bool graphHasChanged = false; // <this one holds whether the graph has any changes
350 
351  // Channels
352  foreach(const std::string& id, MIRA_FW.getChannelManager().getChannels())
353  {
354  ChannelNodePtr node = getChannelNode(id);
355  }
356 
357  graphHasChanged |= mGraphHasChanged;
358  if(mGraphHasChanged && changeCb)
359  changeCb();
360 
361  // Authorities
362  // discovery of authorities may be a little time consuming, if
363  // a lot of remote authorities and hence RPC calls are involved
364  auto authorities = MIRA_FW.getAuthorityManager().getAuthorities();
365  foreach(auto id, authorities)
366  {
367  mGraphHasChanged = false; // reset marker
368 
370  if(!node) {
371  AuthorityDescription d = MIRA_FW.getAuthorityManager().getDescription(id);
372 
373  boost::mutex::scoped_lock lock(mMutex);
374  node.reset(new AuthorityNode(d));
375  mAuthorities.push_back(node);
376 
377  // Namespace
378  NamespaceNodePtr ns = getNamespaceNode(d.ns);
379  node->mNamespace = ns;
380  ns->nodes.insert(node);
381 
382  // Framework
383  std::string fwid = "local";
384  foreach(const auto& connection, *(MIRA_FW.getRemoteModule()->getConnections()))
385  {
386  if (connection.second->hasAuthority(id)) {
387  fwid = connection.second->getAddress().address;
388  break;
389  }
390  }
391  FrameworkNodePtr fw = getFrameworkNode(fwid);
392  node->mFramework = fw;
393  fw->nodes.insert(node);
394 
395  mGraphHasChanged = true;
396  }
397 
398  // connections: Authorities -> Channels:
399  auto publishedChannels = MIRA_FW.getAuthorityManager().getPublishedChannels(id);
400  foreach(const std::string& channel, publishedChannels)
401  {
402  boost::mutex::scoped_lock lock(mMutex);
403  ChannelNodePtr channelNode = getChannelNode(channel);
404  mGraphHasChanged |= node->mPublishedChannels.insert(channelNode).second;
405  mGraphHasChanged |= channelNode->mPublishingAuthorities.insert(node).second;
406  }
407 
408  auto subscribedChannels = MIRA_FW.getAuthorityManager().getSubscribedChannels(id);
409  foreach(const std::string& channel, subscribedChannels)
410  {
411  boost::mutex::scoped_lock lock(mMutex);
412  ChannelNodePtr channelNode = getChannelNode(channel);
413  mGraphHasChanged |= node->mSubscribedChannels.insert(channelNode).second;
414  mGraphHasChanged |= channelNode->mSubscribedAuthorities.insert(node).second;
415  }
416 
417  graphHasChanged |= mGraphHasChanged;
418  if(mGraphHasChanged && changeCb)
419  changeCb();
420  }
421  return graphHasChanged;
422  }
423 
424 private:
425 
426  ChannelNodePtr getChannelNode(const std::string& id)
427  {
428  ChannelNodePtr node = findPtr(mChannels, id);
429  if(!node) {
430  node.reset(new ChannelNode(id));
431  mChannels.push_back(node);
432  NamespaceNodePtr ns = getNamespaceNode(ResourceName(id).parent());
433  node->mNamespace = ns;
434  ns->nodes.insert(node);
435  mGraphHasChanged = true;
436  }
437  return node;
438  }
439 
440  NamespaceNodePtr getNamespaceNode(const ResourceName& ns)
441  {
443  if(!node) {
444  node.reset(new NamespaceNode(ns));
445  mNamespaces.push_back(node);
446  if(!node->ns.isRoot())
448  mGraphHasChanged = true;
449  }
450  return node;
451  }
452 
453  FrameworkNodePtr getFrameworkNode(const std::string& name)
454  {
455  FrameworkNodePtr node = findPtr(mFrameworks, name);
456  if(!node) {
457  node.reset(new FrameworkNode(name));
458  mFrameworks.push_back(node);
459  mGraphHasChanged = true;
460  }
461  return node;
462  }
463 
464 public:
465 
467  std::list<NodePtr> getNodes() {
468  std::list<NodePtr> nodes;
469  std::copy(getChannels().begin(),getChannels().end(),std::back_inserter(nodes));
470  std::copy(getAuthorities().begin(),getAuthorities().end(),std::back_inserter(nodes));
471  return nodes;
472  }
473 
475  std::list<ChannelNodePtr>& getChannels() {
476  return mChannels; }
477 
479  template <typename Visitor>
480  void visitAuthorities(Visitor&& visit){
481  boost::mutex::scoped_lock lock(mMutex);
482  for(auto&& auth: mAuthorities)
483  {
484  visit(auth);
485  }
486  }
487 
489  std::list<AuthorityNodePtr>& getAuthorities() {
490  return mAuthorities; }
491 
493  std::list<NamespaceNodePtr>& getNamespaces() {
494  return mNamespaces; }
495 
497  std::list<FrameworkNodePtr>& getFrameworks() {
498  return mFrameworks; }
499 
502  return mRootNamespace; }
503 
506  {
507  assert(mRootNamespace);
508 
509  // find direct ancestor node
510  NamespaceNodePtr ancestor = mRootNamespace;
511  bool abort;
512  do {
513  abort = true;
514  foreach(NamespaceNodePtr child, ancestor->children)
515  {
516  if(child->ns.isAncestorOf(node->ns)) {
517  ancestor = child;
518  abort = false;
519  break;
520  }
521  }
522  } while(!abort);
523 
524 
525  // now add all children from ancestor that are actually our children
526  // and remove them from ancestor
527  auto childrenSet = ancestor->children;
528  foreach(NamespaceNodePtr child, childrenSet)
529  {
530  if(child->ns.isChildOf(node->ns)) {
531  node->children.insert(child);
532  ancestor->children.erase(child);
533  child->parent = node;
534  }
535  }
536 
537  // add us as new child to the ancestor
538  ancestor->children.insert(node);
539  // which is our parent
540  node->parent = ancestor;
541 
542  // check if 'ancestor' is direct namespace parent of 'node'
543  // if not, add all missing namespaces between 'ancestor' and 'node' recursively,
544  // beginning with the direct parent of 'node'
545  auto parent_ns = node->ns.parent();
546  if (parent_ns != ancestor->ns)
547  {
548  NamespaceNodePtr n(new NamespaceNode(parent_ns));
549  mNamespaces.push_back(n);
551  }
552  }
553 
554  /*
555  2nd version of the above method, work in progress
556  void integrateNamespaceNode2(NamespaceNodePtr node)
557  {
558  assert(mRootNamespace);
559 
560  NamespaceNodePtr parent = getNamespaceNode(node->ns.parent());
561  parent->children.insert(node);
562  node->parent = parent;
563  }
564  */
565 
566 protected:
567 
568  boost::mutex mMutex;
569  std::list<AuthorityNodePtr> mAuthorities;
570  std::list<ChannelNodePtr> mChannels;
571  std::list<NamespaceNodePtr> mNamespaces;
572  std::list<FrameworkNodePtr> mFrameworks;
574 
576 
577 
578 
579  template <typename Container, typename Key>
580  typename Container::value_type findPtr(Container& c, const Key& key)
581  {
582  foreach(typename Container::value_type ptr, c)
583  if(*ptr == key)
584  return ptr;
585  return typename Container::value_type();
586  }
587 };
588 
590 
591 } // namespace
592 
593 #endif
bool operator==(const std::string &iName)
Definition: FrameworkGraph.h:309
NamespaceNodePtr mRootNamespace
Definition: FrameworkGraph.h:573
std::set< AuthorityNodePtr > getSubscribedAuthorities()
Definition: FrameworkGraph.h:155
std::set< NamespaceNodePtr > children
sub-namespaces that live in this namespace
Definition: FrameworkGraph.h:297
FrameworkNode(const std::string &iName)
Definition: FrameworkGraph.h:308
Base class for all nodes in the framework computation graph.
Definition: FrameworkGraph.h:125
std::string id
the authority id. will be generated for anonymous authorities
Definition: AuthorityDescription.h:96
ResourceName ns
the name of the namespace
Definition: FrameworkGraph.h:291
std::set< ChannelNodePtr > mPublishedChannels
Definition: FrameworkGraph.h:257
std::list< NamespaceNodePtr > mNamespaces
Definition: FrameworkGraph.h:571
boost::shared_ptr< Node > NodePtr
Definition: FrameworkGraph.h:107
std::set< ChannelNodePtr > mSubscribedChannels
Definition: FrameworkGraph.h:256
Container::value_type findPtr(Container &c, const Key &key)
Definition: FrameworkGraph.h:580
std::set< NodePtr > nodes
channel and authority nodes within this framework
Definition: FrameworkGraph.h:327
std::list< ChannelNodePtr > mChannels
Definition: FrameworkGraph.h:570
NamespaceNodePtr getRootNamespace()
Returns the root namespace node.
Definition: FrameworkGraph.h:501
std::list< FrameworkNodePtr > & getFrameworks()
Returns all framework nodes.
Definition: FrameworkGraph.h:497
bool operator==(const std::string &id)
Definition: FrameworkGraph.h:186
NamespaceNodePtr getNamespace()
Returns the namespace node where this channel lives in.
Definition: FrameworkGraph.h:164
boost::shared_ptr< ChannelNode > ChannelNodePtr
Definition: FrameworkGraph.h:110
Descriptive informations about an authority.
Definition: FrameworkGraph.h:66
specialize cv::DataType for our ImgPixel and inherit from cv::DataType<Vec>
Definition: IOService.h:67
ChannelNode(const std::string &iID)
Definition: FrameworkGraph.h:140
The framework module responsible for connections to remote frameworks.
Represents a single authority in the framwork computation graph.
Definition: FrameworkGraph.h:183
Class for 2D, 3D and N-dimensional points.
FrameworkNodePtr getFramework()
Returns the framework where this authority lives in.
Definition: FrameworkGraph.h:218
std::list< FrameworkNodePtr > mFrameworks
Definition: FrameworkGraph.h:572
virtual std::set< NodePtr > getAdjacentNodes()
Returns the adjacent (incoming and outgoing nodes)
Definition: FrameworkGraph.h:315
std::set< ChannelNodePtr > getPublishedChannels()
Returns all channel nodes with channels that are published by the authority.
Definition: FrameworkGraph.h:203
std::set< AuthorityNodePtr > mSubscribedAuthorities
Definition: FrameworkGraph.h:175
boost::mutex mMutex
Definition: FrameworkGraph.h:568
NamespaceNodePtr mNamespace
Definition: FrameworkGraph.h:177
boost::shared_ptr< NamespaceNode > NamespaceNodePtr
Definition: FrameworkGraph.h:116
AuthorityNode(const AuthorityDescription &iDesc)
Definition: FrameworkGraph.h:185
FrameworkNodePtr mFramework
Definition: FrameworkGraph.h:259
#define MIRA_FW
Macro for accessing the framework instance.
Definition: Framework.h:74
virtual std::set< NodePtr > getAdjacentNodes()
Returns the adjacent (incoming and outgoing nodes)
Definition: FrameworkGraph.h:145
std::set< NodePtr > nodes
channel and authority nodes within this namespace
Definition: FrameworkGraph.h:300
This is the descriptive part of an authority.
Definition: AuthorityDescription.h:61
std::set< ChannelNodePtr > getSubscribedChannels()
Returns all channel nodes with channels the authority is subscribed on.
Definition: FrameworkGraph.h:208
std::map< AuthorityNodePtr, std::set< ChannelNodePtr > > getDependers()
Returns all authority nodes that DEPEND on this authority.
Definition: FrameworkGraph.h:240
NamespaceNodePtr getNamespace()
Returns the namespace node where this authority lives in.
Definition: FrameworkGraph.h:213
virtual ~Node()
Definition: FrameworkGraph.h:128
Represents a namespace in the framework computation graph within the overall namespace hierarchy...
Definition: FrameworkGraph.h:266
Class for storing/combining/managing resource names consisting of namespaces and names separated by &#39;...
Definition: ResourceName.h:68
bool mGraphHasChanged
Definition: FrameworkGraph.h:575
std::string name
the name
Definition: FrameworkGraph.h:324
std::map< AuthorityNodePtr, std::set< ChannelNodePtr > > getDependees()
Returns all authority nodes that THIS authority depends on.
Definition: FrameworkGraph.h:227
boost::shared_ptr< AuthorityNode > AuthorityNodePtr
Definition: FrameworkGraph.h:113
bool operator==(const std::string &id)
Definition: FrameworkGraph.h:141
NamespaceNodePtr parent
the namespace parent node (if we are not the root node)
Definition: FrameworkGraph.h:294
Represents a framework in the framework computation graph.
Definition: FrameworkGraph.h:306
std::string id
the fully qualified name of the node (the id)
Definition: FrameworkGraph.h:171
std::list< ChannelNodePtr > & getChannels()
Returns all channel nodes.
Definition: FrameworkGraph.h:475
bool discover(boost::function< void()> changeCb=boost::function< void()>())
Discovers the whole structure of all connected frameworks with its authorities, channels, services, etc.
Definition: FrameworkGraph.h:346
virtual std::set< NodePtr > getAdjacentNodes()
Returns the adjacent (incoming and outgoing nodes)
Definition: FrameworkGraph.h:192
static void setParent(NamespaceNodePtr child, NamespaceNodePtr parent)
workaround to avoid shared_from_this
Definition: FrameworkGraph.h:274
std::list< AuthorityNodePtr > & getAuthorities()
Returns all authority nodes.
Definition: FrameworkGraph.h:489
ResourceName ns
the full namespace (starting from root) of this authority
Definition: AuthorityDescription.h:95
std::list< NamespaceNodePtr > & getNamespaces()
Returns all namespace nodes.
Definition: FrameworkGraph.h:493
std::set< AuthorityNodePtr > getPublishingAuthorities()
Definition: FrameworkGraph.h:159
Represents the whole computation graph with all known units/authorities and channels within their nam...
Definition: FrameworkGraph.h:101
NamespaceNode(const ResourceName &iNs)
Definition: FrameworkGraph.h:268
virtual std::set< NodePtr > getAdjacentNodes()=0
Returns the adjacent (incoming and outgoing nodes)
void integrateNamespaceNode(NamespaceNodePtr node)
inserts a new namespace node and reparents the existing namespace nodes, if necessary.
Definition: FrameworkGraph.h:505
std::list< AuthorityNodePtr > mAuthorities
Definition: FrameworkGraph.h:569
AuthorityDescription desc
full information on the authority
Definition: FrameworkGraph.h:252
FrameworkGraph()
Creates an emtpy framework graph object.
Definition: FrameworkGraph.h:333
std::set< AuthorityNodePtr > mPublishingAuthorities
Definition: FrameworkGraph.h:176
void visitAuthorities(Visitor &&visit)
visit all authories
Definition: FrameworkGraph.h:480
boost::shared_ptr< FrameworkNode > FrameworkNodePtr
Definition: FrameworkGraph.h:119
bool operator==(const ResourceName &iNs)
Definition: FrameworkGraph.h:269
The framework that holds all manager classes and provides startup and shutdown of all framework relat...
NamespaceNodePtr mNamespace
Definition: FrameworkGraph.h:258
Represents a single channel in the framwork computation graph.
Definition: FrameworkGraph.h:137
virtual std::set< NodePtr > getAdjacentNodes()
Returns the adjacent (incoming and outgoing nodes)
Definition: FrameworkGraph.h:282
std::list< NodePtr > getNodes()
Returns all channel and authority nodes.
Definition: FrameworkGraph.h:467