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/manager.h>
25 #include <aspect/inifins/aspect_provider.h>
26 #include <aspect/inifins/blackboard.h>
27 #include <aspect/inifins/blocked_timing.h>
28 #include <aspect/inifins/clock.h>
29 #include <aspect/inifins/configurable.h>
30 #include <aspect/inifins/fawkes_network.h>
31 #include <aspect/inifins/logger.h>
32 #include <aspect/inifins/logging.h>
33 #include <aspect/inifins/mainloop.h>
34 #include <aspect/inifins/network.h>
35 #include <aspect/inifins/plugin_director.h>
36 #include <aspect/inifins/thread_producer.h>
37 #include <aspect/inifins/time_source.h>
38 #include <aspect/inifins/vision_master.h>
39 #include <aspect/inifins/vision.h>
40 #ifdef HAVE_WEBVIEW
41 # include <aspect/inifins/webview.h>
42 #endif
43 #ifdef HAVE_TF
44 # include <aspect/inifins/tf.h>
45 #endif
46 #ifdef HAVE_PCL
47 # include <aspect/inifins/pointcloud.h>
48 #endif
49 
50 namespace fawkes {
51 #if 0 /* just to make Emacs auto-indent happy */
52 }
53 #endif
54 
55 /** @class AspectManager <aspect/manager.h>
56  * Aspect and aspect initializer/finalizer manager.
57  * This class is the central gatekeeper to aspects for the main application.
58  * It manages the initializers/finalizers and thus the aspects which are
59  * currently available in the system. It assures that these are not removed
60  * before the last thread with an aspect is gone.
61  * @author Tim Niemueller
62  */
63 
64 /** Constructor. */
66 {
67  std::map<std::string, AspectIniFin *>::iterator i;
68  for (i = __default_inifins.begin(); i != __default_inifins.end(); ++i) {
69  delete i->second;
70  }
71  __default_inifins.clear();
72 }
73 
74 /** Register initializer/finalizer.
75  * @param inifin aspect initializer/finalizer to register
76  */
77 void
79 {
80  if (__inifins.find(inifin->get_aspect_name()) != __inifins.end()) {
81  throw Exception("An initializer for %s has already been registered",
82  inifin->get_aspect_name());
83  }
84  __inifins[inifin->get_aspect_name()] = inifin;
85 }
86 
87 /** Unregister initializer/finalizer.
88  * @param inifin aspect initializer/finalizer to unregister
89  */
90 void
92 {
93  if (__inifins.find(inifin->get_aspect_name()) == __inifins.end()) {
94  throw Exception("An initializer for %s has not been registered",
95  inifin->get_aspect_name());
96  }
97  if (! __threads[inifin->get_aspect_name()].empty()) {
98  throw Exception("Threads with the %s aspect are still alive, cannot "
99  "unregister the aspect", inifin->get_aspect_name());
100  }
101  __inifins.erase(inifin->get_aspect_name());
102  __threads.erase(inifin->get_aspect_name());
103 }
104 
105 /** Check if threads for a particular aspect still exist.
106  * @param aspect_name name of the aspect to check for
107  * @return true if thread for the given aspect have been registered,
108  * false otherwise
109  */
110 bool
112 {
113  return (__threads.find(aspect_name) != __threads.end()) &&
114  (! __threads[aspect_name].empty());
115 }
116 
117 void
119 {
120  Aspect *aspected_thread = dynamic_cast<Aspect *>(thread);
121  if (aspected_thread != NULL) { // thread has aspects to initialize
122  const std::list<const char *> &aspects = aspected_thread->get_aspects();
123 
124  std::list<const char *> initialized;
125 
126  try {
127  std::list<const char *>::const_iterator i;
128  for (i = aspects.begin(); i != aspects.end(); ++i) {
129  if (__inifins.find(*i) == __inifins.end()) {
130  throw CannotInitializeThreadException("Thread '%s' has the %s, "
131  "but no initiliazer is known.",
132  thread->name(), *i);
133  }
134  __inifins[*i]->init(thread);
135  initialized.push_back(*i);
136  }
137 
138  for (i = aspects.begin(); i != aspects.end(); ++i) {
139  __threads[*i].push_back(thread);
140  }
141  } catch (CannotInitializeThreadException &e) {
142  std::list<const char *>::const_reverse_iterator i;
143  for (i = initialized.rbegin(); i != initialized.rend(); ++i) {
144  __inifins[*i]->finalize(thread);
145  }
146  throw;
147  } catch (Exception &e) {
148  std::list<const char *>::const_reverse_iterator i;
149  for (i = initialized.rbegin(); i != initialized.rend(); ++i) {
150  __inifins[*i]->finalize(thread);
151  }
153  ce.append(e);
154  throw ce;
155  }
156  }
157 }
158 
160 {
161  Aspect *aspected_thread = dynamic_cast<Aspect *>(thread);
162  if (aspected_thread != NULL) { // thread has aspects to finalize
163  const std::list<const char *> &aspects = aspected_thread->get_aspects();
164 
165  std::list<const char *>::const_iterator i;
166  for (i = aspects.begin(); i != aspects.end(); ++i) {
167  if (__inifins.find(*i) == __inifins.end()) {
168  throw CannotFinalizeThreadException("Thread '%s' has the %s, "
169  "but no finalizer is known.",
170  thread->name(), *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 
184 bool
186 {
187  Aspect *aspected_thread = dynamic_cast<Aspect *>(thread);
188  if (aspected_thread != NULL) { // thread has aspects to finalize
189  const std::list<const char *> &aspects = aspected_thread->get_aspects();
190 
191  std::list<const char *>::const_iterator i;
192  for (i = aspects.begin(); i != aspects.end(); ++i) {
193  if (__inifins.find(*i) == __inifins.end()) {
194  throw CannotFinalizeThreadException("Thread '%s' has the %s, "
195  "but no finalizer is known.",
196  thread->name(), *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  */
225 void
227  ThreadCollector *collector,
228  Configuration *config,
229  Logger *logger,
230  Clock *clock,
231  FawkesNetworkHub *fnethub,
232  MainLoopEmployer *mloop_employer,
233  LoggerEmployer *logger_employer,
234  BlockedTimingExecutor *btexec,
235  NetworkNameResolver *nnresolver,
236  ServicePublisher *service_publisher,
237  ServiceBrowser *service_browser,
238  PluginManager *pmanager,
239  tf::Transformer *tf_listener)
240 {
241  if (! __default_inifins.empty()) return;
242 
244  BlackBoardAspectIniFin *bb_aif = new BlackBoardAspectIniFin(blackboard);
246  ClockAspectIniFin *clock_aif = new ClockAspectIniFin(clock);
247  ConfigurableAspectIniFin *conf_aif = new ConfigurableAspectIniFin(config);
248  FawkesNetworkAspectIniFin *fnet_aif = new FawkesNetworkAspectIniFin(fnethub);
249  LoggerAspectIniFin *logger_aif = new LoggerAspectIniFin(logger_employer);
250  LoggingAspectIniFin *log_aif = new LoggingAspectIniFin(logger);
251  MainLoopAspectIniFin *mloop_aif = new MainLoopAspectIniFin(mloop_employer,
252  btexec);
253  NetworkAspectIniFin *net_aif = new NetworkAspectIniFin(nnresolver,
254  service_publisher,
255  service_browser);
256  PluginDirectorAspectIniFin *plug_aif = new PluginDirectorAspectIniFin(pmanager);
258  TimeSourceAspectIniFin *ts_aif = new TimeSourceAspectIniFin(clock);
260  VisionAspectIniFin *vis_aif = new VisionAspectIniFin(vm_aif);
261 #ifdef HAVE_WEBVIEW
262  WebviewAspectIniFin *web_aif = new WebviewAspectIniFin();
263 #endif
264 #ifdef HAVE_TF
265  TransformAspectIniFin *tf_aif = new TransformAspectIniFin(blackboard, tf_listener);
266 #endif
267 #ifdef HAVE_PCL
268  PointCloudAspectIniFin *pcl_aif = new PointCloudAspectIniFin(config);
269 #endif
270 
271 
272  __default_inifins[prov_aif->get_aspect_name()] = prov_aif;
273  __default_inifins[bb_aif->get_aspect_name()] = bb_aif;
274  __default_inifins[bt_aif->get_aspect_name()] = bt_aif;
275  __default_inifins[clock_aif->get_aspect_name()] = clock_aif;
276  __default_inifins[conf_aif->get_aspect_name()] = conf_aif;
277  __default_inifins[fnet_aif->get_aspect_name()] = fnet_aif;
278  __default_inifins[logger_aif->get_aspect_name()] = logger_aif;
279  __default_inifins[log_aif->get_aspect_name()] = log_aif;
280  __default_inifins[mloop_aif->get_aspect_name()] = mloop_aif;
281  __default_inifins[net_aif->get_aspect_name()] = net_aif;
282  __default_inifins[plug_aif->get_aspect_name()] = plug_aif;
283  __default_inifins[tp_aif->get_aspect_name()] = tp_aif;
284  __default_inifins[ts_aif->get_aspect_name()] = ts_aif;
285  __default_inifins[vm_aif->get_aspect_name()] = vm_aif;
286  __default_inifins[vis_aif->get_aspect_name()] = vis_aif;
287 #ifdef HAVE_WEBVIEW
288  __default_inifins[web_aif->get_aspect_name()] = web_aif;
289 #endif
290 #ifdef HAVE_TF
291  __default_inifins[tf_aif->get_aspect_name()] = tf_aif;
292 #endif
293 #ifdef HAVE_PCL
294  __default_inifins[pcl_aif->get_aspect_name()] = pcl_aif;
295 #endif
296 
297  std::map<std::string, AspectIniFin *>::iterator i;
298  for (i = __default_inifins.begin(); i != __default_inifins.end(); ++i) {
299  __inifins[i->first] = i->second;
300  }
301 }
302 
303 } // end namespace fawkes
Service browser.
Initializer/finalizer for the BlockedTimingAspect.
Service publisher interface.
virtual void init(Thread *thread)
This method is called by the ThreadManager for each newly added Thread.
Definition: manager.cpp:118
Initializer/finalizer for the WebviewAspect.
Definition: webview.h:35
Initializer/finalizer for the AspectProviderAspect.
Initializer/finalizer for the MainLoopAspect.
Definition: mainloop.h:40
Fawkes aspect base class.
Definition: aspect.h:34
Fawkes library namespace.
This is supposed to be the central clock in Fawkes.
Definition: clock.h:34
Initializer/finalizer for the ConfigurableAspect.
Definition: configurable.h:36
Logger employer The LoggerEmployer shall pipe all log messages of the system to added loggers...
Initializer/finalizer for the LoggerAspect.
Definition: logger.h:37
Thread collector.
Initializer/finalizer for the PointCloudAspect.
Definition: pointcloud.h:34
virtual ~AspectManager()
Constructor.
Definition: manager.cpp:65
Thread class encapsulation of pthreads.
Definition: thread.h:42
void register_inifin(AspectIniFin *inifin)
Register initializer/finalizer.
Definition: manager.cpp:78
Fawkes Plugin Manager.
Definition: manager.h:51
void unregister_inifin(AspectIniFin *inifin)
Unregister initializer/finalizer.
Definition: manager.cpp:91
Initializer/finalizer for the TimeSourceAspect.
Definition: time_source.h:38
Fawkes Network Hub.
Definition: hub.h:33
Initializer/finalizer for the NetworkAspect.
Definition: network.h:38
Thread cannot be initialized.
Initializer/finalizer for the BlackBoardAspect.
Definition: blackboard.h:36
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)
Register default aspect initializer/finalizer.
Definition: manager.cpp:226
Base class for exceptions in Fawkes.
Definition: exception.h:36
Blocked timing executor.
Definition: executor.h:35
const char * name() const
Get name of thread.
Definition: thread.h:95
virtual bool prepare_finalize(Thread *thread)
Prepare finalization of a thread.
Definition: manager.cpp:185
Initializer/finalizer for the ThreadProducerAspect.
bool has_threads_for_aspect(const char *aspect_name)
Check if threads for a particular aspect still exist.
Definition: manager.cpp:111
Initializer/finalizer for the ClockAspect.
Definition: clock.h:36
Main loop employer The MainLoopEmployer calls the main loop for execution.
Definition: employer.h:31
const std::list< const char * > & get_aspects() const
Get list of aspect names attached to a aspected thread.
Definition: aspect.cpp:62
Network name and address resolver.
Definition: resolver.h:48
const char * get_aspect_name() const
Get aspect name.
Definition: inifin.cpp:88
Initializer/finalizer for the FawkesNetworkAspect.
Thread cannot be finalized.
Initializer/finalizer for the VisionAspect.
Definition: vision.h:37
The BlackBoard abstract class.
Definition: blackboard.h:48
Initializer/finalizer for the PluginDirectorAspect.
Coordinate transforms between any two frames in a system.
Definition: transformer.h:68
virtual void finalize(Thread *thread)
Finalize a thread.
Definition: manager.cpp:159
Interface for configuration handling.
Definition: config.h:67
Initializer/finalizer for the LoggingAspect.
Definition: logging.h:36
void append(const char *format,...)
Append messages to the message list.
Definition: exception.cpp:341
Initializer/finalizer for the VisionMasterAspect.
Definition: vision_master.h:41
Aspect initializer/finalizer base class.
Definition: inifin.h:36
Initializer/finalizer for the TransformAspect.
Definition: tf.h:39
Interface for logging.
Definition: logger.h:34