Fawkes API  Fawkes Development Version
manager.cpp
1 
2 /***************************************************************************
3  * manager.cpp - Fawkes Aspect Manager
4  *
5  * Created: Thu Nov 25 00:34:06 2010 (based on inifin.h)
6  * Copyright 2006-2010 Tim Niemueller [www.niemueller.de]
7  *
8  ****************************************************************************/
9 
10 /* This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version. A runtime exception applies to
14  * this software (see LICENSE.GPL_WRE file mentioned below for details).
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU Library General Public License for more details.
20  *
21  * Read the full text in the LICENSE.GPL_WRE file in the doc directory.
22  */
23 
24 #include <aspect/inifins/aspect_provider.h>
25 #include <aspect/inifins/blackboard.h>
26 #include <aspect/inifins/blocked_timing.h>
27 #include <aspect/inifins/clock.h>
28 #include <aspect/inifins/configurable.h>
29 #include <aspect/inifins/fawkes_network.h>
30 #include <aspect/inifins/logger.h>
31 #include <aspect/inifins/logging.h>
32 #include <aspect/inifins/mainloop.h>
33 #include <aspect/inifins/network.h>
34 #include <aspect/inifins/plugin_director.h>
35 #include <aspect/inifins/syncpoint.h>
36 #include <aspect/inifins/syncpoint_manager.h>
37 #include <aspect/inifins/thread_producer.h>
38 #include <aspect/inifins/time_source.h>
39 #include <aspect/inifins/vision.h>
40 #include <aspect/inifins/vision_master.h>
41 #include <aspect/manager.h>
42 #ifdef HAVE_WEBVIEW
43 # include <aspect/inifins/webview.h>
44 #endif
45 #ifdef HAVE_TF
46 # include <aspect/inifins/tf.h>
47 #endif
48 #ifdef HAVE_PCL
49 # include <aspect/inifins/pointcloud.h>
50 #endif
51 
52 namespace fawkes {
53 
54 /** @class AspectManager <aspect/manager.h>
55  * Aspect and aspect initializer/finalizer manager.
56  * This class is the central gatekeeper to aspects for the main application.
57  * It manages the initializers/finalizers and thus the aspects which are
58  * currently available in the system. It assures that these are not removed
59  * before the last thread with an aspect is gone.
60  * @author Tim Niemueller
61  */
62 
63 /** Constructor. */
65 {
66  std::map<std::string, AspectIniFin *>::iterator i;
67  for (i = default_inifins_.begin(); i != default_inifins_.end(); ++i) {
68  delete i->second;
69  }
70  default_inifins_.clear();
71 }
72 
73 /** Register initializer/finalizer.
74  * @param inifin aspect initializer/finalizer to register
75  */
76 void
78 {
79  if (inifins_.find(inifin->get_aspect_name()) != inifins_.end()) {
80  throw Exception("An initializer for %s has already been registered", inifin->get_aspect_name());
81  }
82  inifins_[inifin->get_aspect_name()] = inifin;
83 }
84 
85 /** Unregister initializer/finalizer.
86  * @param inifin aspect initializer/finalizer to unregister
87  */
88 void
90 {
91  if (inifins_.find(inifin->get_aspect_name()) == inifins_.end()) {
92  throw Exception("An initializer for %s has not been registered", inifin->get_aspect_name());
93  }
94  if (!threads_[inifin->get_aspect_name()].empty()) {
95  throw Exception("Threads with the %s aspect are still alive, cannot "
96  "unregister the aspect",
97  inifin->get_aspect_name());
98  }
99  inifins_.erase(inifin->get_aspect_name());
100  threads_.erase(inifin->get_aspect_name());
101 }
102 
103 /** Check if threads for a particular aspect still exist.
104  * @param aspect_name name of the aspect to check for
105  * @return true if thread for the given aspect have been registered,
106  * false otherwise
107  */
108 bool
110 {
111  return (threads_.find(aspect_name) != threads_.end()) && (!threads_[aspect_name].empty());
112 }
113 
114 void
116 {
117  Aspect *aspected_thread = dynamic_cast<Aspect *>(thread);
118  if (aspected_thread != NULL) { // thread has aspects to initialize
119  const std::list<const char *> &aspects = aspected_thread->get_aspects();
120 
121  std::list<const char *> initialized;
122 
123  try {
124  std::list<const char *>::const_iterator i;
125  for (i = aspects.begin(); i != aspects.end(); ++i) {
126  if (inifins_.find(*i) == inifins_.end()) {
127  throw CannotInitializeThreadException("Thread '%s' has the %s, "
128  "but no initializer is known.",
129  thread->name(),
130  *i);
131  }
132  inifins_[*i]->init(thread);
133  initialized.push_back(*i);
134  }
135 
136  for (i = aspects.begin(); i != aspects.end(); ++i) {
137  threads_[*i].push_back(thread);
138  }
139  } catch (CannotInitializeThreadException &e) {
140  std::list<const char *>::const_reverse_iterator i;
141  for (i = initialized.rbegin(); i != initialized.rend(); ++i) {
142  inifins_[*i]->finalize(thread);
143  }
144  throw;
145  } catch (Exception &e) {
146  std::list<const char *>::const_reverse_iterator i;
147  for (i = initialized.rbegin(); i != initialized.rend(); ++i) {
148  inifins_[*i]->finalize(thread);
149  }
151  ce.append(e);
152  throw ce;
153  }
154  }
155 }
156 
157 void
159 {
160  Aspect *aspected_thread = dynamic_cast<Aspect *>(thread);
161  if (aspected_thread != NULL) { // thread has aspects to finalize
162  const std::list<const char *> &aspects = aspected_thread->get_aspects();
163 
164  std::list<const char *>::const_iterator i;
165  for (i = aspects.begin(); i != aspects.end(); ++i) {
166  if (inifins_.find(*i) == inifins_.end()) {
167  throw CannotFinalizeThreadException("Thread '%s' has the %s, "
168  "but no finalizer is known.",
169  thread->name(),
170  *i);
171  }
172  inifins_[*i]->finalize(thread);
173  }
174 
175  // We remove the threads afterwards, because we assume that the plugin
176  // will not be unloaded, if the finalization throws an exception.
177  for (i = aspects.begin(); i != aspects.end(); ++i) {
178  threads_[*i].remove(thread);
179  }
180  }
181 }
182 
183 bool
185 {
186  Aspect *aspected_thread = dynamic_cast<Aspect *>(thread);
187  if (aspected_thread != NULL) { // thread has aspects to finalize
188  const std::list<const char *> &aspects = aspected_thread->get_aspects();
189 
190  std::list<const char *>::const_iterator i;
191  for (i = aspects.begin(); i != aspects.end(); ++i) {
192  if (inifins_.find(*i) == inifins_.end()) {
193  throw CannotFinalizeThreadException("Thread '%s' has the %s, "
194  "but no finalizer is known.",
195  thread->name(),
196  *i);
197  }
198  if (!inifins_[*i]->prepare_finalize(thread)) {
199  return false;
200  }
201  }
202  }
203 
204  return true;
205 }
206 
207 /** Register default aspect initializer/finalizer.
208  * This loads initializer/finalizer of all aspects which are in the
209  * Fawkes aspect library.
210  * @param blackboard blackboard for BlackBoardAspect and TransformAspect
211  * @param collector thread collector for ThreadProducerAspect
212  * @param config configuration for ConfigurableAspect
213  * @param clock clock for ClockAspect
214  * @param logger logger for LoggingAspect
215  * @param fnethub Fawkes network hub for FawkesNetworkAspect
216  * @param mloop_employer Main loop employer for MainLoopAspect
217  * @param logger_employer logger employer for LoggerAspect
218  * @param btexec blocked timing executor for MainLoopAspect
219  * @param nnresolver network name resolver for NetworkAspect
220  * @param service_publisher service publisher for NetworkAspect
221  * @param service_browser service browser for NetworkAspect
222  * @param pmanager plugin manager for PluginDirectorAspect
223  * @param tf_listener transformer for TransformAspect
224  * @param syncpoint_manager manager for SyncPointManagerAspect
225  */
226 void
228  ThreadCollector * collector,
229  Configuration * config,
230  Logger * logger,
231  Clock * clock,
232  FawkesNetworkHub * fnethub,
233  MainLoopEmployer * mloop_employer,
234  LoggerEmployer * logger_employer,
235  BlockedTimingExecutor *btexec,
236  NetworkNameResolver * nnresolver,
237  ServicePublisher * service_publisher,
238  ServiceBrowser * service_browser,
239  PluginManager * pmanager,
240  tf::Transformer * tf_listener,
241  SyncPointManager * syncpoint_manager)
242 {
243  if (!default_inifins_.empty())
244  return;
245 
247  BlackBoardAspectIniFin * bb_aif = new BlackBoardAspectIniFin(blackboard);
249  ClockAspectIniFin * clock_aif = new ClockAspectIniFin(clock);
250  ConfigurableAspectIniFin * conf_aif = new ConfigurableAspectIniFin(config);
251  FawkesNetworkAspectIniFin * fnet_aif = new FawkesNetworkAspectIniFin(fnethub);
252  LoggerAspectIniFin * logger_aif = new LoggerAspectIniFin(logger_employer);
253  LoggingAspectIniFin * log_aif = new LoggingAspectIniFin(logger);
254  MainLoopAspectIniFin * mloop_aif = new MainLoopAspectIniFin(mloop_employer, btexec);
255  NetworkAspectIniFin * net_aif =
256  new NetworkAspectIniFin(nnresolver, service_publisher, service_browser);
257  PluginDirectorAspectIniFin * plug_aif = new PluginDirectorAspectIniFin(pmanager);
258  ThreadProducerAspectIniFin * tp_aif = new ThreadProducerAspectIniFin(collector);
259  TimeSourceAspectIniFin * ts_aif = new TimeSourceAspectIniFin(clock);
261  VisionAspectIniFin * vis_aif = new VisionAspectIniFin(vm_aif);
262  SyncPointManagerAspectIniFin *spm_aif = new SyncPointManagerAspectIniFin(syncpoint_manager);
263  SyncPointAspectIniFin * sp_aif = new SyncPointAspectIniFin(syncpoint_manager);
264 #ifdef HAVE_WEBVIEW
265  WebviewAspectIniFin *web_aif = new WebviewAspectIniFin();
266 #endif
267 #ifdef HAVE_TF
268  TransformAspectIniFin *tf_aif = new TransformAspectIniFin(blackboard, tf_listener);
269 #endif
270 #ifdef HAVE_PCL
271  PointCloudAspectIniFin *pcl_aif = new PointCloudAspectIniFin(config);
272 #endif
273 
274  default_inifins_[prov_aif->get_aspect_name()] = prov_aif;
275  default_inifins_[bb_aif->get_aspect_name()] = bb_aif;
276  default_inifins_[bt_aif->get_aspect_name()] = bt_aif;
277  default_inifins_[clock_aif->get_aspect_name()] = clock_aif;
278  default_inifins_[conf_aif->get_aspect_name()] = conf_aif;
279  default_inifins_[fnet_aif->get_aspect_name()] = fnet_aif;
280  default_inifins_[logger_aif->get_aspect_name()] = logger_aif;
281  default_inifins_[log_aif->get_aspect_name()] = log_aif;
282  default_inifins_[mloop_aif->get_aspect_name()] = mloop_aif;
283  default_inifins_[net_aif->get_aspect_name()] = net_aif;
284  default_inifins_[plug_aif->get_aspect_name()] = plug_aif;
285  default_inifins_[tp_aif->get_aspect_name()] = tp_aif;
286  default_inifins_[ts_aif->get_aspect_name()] = ts_aif;
287  default_inifins_[vm_aif->get_aspect_name()] = vm_aif;
288  default_inifins_[vis_aif->get_aspect_name()] = vis_aif;
289  default_inifins_[spm_aif->get_aspect_name()] = spm_aif;
290  default_inifins_[sp_aif->get_aspect_name()] = sp_aif;
291 #ifdef HAVE_WEBVIEW
292  default_inifins_[web_aif->get_aspect_name()] = web_aif;
293 #endif
294 #ifdef HAVE_TF
295  default_inifins_[tf_aif->get_aspect_name()] = tf_aif;
296 #endif
297 #ifdef HAVE_PCL
298  default_inifins_[pcl_aif->get_aspect_name()] = pcl_aif;
299 #endif
300 
301  std::map<std::string, AspectIniFin *>::iterator i;
302  for (i = default_inifins_.begin(); i != default_inifins_.end(); ++i) {
303  inifins_[i->first] = i->second;
304  }
305 }
306 
307 } // end namespace fawkes
fawkes::ThreadCollector
Thread collector.
Definition: thread_collector.h:34
fawkes::SyncPointManagerAspectIniFin
Initializer/finalizer for the SyncPointManagerAspect.
Definition: syncpoint_manager.h:32
fawkes::BlackBoardAspectIniFin
Initializer/finalizer for the BlackBoardAspect.
Definition: blackboard.h:34
fawkes::PluginManager
Fawkes Plugin Manager.
Definition: manager.h:48
fawkes::SyncPointManager
This class gives access to SyncPoints.
Definition: syncpoint_manager.h:38
fawkes::TransformAspectIniFin
Initializer/finalizer for the TransformAspect.
Definition: tf.h:36
fawkes::FawkesNetworkAspectIniFin
Initializer/finalizer for the FawkesNetworkAspect.
Definition: fawkes_network.h:34
fawkes::ThreadProducerAspectIniFin
Initializer/finalizer for the ThreadProducerAspect.
Definition: thread_producer.h:34
fawkes::Aspect::get_aspects
const std::list< const char * > & get_aspects() const
Get list of aspect names attached to a aspected thread.
Definition: aspect.cpp:58
fawkes::NetworkNameResolver
Network name and address resolver.
Definition: resolver.h:45
fawkes::NetworkAspectIniFin
Initializer/finalizer for the NetworkAspect.
Definition: network.h:36
fawkes::ServiceBrowser
Service browser.
Definition: service_browser.h:33
fawkes::BlockedTimingExecutor
Blocked timing executor.
Definition: executor.h:37
fawkes::tf::Transformer
Coordinate transforms between any two frames in a system.
Definition: transformer.h:65
fawkes::BlackBoard
The BlackBoard abstract class.
Definition: blackboard.h:46
fawkes::AspectIniFin::get_aspect_name
const char * get_aspect_name() const
Get aspect name.
Definition: inifin.cpp:85
fawkes::VisionAspectIniFin
Initializer/finalizer for the VisionAspect.
Definition: vision.h:35
fawkes::CannotInitializeThreadException
Thread cannot be initialized.
Definition: thread_initializer.h:34
fawkes::BlockedTimingAspectIniFin
Initializer/finalizer for the BlockedTimingAspect.
Definition: blocked_timing.h:32
fawkes::Thread::name
const char * name() const
Get name of thread.
Definition: thread.h:100
fawkes::Configuration
Interface for configuration handling.
Definition: config.h:65
fawkes::Exception::append
void append(const char *format,...)
Append messages to the message list.
Definition: exception.cpp:333
fawkes::AspectManager::init
virtual void init(Thread *thread)
This method is called by the ThreadManager for each newly added Thread.
Definition: manager.cpp:115
fawkes::AspectIniFin
Aspect initializer/finalizer base class.
Definition: inifin.h:34
fawkes::AspectManager::finalize
virtual void finalize(Thread *thread)
Finalize a thread.
Definition: manager.cpp:158
fawkes::MainLoopAspectIniFin
Initializer/finalizer for the MainLoopAspect.
Definition: mainloop.h:38
fawkes::Logger
Interface for logging.
Definition: logger.h:42
fawkes
Fawkes library namespace.
fawkes::ServicePublisher
Service publisher interface.
Definition: service_publisher.h:32
fawkes::Aspect
Fawkes aspect base class.
Definition: aspect.h:32
fawkes::ConfigurableAspectIniFin
Initializer/finalizer for the ConfigurableAspect.
Definition: configurable.h:34
fawkes::AspectProviderAspectIniFin
Initializer/finalizer for the AspectProviderAspect.
Definition: aspect_provider.h:34
fawkes::LoggerAspectIniFin
Initializer/finalizer for the LoggerAspect.
Definition: logger.h:35
fawkes::AspectManager::~AspectManager
virtual ~AspectManager()
Constructor.
Definition: manager.cpp:64
fawkes::Thread
Thread class encapsulation of pthreads.
Definition: thread.h:46
fawkes::AspectManager::register_inifin
void register_inifin(AspectIniFin *inifin)
Register initializer/finalizer.
Definition: manager.cpp:77
fawkes::PluginDirectorAspectIniFin
Initializer/finalizer for the PluginDirectorAspect.
Definition: plugin_director.h:34
fawkes::MainLoopEmployer
Main loop employer The MainLoopEmployer calls the main loop for execution.
Definition: employer.h:32
fawkes::LoggerEmployer
Logger employer The LoggerEmployer shall pipe all log messages of the system to added loggers.
Definition: logger_employer.h:37
fawkes::LoggingAspectIniFin
Initializer/finalizer for the LoggingAspect.
Definition: logging.h:34
fawkes::TimeSourceAspectIniFin
Initializer/finalizer for the TimeSourceAspect.
Definition: time_source.h:36
fawkes::SyncPointAspectIniFin
Initializer/finalizer for the SyncPointAspect.
Definition: syncpoint.h:32
fawkes::FawkesNetworkHub
Fawkes Network Hub.
Definition: hub.h:34
fawkes::AspectManager::has_threads_for_aspect
bool has_threads_for_aspect(const char *aspect_name)
Check if threads for a particular aspect still exist.
Definition: manager.cpp:109
fawkes::CannotFinalizeThreadException
Thread cannot be finalized.
Definition: thread_finalizer.h:34
fawkes::ClockAspectIniFin
Initializer/finalizer for the ClockAspect.
Definition: clock.h:34
fawkes::VisionMasterAspectIniFin
Initializer/finalizer for the VisionMasterAspect.
Definition: vision_master.h:39
fawkes::PointCloudAspectIniFin
Initializer/finalizer for the PointCloudAspect.
Definition: pointcloud.h:32
fawkes::AspectManager::unregister_inifin
void unregister_inifin(AspectIniFin *inifin)
Unregister initializer/finalizer.
Definition: manager.cpp:89
fawkes::Clock
This is supposed to be the central clock in Fawkes.
Definition: clock.h:35
fawkes::AspectManager::register_default_inifins
void register_default_inifins(BlackBoard *blackboard, ThreadCollector *collector, Configuration *config, Logger *logger, Clock *clock, FawkesNetworkHub *fnethub, MainLoopEmployer *mloop_employer, LoggerEmployer *logger_employer, BlockedTimingExecutor *btexec, NetworkNameResolver *nnresolver, ServicePublisher *service_publisher, ServiceBrowser *service_browser, PluginManager *pmanager, tf::Transformer *tf_listener, SyncPointManager *syncpoint_manager)
Register default aspect initializer/finalizer.
Definition: manager.cpp:227
fawkes::AspectManager::prepare_finalize
virtual bool prepare_finalize(Thread *thread)
Prepare finalization of a thread.
Definition: manager.cpp:184
fawkes::WebviewAspectIniFin
Initializer/finalizer for the WebviewAspect.
Definition: webview.h:33
fawkes::Exception
Base class for exceptions in Fawkes.
Definition: exception.h:36