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
52namespace 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 */
76void
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 */
88void
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 */
108bool
110{
111 return (threads_.find(aspect_name) != threads_.end()) && (!threads_[aspect_name].empty());
112}
113
114void
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 }
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
157void
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
183bool
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 */
226void
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);
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);
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
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
Aspect initializer/finalizer base class.
Definition: inifin.h:34
const char * get_aspect_name() const
Get aspect name.
Definition: inifin.cpp:85
virtual bool prepare_finalize(Thread *thread)
Prepare finalization of a thread.
Definition: manager.cpp:184
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
virtual void finalize(Thread *thread)
Finalize a thread.
Definition: manager.cpp:158
virtual void init(Thread *thread)
This method is called by the ThreadManager for each newly added Thread.
Definition: manager.cpp:115
void register_inifin(AspectIniFin *inifin)
Register initializer/finalizer.
Definition: manager.cpp:77
void unregister_inifin(AspectIniFin *inifin)
Unregister initializer/finalizer.
Definition: manager.cpp:89
bool has_threads_for_aspect(const char *aspect_name)
Check if threads for a particular aspect still exist.
Definition: manager.cpp:109
virtual ~AspectManager()
Constructor.
Definition: manager.cpp:64
Initializer/finalizer for the AspectProviderAspect.
Fawkes aspect base class.
Definition: aspect.h:32
const std::list< const char * > & get_aspects() const
Get list of aspect names attached to a aspected thread.
Definition: aspect.cpp:58
Initializer/finalizer for the BlackBoardAspect.
Definition: blackboard.h:34
The BlackBoard abstract class.
Definition: blackboard.h:46
Initializer/finalizer for the BlockedTimingAspect.
Blocked timing executor.
Definition: executor.h:37
Thread cannot be finalized.
Initializer/finalizer for the ClockAspect.
Definition: clock.h:34
This is supposed to be the central clock in Fawkes.
Definition: clock.h:35
Initializer/finalizer for the ConfigurableAspect.
Definition: configurable.h:34
Interface for configuration handling.
Definition: config.h:68
Base class for exceptions in Fawkes.
Definition: exception.h:36
void append(const char *format,...) noexcept
Append messages to the message list.
Definition: exception.cpp:333
Initializer/finalizer for the FawkesNetworkAspect.
Fawkes Network Hub.
Definition: hub.h:34
Initializer/finalizer for the LoggerAspect.
Definition: logger.h:35
Logger employer The LoggerEmployer shall pipe all log messages of the system to added loggers.
Interface for logging.
Definition: logger.h:42
Initializer/finalizer for the LoggingAspect.
Definition: logging.h:34
Initializer/finalizer for the MainLoopAspect.
Definition: mainloop.h:38
Main loop employer The MainLoopEmployer calls the main loop for execution.
Definition: employer.h:32
Initializer/finalizer for the NetworkAspect.
Definition: network.h:36
Network name and address resolver.
Definition: resolver.h:45
Initializer/finalizer for the PluginDirectorAspect.
Fawkes Plugin Manager.
Definition: manager.h:48
Initializer/finalizer for the PointCloudAspect.
Definition: pointcloud.h:32
Service browser.
Service publisher interface.
Initializer/finalizer for the SyncPointAspect.
Definition: syncpoint.h:32
Initializer/finalizer for the SyncPointManagerAspect.
This class gives access to SyncPoints.
Initializer/finalizer for the ThreadProducerAspect.
Thread class encapsulation of pthreads.
Definition: thread.h:46
const char * name() const
Get name of thread.
Definition: thread.h:100
Initializer/finalizer for the TimeSourceAspect.
Definition: time_source.h:36
Initializer/finalizer for the TransformAspect.
Definition: tf.h:36
Initializer/finalizer for the VisionAspect.
Definition: vision.h:35
Initializer/finalizer for the VisionMasterAspect.
Definition: vision_master.h:39
Initializer/finalizer for the WebviewAspect.
Definition: webview.h:33
Coordinate transforms between any two frames in a system.
Definition: transformer.h:65
Fawkes library namespace.