]> git.mxchange.org Git - flightgear.git/blob - src/Main/globals.cxx
8cf9d171d0741c3cdec7f8cbe86ed69104c86e9e
[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 <Airports/simple.hxx>
51 #include <Navaids/navlist.hxx>
52 #include <Navaids/fixlist.hxx>
53
54 #include "globals.hxx"
55 #include "renderer.hxx"
56 #include "viewmgr.hxx"
57
58 #include "fg_props.hxx"
59 #include "fg_io.hxx"
60
61 \f
62 ////////////////////////////////////////////////////////////////////////
63 // Implementation of FGGlobals.
64 ////////////////////////////////////////////////////////////////////////
65
66 // global global :-)
67 FGGlobals *globals;
68
69
70 // Constructor
71 FGGlobals::FGGlobals() :
72     renderer( new FGRenderer ),
73     subsystem_mgr( new SGSubsystemMgr ),
74     event_mgr( new SGEventMgr ),
75     sim_time_sec( 0.0 ),
76     fg_root( "" ),
77     warp( 0 ),
78     warp_delta( 0 ),
79     time_params( NULL ),
80     ephem( NULL ),
81     mag( NULL ),
82     matlib( NULL ),
83     route_mgr( NULL ),
84     current_panel( NULL ),
85     soundmgr( NULL ),
86     airports( NULL ),
87     ATC_mgr( NULL ),
88     AI_mgr( NULL ),
89     controls( NULL ),
90     viewmgr( NULL ),
91     props( new SGPropertyNode ),
92     initial_state( NULL ),
93     locale( NULL ),
94     commands( SGCommandMgr::instance() ),
95     acmodel( NULL ),
96     model_mgr( NULL ),
97     channel_options_list( NULL ),
98     initial_waypoints( NULL ),
99     scenery( NULL ),
100     tile_mgr( NULL ),
101     io( new FGIO ),
102     fontcache ( new FGFontCache ),
103     navlist( NULL ),
104     loclist( NULL ),
105     gslist( NULL ),
106     dmelist( NULL ),
107     mkrlist( NULL ),
108     tacanlist( NULL ),
109     carrierlist( NULL ),
110     channellist( 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 ATC_mgr;
140     delete AI_mgr;
141     delete controls;
142     delete viewmgr;
143
144 //     delete commands;
145     delete acmodel;
146     delete model_mgr;
147     delete channel_options_list;
148     delete initial_waypoints;
149     delete tile_mgr;
150     delete scenery;
151     delete io;
152     delete fontcache;
153
154     delete navlist;
155     delete loclist;
156     delete gslist;
157     delete dmelist;
158     delete mkrlist;
159     delete tacanlist;
160     delete carrierlist;
161     delete channellist;
162     delete airwaynet;
163     delete multiplayer_mgr;
164 }
165
166
167 // set the fg_root path
168 void FGGlobals::set_fg_root (const string &root) {
169     fg_root = root;
170
171     // append /data to root if it exists
172     SGPath tmp( fg_root );
173     tmp.append( "data" );
174     tmp.append( "version" );
175     if ( ulFileExists( tmp.c_str() ) ) {
176         fg_root += "/data";
177         SG_LOG(SG_GENERAL, SG_WARN, "Warning: changing bad FG_ROOT/--fg-root to '"
178                 << fg_root << '\'');
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