]> git.mxchange.org Git - flightgear.git/blob - src/Main/globals.cxx
James Turner: Improved runway management code:
[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     ATC_mgr( NULL ),
85     AI_mgr( NULL ),
86     controls( NULL ),
87     viewmgr( NULL ),
88     props( new SGPropertyNode ),
89     initial_state( NULL ),
90     locale( 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     mkrlist( NULL ),
105     tacanlist( NULL ),
106     carrierlist( NULL ),
107     channellist( NULL ),
108     fixlist( NULL ),
109     airwaynet( NULL ),
110     multiplayer_mgr( NULL )
111 {
112 }
113
114
115 // Destructor
116 FGGlobals::~FGGlobals() 
117 {
118     delete renderer;
119 // The AIModels manager performs a number of actions upon
120     // Shutdown that implicitly assume that other subsystems
121     // are still operational (Due to the dynamic allocation and
122     // deallocation of AIModel objects. To ensure we can safely
123     // shut down all subsystems, make sure we take down the 
124     // AIModels system first.
125     subsystem_mgr->get_group(SGSubsystemMgr::GENERAL)->remove_subsystem("ai_model");
126     delete subsystem_mgr;
127     delete event_mgr;
128     delete time_params;
129     delete ephem;
130     delete mag;
131     delete matlib;
132     delete route_mgr;
133     delete current_panel;
134     delete soundmgr;
135     delete airports;
136
137     delete ATC_mgr;
138     delete AI_mgr;
139     delete controls;
140     delete viewmgr;
141
142 //     delete commands;
143     delete acmodel;
144     delete model_mgr;
145     delete channel_options_list;
146     delete initial_waypoints;
147     delete tile_mgr;
148     delete scenery;
149     delete io;
150     delete fontcache;
151
152     delete navlist;
153     delete loclist;
154     delete gslist;
155     delete dmelist;
156     delete mkrlist;
157     delete tacanlist;
158     delete carrierlist;
159     delete channellist;
160     delete fixlist;
161     delete airwaynet;
162     delete multiplayer_mgr;
163 }
164
165
166 // set the fg_root path
167 void FGGlobals::set_fg_root (const string &root) {
168     fg_root = root;
169
170     // append /data to root if it exists
171     SGPath tmp( fg_root );
172     tmp.append( "data" );
173     tmp.append( "version" );
174     if ( ulFileExists( tmp.c_str() ) ) {
175         fg_root += "/data";
176     }
177
178     // remove /sim/fg-root before writing to prevent hijacking
179     SGPropertyNode *n = fgGetNode("/sim", true);
180     n->removeChild("fg-root", 0, false);
181     n = n->getChild("fg-root", 0, true);
182     n->setStringValue(fg_root.c_str());
183     n->setAttribute(SGPropertyNode::WRITE, false);
184 }
185
186 void FGGlobals::set_fg_scenery (const string &scenery) {
187     SGPath s;
188     if (scenery.empty()) {
189         s.set( fg_root );
190         s.append( "Scenery" );
191     } else
192         s.set( scenery );
193
194     string_list path_list = sgPathSplit( s.str() );
195     fg_scenery.clear();
196
197     for (unsigned i = 0; i < path_list.size(); i++) {
198
199         ulDir *d = ulOpenDir( path_list[i].c_str() );
200         if (d == NULL)
201             continue;
202         ulCloseDir( d );
203
204         SGPath pt( path_list[i] ), po( path_list[i] );
205         pt.append("Terrain");
206         po.append("Objects");
207
208         ulDir *td = ulOpenDir( pt.c_str() );
209         ulDir *od = ulOpenDir( po.c_str() );
210
211         if (td == NULL && od == NULL)
212             fg_scenery.push_back( path_list[i] );
213         else {
214             if (td != NULL) {
215                 fg_scenery.push_back( pt.str() );
216                 ulCloseDir( td );
217             }
218             if (od != NULL) {
219                 fg_scenery.push_back( po.str() );
220                 ulCloseDir( od );
221             }
222         }
223         // insert a marker for FGTileEntry::load(), so that
224         // FG_SCENERY=A:B becomes list ["A/Terrain", "A/Objects", "",
225         // "B/Terrain", "B/Objects", ""]
226         fg_scenery.push_back("");
227     }
228 }
229
230
231 FGRenderer *
232 FGGlobals::get_renderer () const
233 {
234    return renderer;
235 }
236
237 SGSubsystemMgr *
238 FGGlobals::get_subsystem_mgr () const
239 {
240     return subsystem_mgr;
241 }
242
243 SGSubsystem *
244 FGGlobals::get_subsystem (const char * name)
245 {
246     return subsystem_mgr->get_subsystem(name);
247 }
248
249 void
250 FGGlobals::add_subsystem (const char * name,
251                           SGSubsystem * subsystem,
252                           SGSubsystemMgr::GroupType type,
253                           double min_time_sec)
254 {
255     subsystem_mgr->add(name, subsystem, type, min_time_sec);
256 }
257
258
259 SGEventMgr *
260 FGGlobals::get_event_mgr () const
261 {
262     return event_mgr;
263 }
264
265
266 // Save the current state as the initial state.
267 void
268 FGGlobals::saveInitialState ()
269 {
270   initial_state = new SGPropertyNode();
271
272   if (!copyProperties(props, initial_state))
273     SG_LOG(SG_GENERAL, SG_ALERT, "Error saving initial state");
274 }
275
276
277 // Restore the saved initial state, if any
278 void
279 FGGlobals::restoreInitialState ()
280 {
281     if ( initial_state == 0 ) {
282         SG_LOG(SG_GENERAL, SG_ALERT,
283                "No initial state available to restore!!!");
284         return;
285     }
286
287     SGPropertyNode *currentPresets = new SGPropertyNode;
288     SGPropertyNode *targetNode = fgGetNode( "/sim/presets" );
289
290     // stash the /sim/presets tree
291     if ( !copyProperties(targetNode, currentPresets) ) {
292         SG_LOG( SG_GENERAL, SG_ALERT, "Failed to save /sim/presets subtree" );
293     }
294     
295     if ( copyProperties(initial_state, props) ) {
296         SG_LOG( SG_GENERAL, SG_INFO, "Initial state restored successfully" );
297     } else {
298         SG_LOG( SG_GENERAL, SG_INFO,
299                 "Some errors restoring initial state (read-only props?)" );
300     }
301
302     // recover the /sim/presets tree
303     if ( !copyProperties(currentPresets, targetNode) ) {
304         SG_LOG( SG_GENERAL, SG_ALERT,
305                 "Failed to restore /sim/presets subtree" );
306     }
307
308    delete currentPresets;
309 }
310
311 FGViewer *
312 FGGlobals::get_current_view () const
313 {
314   return viewmgr->get_current_view();
315 }
316
317 // end of globals.cxx