JeVois  1.0
JeVois Smart Embedded Machine Vision Toolkit
ManagerImpl.H
Go to the documentation of this file.
1 // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2 //
3 // JeVois Smart Embedded Machine Vision Toolkit - Copyright (C) 2016 by Laurent Itti, the University of Southern
4 // California (USC), and iLab at USC. See http://iLab.usc.edu and http://jevois.org for information about this project.
5 //
6 // This file is part of the JeVois Smart Embedded Machine Vision Toolkit. This program is free software; you can
7 // redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software
8 // Foundation, version 2. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
9 // without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
10 // License for more details. You should have received a copy of the GNU General Public License along with this program;
11 // if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
12 //
13 // Contact information: Laurent Itti - 3641 Watt Way, HNB-07A - Los Angeles, CA 90089-2520 - USA.
14 // Tel: +1 213 740 3527 - itti@pollux.usc.edu - http://iLab.usc.edu - http://jevois.org
15 // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
16 /*! \file */
17 
18 // This code is inspired by the Neuromorphic Robotics Toolkit (http://nrtkit.org)
19 
20 #pragma once
21 
22 #include <jevois/Debug/Log.H>
23 
24 // ######################################################################
25 template <class Comp, typename... Args> inline
26 std::shared_ptr<Comp> jevois::Manager::addComponent(std::string const & instance, Args && ...args)
27 {
28  // Keep this code in sync with that in Engine.C!
29 
30  // Enforce that Comp derives from Component:
31  static_assert(std::is_base_of<jevois::Component, Comp>::value, "Comp must derive from jevois::Component");
32 
33  std::shared_ptr<Comp> subComp;
34 
35  {
36  // Lock up so we guarantee the instance name does not get robbed as we add the sub:
37  boost::unique_lock<boost::shared_mutex> ulck(itsSubMtx);
38 
39  // Create the sub and put it into a shared_ptr. Note: computeInstanceName() will throw if name clashes with some
40  // existing sub-component:
41  subComp.reset(new Comp(computeInstanceName(instance, jevois::demangledName<Comp>()), std::forward<Args>(args)...));
42 
43  // Then add it as a sub-component to us, if there is not instance name clash with our other sub-components:
44  LDEBUG("Adding Component [" << subComp->instanceName() << ']');
45  itsSubComponents.push_back(subComp);
46  subComp->itsParent = this;
47 
48  // By default, inherit the path from the parent:
49  subComp->setPath(absolutePath());
50  }
51 
52  // Finally bring it to our runstate:
53  if (itsInitialized) subComp->init();
54 
55  return subComp;
56 }
57 
58 // ######################################################################
59 template <class Comp> inline
60 std::shared_ptr<Comp> jevois::Manager::getComponent(std::string const & instance) const
61 {
62  // Keep this code in sync with module version
63 
64  // Enforce that Comp derives from Component:
65  static_assert(std::is_base_of<jevois::Component, Comp>::value, "Comp must derive from jevois::Component");
66 
67  boost::shared_lock<boost::shared_mutex> lck(itsSubMtx);
68 
69  for (std::shared_ptr<jevois::Component> c : itsSubComponents)
70  if (c->instanceName() == instance)
71  {
72  std::shared_ptr<Comp> ret = std::dynamic_pointer_cast<Comp>(c);
73  if (ret) return ret; // correct type
74  LFATAL("Component [" << instance << "] is not of type [" << jevois::demangledName<Comp>() << ']');
75  }
76 
77  LFATAL("Component [" << instance << "] not found");
78 }
79 
80 // ######################################################################
81 // Specialization for jevois::Component return: no need to cast
82 #ifndef JEVOIS_DOXYGEN
83 namespace jevois
84 {
85  template <> inline
86  std::shared_ptr<Component> Manager::getComponent<Component>(std::string const & instance) const
87  {
88  boost::shared_lock<boost::shared_mutex> lck(itsSubMtx);
89 
90  for (std::shared_ptr<Component> c : itsSubComponents)
91  if (c->instanceName() == instance) return c;
92 
93  LFATAL("Component [" << instance << "] not found");
94  }
95 }
96 #endif
97 
98 // ######################################################################
99 template <class Comp>
100 void jevois::Manager::removeComponent(std::shared_ptr<Comp> & component)
101 {
102  static_assert(std::is_base_of<jevois::Component, Comp>::value, "Comp must derive from jevois::Component");
103 
104  boost::upgrade_lock<boost::shared_mutex> uplck(itsSubMtx);
105 
106  for (auto itr = itsSubComponents.begin(); itr != itsSubComponents.end(); ++itr)
107  if (itr->get() == component.get())
108  {
109  // First, nuke the "component" shared_ptr so it does not show up as a dangling shared_ptr in
110  // doRemoveSubComponent(). itr still has one ref to the pointee:
111  component.reset();
112 
113  // Then remove that sub:
114  doRemoveSubComponent(itr, uplck, "Component");
115  return;
116  }
117 
118  LERROR("Component [" << component->instanceName() << "] not found. Ignored.");
119 }
#define LDEBUG(msg)
Convenience macro for users to print out console or syslog messages, DEBUG level. ...
Definition: Log.H:148
std::shared_ptr< Comp > addComponent(std::string const &instanceName, Args &&...args)
Pseudo-constructor: construct a top-level Component.
Definition: ManagerImpl.H:26
void removeComponent(std::shared_ptr< Comp > &component)
Remove a top-level Component from the Manager, by shared_ptr.
Definition: ManagerImpl.H:100
#define LERROR(msg)
Convenience macro for users to print out console or syslog messages, ERROR level. ...
Definition: Log.H:186
#define LFATAL(msg)
Convenience macro for users to print out console or syslog messages, FATAL level. ...
Definition: Log.H:205
std::shared_ptr< Comp > getComponent(std::string const &instanceName) const
Get a top-level component by instance name.
Definition: ManagerImpl.H:60
std::string absolutePath(std::string const &path="")
If given path is relative (not starting with /), prepend the Component path to it.
Definition: Component.C:501