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