iLab Neuromorphic Robotics Toolkit  0.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ManagerImpl.H
Go to the documentation of this file.
1 /*! @file
2  @author Laurent Itti
3  @copyright GNU Public License (GPL v3)
4  @section License
5  @verbatim
6  // ////////////////////////////////////////////////////////////////////////
7  // The iLab Neuromorphic Robotics Toolkit (NRT) //
8  // Copyright 2010-2012 by the University of Southern California (USC) //
9  // and the iLab at USC. //
10  // //
11  // iLab - University of Southern California //
12  // Hedco Neurociences Building, Room HNB-10 //
13  // Los Angeles, Ca 90089-2520 - USA //
14  // //
15  // See http://ilab.usc.edu for information about this project. //
16  // ////////////////////////////////////////////////////////////////////////
17  // This file is part of The iLab Neuromorphic Robotics Toolkit. //
18  // //
19  // The iLab Neuromorphic Robotics Toolkit is free software: you can //
20  // redistribute it and/or modify it under the terms of the GNU General //
21  // Public License as published by the Free Software Foundation, either //
22  // version 3 of the License, or (at your option) any later version. //
23  // //
24  // The iLab Neuromorphic Robotics Toolkit is distributed in the hope //
25  // that it will be useful, but WITHOUT ANY WARRANTY; without even the //
26  // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //
27  // PURPOSE. See the GNU General Public License for more details. //
28  // //
29  // You should have received a copy of the GNU General Public License //
30  // along with The iLab Neuromorphic Robotics Toolkit. If not, see //
31  // <http://www.gnu.org/licenses/>. //
32  // ////////////////////////////////////////////////////////////////////////
33  @endverbatim */
34 
35 #ifndef INCLUDE_NRT_CORE_MODEL_DETAILS_MANAGERIMPL_H
36 #define INCLUDE_NRT_CORE_MODEL_DETAILS_MANAGERIMPL_H
37 
38 #include <nrt/Core/Debugging/Log.H>
39 
40 // ######################################################################
41 template <class Comp> inline
42 std::shared_ptr<Comp> nrt::Manager::addComponent(std::string const & instanceName)
43 {
44  // Keep this code in sync with module version
45 
46  // Enforce that Comp derives from Component, but not from Module:
47  static_assert(std::is_base_of<nrt::Component, Comp>::value, "Comp must derive from nrt::Component");
48  static_assert( ! std::is_base_of<nrt::ModuleBase, Comp>::value, "Use nrt::Blackboard::addModule() for top-level "
49  "objects that derive from nrt::Module");
50 
51  // First, create the sub and put it into a shared_ptr:
52  std::shared_ptr<Comp> subComp(new Comp(computeInstanceName(instanceName)));
53 
54  // Then add it as a sub-component to us:
55  {
56  boost::upgrade_lock<boost::shared_mutex> uplck(itsSubMtx);
57 
58  std::string const inst = subComp->meta().instanceName;
59 
60  for (std::shared_ptr<nrt::Component> const & c : itsSubComponents)
61  if (inst == c->meta().instanceName)
62  NRT_FATAL("Cannot add two components with identical instanceNames [" << inst << ']');
63 
64  NRT_MODDEBUG("Adding Component [" << subComp->meta().str() << ']');
65 
66  {
67  boost::upgrade_to_unique_lock<boost::shared_mutex> ulck(uplck);
68  itsSubComponents.push_back(subComp);
69  subComp->itsParent = this;
70  }
71  }
72 
73  // Finally bring it to our runstate:
74  if (itsInitialized) subComp->init();
75  if (itsStarted) subComp->start();
76  if (itsRunning) subComp->launch();
77 
78  return subComp;
79 }
80 
81 // ######################################################################
82 template <class Comp> inline
83 std::shared_ptr<Comp> nrt::Manager::getComponent(std::string const & instanceName) const
84 {
85  // Keep this code in sync with module version
86 
87  // Enforce that Comp derives from Component, but not from Module:
88  static_assert(std::is_base_of<nrt::Component, Comp>::value, "Comp must derive from nrt::Component");
89  static_assert( ! std::is_base_of<nrt::ModuleBase, Comp>::value, "Use nrt::Blackboard::getModule() for top-level "
90  "objects that derive from nrt::Module");
91 
92  boost::shared_lock<boost::shared_mutex> lck(itsSubMtx);
93 
94  for (std::shared_ptr<nrt::Component> c : itsSubComponents)
95  if (instanceName == c->meta().instanceName)
96  {
97  std::shared_ptr<Comp> ret = std::dynamic_pointer_cast<Comp>(c);
98  if (ret) return ret; // correct type
99  NRT_FATAL("SubComponent [" << instanceName << "] is not of type [" << nrt::demangledName<Comp>() << ']');
100  }
101 
102  NRT_FATAL("SubComponent [" << instanceName << "] not found");
103 }
104 
105 // ######################################################################
106 // Specialization for nrt::Component return: no need to cast
107 namespace nrt
108 {
109  template <> inline
110  std::shared_ptr<Component> Manager::getComponent<Component>(std::string const & instanceName) const
111  {
112  boost::shared_lock<boost::shared_mutex> lck(itsSubMtx);
113 
114  for (std::shared_ptr<Component> c : itsSubComponents) if (instanceName == c->meta().instanceName) return c;
115 
116  NRT_FATAL("Component [" << instanceName << "] not found");
117  }
118 }
119 
120 // ######################################################################
121 template <class Comp>
122 void nrt::Manager::removeComponent(std::shared_ptr<Comp> & component)
123 {
124  // Keep this code in sync with module version
125 
126  static_assert(std::is_base_of<nrt::Component, Comp>::value, "Comp must derive from nrt::Component");
127  ///FIXME static_assert( ! std::is_base_of<nrt::ModuleBase, Mod>::value, "Use nrt::Blackboard::removeModule() for objects "
128  // "that derive from nrt::Module");
129 
130  boost::upgrade_lock<boost::shared_mutex> uplck(itsSubMtx);
131 
132  for (auto itr = itsSubComponents.begin(); itr != itsSubComponents.end(); ++itr)
133  if (itr->get() == component.get())
134  {
135  NRT_MODDEBUG("Removing Component [" << component->meta().str() << ']');
136 
137  boost::upgrade_to_unique_lock<boost::shared_mutex> ulck(uplck);
138  component->prepareForDeletion();
139  itsSubComponents.erase(itr);
140 
141  if (component.use_count() > 1)
142  NRT_WARNING(component.use_count() - 1 << " additional external shared_ptr references exist to "
143  "Component [" << component->meta().str() << "]. Component was NOT deleted.");
144  component.reset(); // nuke the shared_ptr, this should yield a delete unless use_count was > 1
145  return;
146  }
147 
148  NRT_WARNING("Component [" << component->meta().str() << "] not found. Ignored.");
149 }
150 
151 #endif // INCLUDE_NRT_CORE_MODEL_DETAILS_MANAGERIMPL_H