iLab Neuromorphic Robotics Toolkit  0.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ModuleImpl.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 
36 #ifndef INCLUDE_NRT_CORE_BLACKBOARD_DETAILS_MODULEIMPL_H
37 #define INCLUDE_NRT_CORE_BLACKBOARD_DETAILS_MODULEIMPL_H
38 
39 // ######################################################################
40 template <class Mod> inline
41 std::shared_ptr<Mod> nrt::Module::addSubModule(std::string const & instanceName)
42 {
43  // Keep this code in sync with component version
44 
45  // Enforce that Mod derives from Module:
46  static_assert(std::is_base_of<nrt::Module, Mod>::value, "Mod must derive from nrt::Module");
47 
48  // First, create the sub and put it into a shared_ptr:
49  std::shared_ptr<Mod> module(new Mod(instanceName));
50 
51  // Set the namespace to match ours:
52  module->setNamespace(getNamespace());
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 = module->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 SubModules with identical instance names [" << inst << ']');
63 
64  NRT_MODDEBUG("Adding SubModule [" << module->meta().str() << ']');
65 
66  {
67  boost::upgrade_to_unique_lock<boost::shared_mutex> ulck(uplck);
68  itsSubComponents.push_back(module);
69  module->setParent(this);
70  }
71  }
72 
73  // Register the module with the Blackboard; this will also update the federation:
74  nrt::Blackboard::instance().registerModule(module.get());
75 
76  // Finally bring it to our runstate:
77  if (itsInitialized) module->init();
78  if (itsStarted) module->start();
79  if (itsRunning) module->launch();
80 
81  return module;
82 }
83 
84 // ######################################################################
85 template <class Mod> inline
86 std::shared_ptr<Mod> nrt::Module::getSubModule(std::string const & instanceName) const
87 {
88  // Keep this code in sync with component version
89 
90  // Enforce that Mod derives from Module:
91  static_assert(std::is_base_of<nrt::Module, Mod>::value, "Mod must derive from nrt::Module");
92 
93  boost::shared_lock<boost::shared_mutex> lck(itsSubMtx);
94 
95  for (std::shared_ptr<nrt::Component> c : itsSubComponents)
96  if (instanceName == c->meta().instanceName)
97  {
98  std::shared_ptr<Mod> ret = std::dynamic_pointer_cast<Mod>(c);
99  if (ret) return ret; // correct type
100  NRT_FATAL("SubModule [" << instanceName << "] is not of type [" << nrt::demangledName<Mod>() << ']');
101  }
102 
103  NRT_FATAL("SubModule [" << instanceName << "] not found");
104 }
105 
106 // ######################################################################
107 template <class Mod>
108 void nrt::Module::removeSubModule(std::shared_ptr<Mod> & module)
109 {
110  // Keep this code in sync with component version
111 
112  // Enforce that Mod derives from Module:
113  static_assert(std::is_base_of<nrt::Module, Mod>::value, "Mod must derive from nrt::Module");
114 
115  boost::upgrade_lock<boost::shared_mutex> uplck(itsSubMtx);
116 
117  for (auto itr = itsSubComponents.begin(); itr != itsSubComponents.end(); ++itr)
118  if (itr->get() == module.get())
119  {
120  NRT_MODDEBUG("Removing SubModule [" << module->meta().str() << ']');
121 
122  boost::upgrade_to_unique_lock<boost::shared_mutex> ulck(uplck);
123  module->prepareForDeletion();
124  itsSubComponents.erase(itr);
125 
126  // Update the blackboard:
127  nrt::Blackboard::instance().unRegisterModule(module.get());
128 
129  if (module.use_count() > 1)
130  NRT_WARNING(module.use_count() - 1 << " additional external shared_ptr references exist to "
131  "Module [" << module->meta().str() << "]. Module was NOT deleted.");
132 
133  module.reset(); // nuke the shared_ptr, this should yield a delete unless use_count was > 1
134  return;
135  }
136 
137  NRT_WARNING("SubModule [" << module->meta().str() << "] not found. Ignored.");
138 
139 }
140 
141 
144 
145 #endif // INCLUDE_NRT_CORE_BLACKBOARD_DETAILS_MODULEIMPL_H