]> git.mxchange.org Git - flightgear.git/blob - src/Main/globals.cxx
Remove obsolete version test.
[flightgear.git] / src / Main / globals.cxx
1 // globals.cxx -- Global state that needs to be shared among the sim modules
2 //
3 // Written by Curtis Olson, started July 2000.
4 //
5 // Copyright (C) 2000  Curtis L. Olson - http://www.flightgear.org/~curt
6 //
7 // This program is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public License as
9 // published by the Free Software Foundation; either version 2 of the
10 // License, or (at your option) any later version.
11 //
12 // This program is distributed in the hope that it will be useful, but
13 // WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 // General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software
19 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20 //
21 // $Id$
22
23 #ifdef HAVE_CONFIG_H
24 #  include <config.h>
25 #endif
26
27 #include <simgear/sound/soundmgr_openal.hxx>
28 #include <simgear/structure/commands.hxx>
29 #include <simgear/misc/sg_path.hxx>
30 #include <simgear/timing/sg_time.hxx>
31 #include <simgear/ephemeris/ephemeris.hxx>
32 #include <simgear/magvar/magvar.hxx>
33 #include <simgear/scene/material/matlib.hxx>
34 #include <simgear/structure/subsystem_mgr.hxx>
35 #include <simgear/structure/event_mgr.hxx>
36
37 #include <Aircraft/controls.hxx>
38 #include <Airports/runways.hxx>
39 #include <ATCDCL/AIMgr.hxx>
40 #include <ATCDCL/ATCmgr.hxx>
41 #include <Autopilot/route_mgr.hxx>
42 #include <Cockpit/panel.hxx>
43 #include <GUI/new_gui.hxx>
44 #include <Model/acmodel.hxx>
45 #include <Model/modelmgr.hxx>
46 #include <MultiPlayer/multiplaymgr.hxx>
47 #include <Navaids/awynet.hxx>
48 #include <Scenery/scenery.hxx>
49 #include <Scenery/tilemgr.hxx>
50 #include <Navaids/navlist.hxx>
51
52 #include "globals.hxx"
53 #include "renderer.hxx"
54 #include "viewmgr.hxx"
55
56 #include "fg_props.hxx"
57 #include "fg_io.hxx"
58
59 \f
60 ////////////////////////////////////////////////////////////////////////
61 // Implementation of FGGlobals.
62 ////////////////////////////////////////////////////////////////////////
63
64 // global global :-)
65 FGGlobals *globals;
66
67
68 // Constructor
69 FGGlobals::FGGlobals() :
70     props( new SGPropertyNode ),
71     initial_state( NULL ),
72     locale( NULL ),
73     renderer( new FGRenderer ),
74     subsystem_mgr( new SGSubsystemMgr ),
75     event_mgr( new SGEventMgr ),
76     sim_time_sec( 0.0 ),
77     fg_root( "" ),
78     warp( 0 ),
79     warp_delta( 0 ),
80     time_params( NULL ),
81     ephem( NULL ),
82     mag( NULL ),
83     matlib( NULL ),
84     route_mgr( NULL ),
85     current_panel( NULL ),
86     soundmgr( NULL ),
87     ATC_mgr( NULL ),
88     AI_mgr( NULL ),
89     controls( NULL ),
90     viewmgr( NULL ),
91     commands( SGCommandMgr::instance() ),
92     acmodel( NULL ),
93     model_mgr( NULL ),
94     channel_options_list( NULL ),
95     initial_waypoints( NULL ),
96     scenery( NULL ),
97     tile_mgr( NULL ),
98     io( new FGIO ),
99     fontcache ( new FGFontCache ),
100     navlist( NULL ),
101     loclist( NULL ),
102     gslist( NULL ),
103     dmelist( NULL ),
104     tacanlist( NULL ),
105     carrierlist( NULL ),
106     channellist( NULL ),
107     airwaynet( NULL ),
108     multiplayer_mgr( NULL )
109 {
110 }
111
112
113 // Destructor
114 FGGlobals::~FGGlobals() 
115 {
116     delete renderer;
117 // The AIModels manager performs a number of actions upon
118     // Shutdown that implicitly assume that other subsystems
119     // are still operational (Due to the dynamic allocation and
120     // deallocation of AIModel objects. To ensure we can safely
121     // shut down all subsystems, make sure we take down the 
122     // AIModels system first.
123     subsystem_mgr->get_group(SGSubsystemMgr::GENERAL)->remove_subsystem("ai_model");
124     // FGInput (FGInputEvent) and FGDialog calls get_subsystem() in their destructors, 
125     // which is not safe since some subsystem are already deleted but can be referred.
126     // So these subsystems must be deleted prior to deleting subsystem_mgr unless
127     // ~SGSubsystemGroup and SGSubsystemMgr::get_subsystem are changed not to refer to
128     // deleted subsystems.
129     subsystem_mgr->get_group(SGSubsystemMgr::GENERAL)->remove_subsystem("input");
130     subsystem_mgr->get_group(SGSubsystemMgr::GENERAL)->remove_subsystem("gui");
131     delete subsystem_mgr;
132     delete event_mgr;
133     delete time_params;
134     delete ephem;
135     delete mag;
136     delete matlib;
137     delete route_mgr;
138     delete current_panel;
139     delete soundmgr;
140
141     delete ATC_mgr;
142     delete AI_mgr;
143     delete controls;
144     delete viewmgr;
145
146 //     delete commands;
147     delete acmodel;
148     delete model_mgr;
149     delete channel_options_list;
150     delete initial_waypoints;
151     delete tile_mgr;
152     delete scenery;
153     delete io;
154     delete fontcache;
155
156     delete navlist;
157     delete loclist;
158     delete gslist;
159     delete dmelist;
160     delete tacanlist;
161     delete carrierlist;
162     delete channellist;
163     delete airwaynet;
164     delete multiplayer_mgr;
165 }
166
167
168 // set the fg_root path
169 void FGGlobals::set_fg_root (const string &root) {
170     fg_root = root;
171
172     // append /data to root if it exists
173     SGPath tmp( fg_root );
174     tmp.append( "data" );
175     tmp.append( "version" );
176     if ( ulFileExists( tmp.c_str() ) ) {
177         fgGetNode("BAD_FG_ROOT", true)->setStringValue(fg_root);
178         fg_root += "/data";
179         fgGetNode("GOOD_FG_ROOT", true)->setStringValue(fg_root);
180         SG_LOG(SG_GENERAL, SG_ALERT, "***\n***\n*** Warning: changing bad FG_ROOT/--fg-root to '"
181                 << fg_root << "'\n***\n***");
182     }
183
184     // remove /sim/fg-root before writing to prevent hijacking
185     SGPropertyNode *n = fgGetNode("/sim", true);
186     n->removeChild("fg-root", 0, false);
187     n = n->getChild("fg-root", 0, true);
188     n->setStringValue(fg_root.c_str());
189     n->setAttribute(SGPropertyNode::WRITE, false);
190 }
191
192 void FGGlobals::set_fg_scenery (const string &scenery) {
193     SGPath s;
194     if (scenery.empty()) {
195         s.set( fg_root );
196         s.append( "Scenery" );
197     } else
198         s.set( scenery );
199
200     string_list path_list = sgPathSplit( s.str() );
201     fg_scenery.clear();
202
203     for (unsigned i = 0; i < path_list.size(); i++) {
204
205         ulDir *d = ulOpenDir( path_list[i].c_str() );
206         if (d == NULL)
207             continue;
208         ulCloseDir( d );
209
210         SGPath pt( path_list[i] ), po( path_list[i] );
211         pt.append("Terrain");
212         po.append("Objects");
213
214         ulDir *td = ulOpenDir( pt.c_str() );
215         ulDir *od = ulOpenDir( po.c_str() );
216
217         // "Terrain" and "Airports" directory don't exist. add directory as is
218         // otherwise, automatically append either Terrain, Objects, or both
219         //if (td == NULL && od == NULL)
220             fg_scenery.push_back( path_list[i] );
221         //else {
222             if (td != NULL) {
223                 fg_scenery.push_back( pt.str() );
224                 ulCloseDir( td );
225             }
226             if (od != NULL) {
227                 fg_scenery.push_back( po.str() );
228                 ulCloseDir( od );
229             }
230         //}
231         // insert a marker for FGTileEntry::load(), so that
232         // FG_SCENERY=A:B becomes list ["A/Terrain", "A/Objects", "",
233         // "B/Terrain", "B/Objects", ""]
234         fg_scenery.push_back("");
235     }
236 }
237
238
239 FGRenderer *
240 FGGlobals::get_renderer () const
241 {
242    return renderer;
243 }
244
245 SGSubsystemMgr *
246 FGGlobals::get_subsystem_mgr () const
247 {
248     return subsystem_mgr;
249 }
250
251 SGSubsystem *
252 FGGlobals::get_subsystem (const char * name)
253 {
254     return subsystem_mgr->get_subsystem(name);
255 }
256
257 void
258 FGGlobals::add_subsystem (const char * name,
259                           SGSubsystem * subsystem,
260                           SGSubsystemMgr::GroupType type,
261                           double min_time_sec)
262 {
263     subsystem_mgr->add(name, subsystem, type, min_time_sec);
264 }
265
266
267 SGEventMgr *
268 FGGlobals::get_event_mgr () const
269 {
270     return event_mgr;
271 }
272
273
274 // Save the current state as the initial state.
275 void
276 FGGlobals::saveInitialState ()
277 {
278   initial_state = new SGPropertyNode();
279
280   if (!copyProperties(props, initial_state))
281     SG_LOG(SG_GENERAL, SG_ALERT, "Error saving initial state");
282 }
283
284
285 // Restore the saved initial state, if any
286 void
287 FGGlobals::restoreInitialState ()
288 {
289     if ( initial_state == 0 ) {
290         SG_LOG(SG_GENERAL, SG_ALERT,
291                "No initial state available to restore!!!");
292         return;
293     }
294
295     SGPropertyNode *currentPresets = new SGPropertyNode;
296     SGPropertyNode *targetNode = fgGetNode( "/sim/presets" );
297
298     // stash the /sim/presets tree
299     if ( !copyProperties(targetNode, currentPresets) ) {
300         SG_LOG( SG_GENERAL, SG_ALERT, "Failed to save /sim/presets subtree" );
301     }
302     
303     if ( copyProperties(initial_state, props) ) {
304         SG_LOG( SG_GENERAL, SG_INFO, "Initial state restored successfully" );
305     } else {
306         SG_LOG( SG_GENERAL, SG_INFO,
307                 "Some errors restoring initial state (read-only props?)" );
308     }
309
310     // recover the /sim/presets tree
311     if ( !copyProperties(currentPresets, targetNode) ) {
312         SG_LOG( SG_GENERAL, SG_ALERT,
313                 "Failed to restore /sim/presets subtree" );
314     }
315
316    delete currentPresets;
317 }
318
319 FGViewer *
320 FGGlobals::get_current_view () const
321 {
322   return viewmgr->get_current_view();
323 }
324
325 // end of globals.cxx