1 // subsystemFactory.cxx - factory for subsystems
3 // Copyright (C) 2012 James Turner zakalawe@mac.com
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.
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.
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.
23 #include "subsystemFactory.hxx"
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>
31 #include <Main/globals.hxx>
32 #include <Sound/soundmanager.hxx>
35 #include <Aircraft/controls.hxx>
36 #include <simgear/misc/interpolator.hxx>
37 #include <Main/fg_props.hxx>
38 #include <Main/fg_io.hxx>
39 #include <FDM/fdm_shell.hxx>
40 #include <Environment/environment_mgr.hxx>
41 #include <Environment/ephemeris.hxx>
42 #include <Instrumentation/instrument_mgr.hxx>
43 #include <Instrumentation/HUD/HUD.hxx>
44 #include <Systems/system_mgr.hxx>
45 #include <Autopilot/route_mgr.hxx>
46 #include <Autopilot/autopilotgroup.hxx>
47 #include <Traffic/TrafficMgr.hxx>
54 SGSubsystem* createSubsystemByName(const std::string& name)
56 #define MAKE_SUB(cl, n) \
57 if (name == n) return new cl;
59 MAKE_SUB(FGControls, "controls");
60 MAKE_SUB(FGSoundManager, "sound");
61 MAKE_SUB(SGInterpolator, "interpolator");
62 MAKE_SUB(FGProperties, "properties");
63 MAKE_SUB(FDMShell, "fdm");
64 MAKE_SUB(FGEnvironmentMgr, "environment");
65 MAKE_SUB(Ephemeris, "ephemeris");
66 MAKE_SUB(FGSystemMgr, "aircraft-systems");
67 MAKE_SUB(FGInstrumentMgr, "instruments");
70 MAKE_SUB(FGRouteMgr, "route-manager");
72 MAKE_SUB(FGTrafficManager, "traffic-manager");
76 throw sg_range_exception("unknown subsystem:" + name);
79 SGSubsystemMgr::GroupType mapGroupNameToType(const std::string& s)
81 if (s == "init") return SGSubsystemMgr::INIT;
82 if (s == "general") return SGSubsystemMgr::GENERAL;
83 if (s == "fdm") return SGSubsystemMgr::FDM;
84 if (s == "post-fdm") return SGSubsystemMgr::POST_FDM;
85 if (s == "display") return SGSubsystemMgr::DISPLAY;
86 if (s == "sound") return SGSubsystemMgr::SOUND;
88 SG_LOG(SG_GENERAL, SG_ALERT, "unrecognized subsystem group:" << s);
89 return SGSubsystemMgr::GENERAL;
93 do_add_subsystem (const SGPropertyNode * arg)
95 std::string subsystem(arg->getStringValue("subsystem"));
96 std::string name = arg->getStringValue("name");
97 if (subsystem.empty() || name.empty()) {
98 SG_LOG(SG_GENERAL, SG_ALERT, "do_add_subsystem:"
99 << "no subsystem/name supplied");
103 if (globals->get_subsystem_mgr()->get_subsystem(name)) {
104 SG_LOG(SG_GENERAL, SG_ALERT, "do_add_subsystem:"
105 << "duplicate subsystem name:" << name);
109 std::string groupname = arg->getStringValue("group");
110 SGSubsystemMgr::GroupType group = SGSubsystemMgr::GENERAL;
111 if (!groupname.empty()) {
112 group = mapGroupNameToType(groupname);
115 SGSubsystem* instance = NULL;
117 instance = createSubsystemByName(subsystem);
118 } catch (sg_exception& e) {
119 SG_LOG(SG_GENERAL, SG_ALERT, "subsystem creation failed:" <<
120 name << ":" << e.getFormattedMessage());
124 bool doInit = arg->getBoolValue("do-bind-init", false);
130 double minTime = arg->getDoubleValue("min-time-sec", 0.0);
131 globals->get_subsystem_mgr()->add(name.c_str(), instance,
137 static bool do_remove_subsystem(const SGPropertyNode * arg)
139 std::string name = arg->getStringValue("subsystem");
141 SGSubsystem* instance = globals->get_subsystem_mgr()->get_subsystem(name);
143 SG_LOG(SG_GENERAL, SG_ALERT, "do_remove_subsystem: unknown subsytem:" << name);
147 // is it safe to always call these? let's assume so!
148 instance->shutdown();
151 // unplug from the manager
152 globals->get_subsystem_mgr()->remove(name.c_str());
154 // and finally kill off the instance.
161 * Built-in command: reinitialize one or more subsystems.
163 * subsystem[*]: the name(s) of the subsystem(s) to reinitialize; if
164 * none is specified, reinitialize all of them.
167 do_reinit (const SGPropertyNode * arg)
171 vector<SGPropertyNode_ptr> subsystems = arg->getChildren("subsystem");
172 if (subsystems.size() == 0) {
173 globals->get_subsystem_mgr()->reinit();
175 for ( unsigned int i = 0; i < subsystems.size(); i++ ) {
176 const char * name = subsystems[i]->getStringValue();
177 SGSubsystem * subsystem = globals->get_subsystem(name);
178 if (subsystem == 0) {
180 SG_LOG( SG_GENERAL, SG_ALERT,
181 "Subsystem " << name << " not found" );
188 globals->get_event_mgr()->reinit();
194 * Built-in command: suspend one or more subsystems.
196 * subsystem[*] - the name(s) of the subsystem(s) to suspend.
199 do_suspend (const SGPropertyNode * arg)
203 vector<SGPropertyNode_ptr> subsystems = arg->getChildren("subsystem");
204 for ( unsigned int i = 0; i < subsystems.size(); i++ ) {
205 const char * name = subsystems[i]->getStringValue();
206 SGSubsystem * subsystem = globals->get_subsystem(name);
207 if (subsystem == 0) {
209 SG_LOG(SG_GENERAL, SG_ALERT, "Subsystem " << name << " not found");
211 subsystem->suspend();
218 * Built-in command: suspend one or more subsystems.
220 * subsystem[*] - the name(s) of the subsystem(s) to suspend.
223 do_resume (const SGPropertyNode * arg)
227 vector<SGPropertyNode_ptr> subsystems = arg->getChildren("subsystem");
228 for ( unsigned int i = 0; i < subsystems.size(); i++ ) {
229 const char * name = subsystems[i]->getStringValue();
230 SGSubsystem * subsystem = globals->get_subsystem(name);
231 if (subsystem == 0) {
233 SG_LOG(SG_GENERAL, SG_ALERT, "Subsystem " << name << " not found");
243 SGCommandMgr::command_t command;
245 { "add-subsystem", do_add_subsystem },
246 { "remove-subsystem", do_remove_subsystem },
247 { "reinit", do_reinit },
248 { "suspend", do_suspend },
249 { "resume", do_resume },
250 { 0, 0 } // zero-terminated
253 void registerSubsystemCommands(SGCommandMgr* cmdMgr)
255 for (int i = 0; built_ins[i].name != 0; i++) {
256 cmdMgr->addCommand(built_ins[i].name, built_ins[i].command);
260 } // of namepace flightgear