]> git.mxchange.org Git - flightgear.git/blob - src/Main/globals.cxx
- make sure /sim/fg-current can't get preset and write protected, so
[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
35 #include <Aircraft/controls.hxx>
36 #include <Airports/runways.hxx>
37 #include <ATCDCL/AIMgr.hxx>
38 #include <ATCDCL/ATCmgr.hxx>
39 #include <Autopilot/route_mgr.hxx>
40 #include <Cockpit/panel.hxx>
41 #include <GUI/new_gui.hxx>
42 #include <Model/acmodel.hxx>
43 #include <Model/modelmgr.hxx>
44 #include <MultiPlayer/multiplaymgr.hxx>
45 #include <Navaids/awynet.hxx>
46 #include <Scenery/scenery.hxx>
47 #include <Scenery/tilemgr.hxx>
48
49 #include "globals.hxx"
50 #include "renderer.hxx"
51 #include "viewmgr.hxx"
52
53 #include "fg_props.hxx"
54 #include "fg_io.hxx"
55
56 \f
57 ////////////////////////////////////////////////////////////////////////
58 // Implementation of FGGlobals.
59 ////////////////////////////////////////////////////////////////////////
60
61 // global global :-)
62 FGGlobals *globals;
63
64
65 // Constructor
66 FGGlobals::FGGlobals() :
67     renderer( new FGRenderer ),
68     subsystem_mgr( new SGSubsystemMgr ),
69     event_mgr( new SGEventMgr ),
70     sim_time_sec( 0.0 ),
71     fg_root( "" ),
72 #if defined(FX) && defined(XMESA)
73     fullscreen( true ),
74 #endif
75     warp( 0 ),
76     warp_delta( 0 ),
77     time_params( NULL ),
78     ephem( NULL ),
79     mag( NULL ),
80     matlib( NULL ),
81     route_mgr( NULL ),
82     current_panel( NULL ),
83     soundmgr( NULL ),
84     airports( NULL ),
85     runways( NULL ),
86     ATC_mgr( NULL ),
87     AI_mgr( NULL ),
88     controls( NULL ),
89     viewmgr( NULL ),
90     props( new SGPropertyNode ),
91     initial_state( NULL ),
92     locale( NULL ),
93     commands( SGCommandMgr::instance() ),
94     acmodel( NULL ),
95     model_mgr( NULL ),
96     channel_options_list( NULL ),
97     initial_waypoints( NULL ),
98     scenery( NULL ),
99     tile_mgr( NULL ),
100     io( new FGIO ),
101     fontcache ( new FGFontCache ),
102     navlist( NULL ),
103     loclist( NULL ),
104     gslist( NULL ),
105     dmelist( NULL ),
106     mkrlist( NULL ),
107     tacanlist( NULL ),
108     carrierlist( NULL ),
109     channellist( NULL ),
110     fixlist( NULL ),
111     airwaynet( NULL ),
112     multiplayer_mgr( NULL )
113 {
114 }
115
116
117 // Destructor
118 FGGlobals::~FGGlobals() 
119 {
120     delete renderer;
121 // The AIModels manager performs a number of actions upon
122     // Shutdown that implicitly assume that other subsystems
123     // are still operational (Due to the dynamic allocation and
124     // deallocation of AIModel objects. To ensure we can safely
125     // shut down all subsystems, make sure we take down the 
126     // AIModels system first.
127     subsystem_mgr->get_group(SGSubsystemMgr::GENERAL)->remove_subsystem("ai_model");
128     delete subsystem_mgr;
129     delete event_mgr;
130     delete time_params;
131     delete ephem;
132     delete mag;
133     delete matlib;
134     delete route_mgr;
135     delete current_panel;
136     delete soundmgr;
137     delete airports;
138
139     delete runways;
140     delete ATC_mgr;
141     delete AI_mgr;
142     delete controls;
143     delete viewmgr;
144
145 //     delete commands;
146     delete acmodel;
147     delete model_mgr;
148     delete channel_options_list;
149     delete initial_waypoints;
150     delete tile_mgr;
151     delete scenery;
152     delete io;
153     delete fontcache;
154
155     delete navlist;
156     delete loclist;
157     delete gslist;
158     delete dmelist;
159     delete mkrlist;
160     delete tacanlist;
161     delete carrierlist;
162     delete channellist;
163     delete fixlist;
164     delete airwaynet;
165     delete multiplayer_mgr;
166 }
167
168
169 // set the fg_root path
170 void FGGlobals::set_fg_root (const string &root) {
171     fg_root = root;
172
173     // append /data to root if it exists
174     SGPath tmp( fg_root );
175     tmp.append( "data" );
176     tmp.append( "version" );
177     if ( ulFileExists( tmp.c_str() ) ) {
178         fg_root += "/data";
179     }
180
181     // remove /sim/fg-root before writing to prevent hijacking
182     SGPropertyNode *n = fgGetNode("/sim", true);
183     n->removeChild("fg-root", 0, false);
184     n = n->getChild("fg-root", 0, true);
185     n->setStringValue(fg_root.c_str());
186     n->setAttribute(SGPropertyNode::WRITE, false);
187 }
188
189 void FGGlobals::set_fg_scenery (const string &scenery) {
190     SGPath s;
191     if (scenery.empty()) {
192         s.set( fg_root );
193         s.append( "Scenery" );
194     } else
195         s.set( scenery );
196
197     string_list path_list = sgPathSplit( s.str() );
198     fg_scenery.clear();
199
200     for (unsigned i = 0; i < path_list.size(); i++) {
201
202         ulDir *d = ulOpenDir( path_list[i].c_str() );
203         if (d == NULL)
204             continue;
205         ulCloseDir( d );
206
207         SGPath pt( path_list[i] ), po( path_list[i] );
208         pt.append("Terrain");
209         po.append("Objects");
210
211         ulDir *td = ulOpenDir( pt.c_str() );
212         ulDir *od = ulOpenDir( po.c_str() );
213
214         if (td == NULL && od == NULL)
215             fg_scenery.push_back( path_list[i] );
216         else {
217             if (td != NULL) {
218                 fg_scenery.push_back( pt.str() );
219                 ulCloseDir( td );
220             }
221             if (od != NULL) {
222                 fg_scenery.push_back( po.str() );
223                 ulCloseDir( od );
224             }
225         }
226         // insert a marker for FGTileEntry::load(), so that
227         // FG_SCENERY=A:B becomes list ["A/Terrain", "A/Objects", "",
228         // "B/Terrain", "B/Objects", ""]
229         fg_scenery.push_back("");
230     }
231 }
232
233
234 FGRenderer *
235 FGGlobals::get_renderer () const
236 {
237    return renderer;
238 }
239
240 SGSubsystemMgr *
241 FGGlobals::get_subsystem_mgr () const
242 {
243     return subsystem_mgr;
244 }
245
246 SGSubsystem *
247 FGGlobals::get_subsystem (const char * name)
248 {
249     return subsystem_mgr->get_subsystem(name);
250 }
251
252 void
253 FGGlobals::add_subsystem (const char * name,
254                           SGSubsystem * subsystem,
255                           SGSubsystemMgr::GroupType type,
256                           double min_time_sec)
257 {
258     subsystem_mgr->add(name, subsystem, type, min_time_sec);
259 }
260
261
262 SGEventMgr *
263 FGGlobals::get_event_mgr () const
264 {
265     return event_mgr;
266 }
267
268
269 // Save the current state as the initial state.
270 void
271 FGGlobals::saveInitialState ()
272 {
273   initial_state = new SGPropertyNode();
274
275   if (!copyProperties(props, initial_state))
276     SG_LOG(SG_GENERAL, SG_ALERT, "Error saving initial state");
277 }
278
279
280 // Restore the saved initial state, if any
281 void
282 FGGlobals::restoreInitialState ()
283 {
284     if ( initial_state == 0 ) {
285         SG_LOG(SG_GENERAL, SG_ALERT,
286                "No initial state available to restore!!!");
287         return;
288     }
289
290     SGPropertyNode *currentPresets = new SGPropertyNode;
291     SGPropertyNode *targetNode = fgGetNode( "/sim/presets" );
292
293     // stash the /sim/presets tree
294     if ( !copyProperties(targetNode, currentPresets) ) {
295         SG_LOG( SG_GENERAL, SG_ALERT, "Failed to save /sim/presets subtree" );
296     }
297     
298     if ( copyProperties(initial_state, props) ) {
299         SG_LOG( SG_GENERAL, SG_INFO, "Initial state restored successfully" );
300     } else {
301         SG_LOG( SG_GENERAL, SG_INFO,
302                 "Some errors restoring initial state (read-only props?)" );
303     }
304
305     // recover the /sim/presets tree
306     if ( !copyProperties(currentPresets, targetNode) ) {
307         SG_LOG( SG_GENERAL, SG_ALERT,
308                 "Failed to restore /sim/presets subtree" );
309     }
310
311    delete currentPresets;
312 }
313
314 FGViewer *
315 FGGlobals::get_current_view () const
316 {
317   return viewmgr->get_current_view();
318 }
319
320 // end of globals.cxx