]> git.mxchange.org Git - flightgear.git/blob - src/Main/globals.cxx
7ab82e16e1b287697fdcfc82cb243fdac2ab5598
[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         SG_LOG(SG_GENERAL, SG_WARN, "Warning: changing bad FG_ROOT/--fg-root to '"
177                 << fg_root << '\'');
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