FlightGear next
subsystemFactory.cxx
Go to the documentation of this file.
1// subsystemFactory.cxx - factory for subsystems
2//
3// Copyright (C) 2012 James Turner zakalawe@mac.com
4//
5// This program is free software; you can redistribute it and/or
6// modify it under the terms of the GNU General Public License as
7// published by the Free Software Foundation; either version 2 of the
8// License, or (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful, but
11// WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13// General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program; if not, write to the Free Software
17// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18
19#ifdef HAVE_CONFIG_H
20 #include "config.h"
21#endif
22
23#include "subsystemFactory.hxx"
24
25#include <simgear/structure/subsystem_mgr.hxx>
26#include <simgear/structure/exception.hxx>
27#include <simgear/debug/logstream.hxx>
28#include <simgear/structure/commands.hxx>
29#include <simgear/structure/event_mgr.hxx>
30
31#include <Main/globals.hxx>
33
34// subsystem includes
35#include <Aircraft/controls.hxx>
37#include <Main/fg_props.hxx>
39#include <Main/fg_io.hxx>
40#include <FDM/fdm_shell.hxx>
48#include <Network/fgcom.hxx>
50#include <GUI/new_gui.hxx>
51#include <Main/logger.hxx>
52#include <ATC/atc_mgr.hxx>
53#include <AIModel/AIManager.hxx>
55#if defined(ENABLE_SWIFT)
57#endif
58#include <AIModel/submodel.hxx>
59#include <Aircraft/controls.hxx>
60#include <Input/input.hxx>
61#include <Aircraft/replay.hxx>
62#include <Sound/voice.hxx>
63#include <Canvas/canvas_mgr.hxx>
64#include <Canvas/gui_mgr.hxx>
65#include <Time/light.hxx>
66#include <Viewer/viewmgr.hxx>
67#include <Model/acmodel.hxx>
68#include <Model/modelmgr.hxx>
69
70using std::vector;
71
72namespace flightgear
73{
74
75SGSubsystem* createSubsystemByName(const std::string& name)
76{
77#define MAKE_SUB(cl, n) \
78 if (name == n) return new cl;
79
80 MAKE_SUB(FGSoundManager, "sound");
81 MAKE_SUB(FGInterpolator, "prop-interpolator")
82 MAKE_SUB(FGProperties, "properties");
83 MAKE_SUB(FGHTTPClient, "http");
84 MAKE_SUB(FDMShell, "flight");
85 MAKE_SUB(FGEnvironmentMgr, "environment");
86 MAKE_SUB(Ephemeris, "ephemeris");
87 MAKE_SUB(FGSystemMgr, "systems");
88 MAKE_SUB(FGInstrumentMgr, "instrumentation");
89 MAKE_SUB(FGRouteMgr, "route-manager");
90 MAKE_SUB(FGIO, "io");
91 MAKE_SUB(FGLogger, "logger");
92 MAKE_SUB(NewGUI, "gui");
93 MAKE_SUB(CanvasMgr, "Canvas");
94 MAKE_SUB(GUIMgr, "CanvasGUI");
95 MAKE_SUB(FGATCManager, "ATC");
97 MAKE_SUB(FGAIManager, "ai-model");
98 MAKE_SUB(FGSubmodelMgr, "submodel-mgr");
99 MAKE_SUB(FGTrafficManager, "traffic-manager");
100 MAKE_SUB(FGControls, "controls");
101 MAKE_SUB(FGInput, "input");
102 MAKE_SUB(FGReplay, "replay");
103 MAKE_SUB(FGFlightHistory, "history");
104#ifdef ENABLE_AUDIO_SUPPORT
105 MAKE_SUB(FGVoiceMgr, "voice");
106#endif
107#ifdef ENABLE_IAX
108 MAKE_SUB(FGCom, "fgcom");
109#endif
110#ifdef ENABLE_SWIFT
112#endif
113 MAKE_SUB(FGLight, "tides");
114 MAKE_SUB(FGLight, "lighting");
115 MAKE_SUB(FGAircraftModel, "aircraft-model");
116 MAKE_SUB(FGModelMgr, "model-manager");
117 MAKE_SUB(FGViewMgr, "view-manager");
118#undef MAKE_SUB
119
120 throw sg_range_exception("unknown subsystem:" + name);
121}
122
123SGSubsystemMgr::GroupType mapGroupNameToType(const std::string& s)
124{
125 if (s == "init") return SGSubsystemMgr::INIT;
126 if (s == "general") return SGSubsystemMgr::GENERAL;
127 if (s == "fdm") return SGSubsystemMgr::FDM;
128 if (s == "post-fdm") return SGSubsystemMgr::POST_FDM;
129 if (s == "display") return SGSubsystemMgr::DISPLAY;
130 if (s == "sound") return SGSubsystemMgr::SOUND;
131
132 SG_LOG(SG_GENERAL, SG_ALERT, "unrecognized subsystem group:" << s);
133 return SGSubsystemMgr::GENERAL;
134}
135
136static SGSubsystem* getSubsystem(const SGPropertyNode* arg, bool create)
137{
138 std::string subsystem(arg->getStringValue("subsystem"));
139 std::string name = arg->getStringValue("name");
140
141 if (name.empty()) {
142 // default name is simply the subsytem's name
143 name = subsystem;
144 }
145
146 SGSubsystem* sys = globals->get_subsystem_mgr()->get_subsystem(name);
147 if (!create)
148 return sys;
149
150 if( subsystem.empty() ) {
151 SG_LOG( SG_GENERAL,
152 SG_ALERT,
153 "do_add_subsystem: no subsystem/name supplied" );
154 return 0;
155 }
156
157 if (sys) {
158 SG_LOG( SG_GENERAL,
159 SG_ALERT,
160 "do_add_subsystem: duplicate subsystem name:" << name );
161 return 0;
162 }
163
164 std::string groupname = arg->getStringValue("group");
165 SGSubsystemMgr::GroupType group = SGSubsystemMgr::GENERAL;
166 if (!groupname.empty()) {
167 group = mapGroupNameToType(groupname);
168 }
169
170 try {
171 sys = createSubsystemByName(subsystem);
172 } catch (sg_exception& e) {
173 SG_LOG( SG_GENERAL,
174 SG_ALERT,
175 "subsystem creation failed:" << name
176 << ":" << e.getFormattedMessage() );
177 return 0;
178 }
179
180 bool doInit = arg->getBoolValue("do-bind-init", false);
181 if (doInit) {
182 sys->bind();
183 sys->init();
184 }
185
186 double minTime = arg->getDoubleValue("min-time-sec", 0.0);
187 globals->get_subsystem_mgr()
188 ->add(name.c_str(), sys, group, minTime);
189
190 return sys;
191}
192
193static bool
194do_check_subsystem_running(const SGPropertyNode * arg, SGPropertyNode * root)
195{
196 return getSubsystem(arg, false) != 0;
197}
198
199static bool
200do_add_subsystem (const SGPropertyNode * arg, SGPropertyNode * root)
201{
202 return getSubsystem(arg, true) != 0;
203}
204
205static bool do_remove_subsystem(const SGPropertyNode * arg, SGPropertyNode * root)
206{
207 std::string name = arg->getStringValue("subsystem");
208
209 SGSubsystem* instance = globals->get_subsystem_mgr()->get_subsystem(name);
210 if (!instance) {
211 SG_LOG(SG_GENERAL, SG_ALERT, "do_remove_subsystem: unknown subsytem:" << name);
212 return false;
213 }
214
215 // is it safe to always call these? let's assume so!
216 instance->shutdown();
217 instance->unbind();
218
219 // unplug from the manager (this also deletes the instance!)
220 globals->get_subsystem_mgr()->remove(name.c_str());
221
222 return true;
223}
224
231static bool
232do_reinit (const SGPropertyNode * arg, SGPropertyNode * root)
233{
234 bool result = true;
235
236 vector<SGPropertyNode_ptr> subsystems = arg->getChildren("subsystem");
237 if (subsystems.empty()) {
238 globals->get_subsystem_mgr()->reinit();
239 } else {
240 for ( unsigned int i = 0; i < subsystems.size(); i++ ) {
241 std::string name = subsystems[i]->getStringValue();
242 SGSubsystem * subsystem = globals->get_subsystem_mgr()->get_subsystem(name.c_str());
243 if (subsystem == 0) {
244 result = false;
245 SG_LOG( SG_GENERAL, SG_ALERT,
246 "Subsystem " << name << " not found" );
247 } else {
248 subsystem->reinit();
249 }
250 }
251 }
252
253 globals->get_event_mgr()->reinit();
254
255 return result;
256}
257
263static bool
264do_suspend (const SGPropertyNode * arg, SGPropertyNode * root)
265{
266 bool result = true;
267
268 vector<SGPropertyNode_ptr> subsystems = arg->getChildren("subsystem");
269 for ( unsigned int i = 0; i < subsystems.size(); i++ ) {
270 std::string name = subsystems[i]->getStringValue();
271 SGSubsystem * subsystem = globals->get_subsystem_mgr()->get_subsystem(name.c_str());
272 if (subsystem == 0) {
273 result = false;
274 SG_LOG(SG_GENERAL, SG_ALERT, "Subsystem " << name << " not found");
275 } else {
276 subsystem->suspend();
277 }
278 }
279 return result;
280}
281
287static bool
288do_resume (const SGPropertyNode * arg, SGPropertyNode * root)
289{
290 bool result = true;
291
292 vector<SGPropertyNode_ptr> subsystems = arg->getChildren("subsystem");
293 for ( unsigned int i = 0; i < subsystems.size(); i++ ) {
294 std::string name = subsystems[i]->getStringValue();
295 SGSubsystem * subsystem = globals->get_subsystem_mgr()->get_subsystem(name.c_str());
296 if (subsystem == 0) {
297 result = false;
298 SG_LOG(SG_GENERAL, SG_ALERT, "Subsystem " << name << " not found");
299 } else {
300 subsystem->resume();
301 }
302 }
303 return result;
304}
305
306static struct {
307 const char * name;
308 SGCommandMgr::command_t command;
309} built_ins [] = {
310 { "add-subsystem", do_add_subsystem },
311 { "remove-subsystem", do_remove_subsystem },
312 { "subsystem-running", do_check_subsystem_running },
313 { "reinit", do_reinit },
314 { "suspend", do_suspend },
315 { "resume", do_resume },
316 { 0, 0 } // zero-terminated
318
319void registerSubsystemCommands(SGCommandMgr* cmdMgr)
320{
321 for (int i = 0; built_ins[i].name != 0; i++) {
322 cmdMgr->addCommand(built_ins[i].name, built_ins[i].command);
323 }
324}
325
326} // of namepace flightgear
#define i(x)
Wrap SGEphemeris in a subsystem/property interface.
Definition ephemeris.hxx:37
Wrap an FDM implementation in a subsystem with standard semantics Notably, deal with the various case...
Definition fdm_shell.hxx:44
Manage environment information.
record the history of the aircraft's movements, making it available as a contiguous block.
Definition fg_io.hxx:21
Generic input module.
Definition input.hxx:46
Manage aircraft instruments.
Log any property values to any number of CSV files.
Definition logger.hxx:21
Manage a list of user-specified models.
Definition modelmgr.hxx:26
Top level route manager class.
Definition route_mgr.hxx:27
Manage aircraft systems.
XML-configured GUI subsystem.
Definition new_gui.hxx:31
static struct @067026177365276227015073311113211264353134373250 built_ins[]
Table of built-in commands.
FGGlobals * globals
Definition globals.cxx:142
FlightPlan.hxx - defines a full flight-plan object, including departure, cruise, arrival information ...
Definition Addon.cxx:53
static bool do_resume(const SGPropertyNode *arg, SGPropertyNode *root)
Built-in command: suspend one or more subsystems.
SGSubsystem * createSubsystemByName(const std::string &name)
create a subsystem by name, and return it.
SGSubsystemMgr::GroupType mapGroupNameToType(const std::string &s)
void registerSubsystemCommands(SGCommandMgr *cmdMgr)
const char * name
static bool do_reinit(const SGPropertyNode *arg, SGPropertyNode *root)
Built-in command: reinitialize one or more subsystems.
static struct flightgear::@155217300064376130365011127241277321035041155211 built_ins[]
static bool do_check_subsystem_running(const SGPropertyNode *arg, SGPropertyNode *root)
static bool do_add_subsystem(const SGPropertyNode *arg, SGPropertyNode *root)
static bool do_suspend(const SGPropertyNode *arg, SGPropertyNode *root)
Built-in command: suspend one or more subsystems.
static bool do_remove_subsystem(const SGPropertyNode *arg, SGPropertyNode *root)
SGCommandMgr::command_t command
static SGSubsystem * getSubsystem(const SGPropertyNode *arg, bool create)
#define MAKE_SUB(cl, n)