]> git.mxchange.org Git - flightgear.git/blob - src/Main/globals.cxx
0e5433006f6e162982be0fa24e146430dfb94c0f
[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 <Navaids/navlist.hxx>
51 #include <Navaids/fixlist.hxx>
52
53 #include "globals.hxx"
54 #include "renderer.hxx"
55 #include "viewmgr.hxx"
56
57 #include "fg_props.hxx"
58 #include "fg_io.hxx"
59
60 \f
61 ////////////////////////////////////////////////////////////////////////
62 // Implementation of FGGlobals.
63 ////////////////////////////////////////////////////////////////////////
64
65 // global global :-)
66 FGGlobals *globals;
67
68
69 // Constructor
70 FGGlobals::FGGlobals() :
71     renderer( new FGRenderer ),
72     subsystem_mgr( new SGSubsystemMgr ),
73     event_mgr( new SGEventMgr ),
74     sim_time_sec( 0.0 ),
75     fg_root( "" ),
76     warp( 0 ),
77     warp_delta( 0 ),
78     time_params( NULL ),
79     ephem( NULL ),
80     mag( NULL ),
81     matlib( NULL ),
82     route_mgr( NULL ),
83     current_panel( NULL ),
84     soundmgr( 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     tacanlist( NULL ),
106     carrierlist( NULL ),
107     channellist( NULL ),
108     airwaynet( NULL ),
109     multiplayer_mgr( NULL )
110 {
111 }
112
113
114 // Destructor
115 FGGlobals::~FGGlobals() 
116 {
117     delete renderer;
118 // The AIModels manager performs a number of actions upon
119     // Shutdown that implicitly assume that other subsystems
120     // are still operational (Due to the dynamic allocation and
121     // deallocation of AIModel objects. To ensure we can safely
122     // shut down all subsystems, make sure we take down the 
123     // AIModels system first.
124     subsystem_mgr->get_group(SGSubsystemMgr::GENERAL)->remove_subsystem("ai_model");
125     delete subsystem_mgr;
126     delete event_mgr;
127     delete time_params;
128     delete ephem;
129     delete mag;
130     delete matlib;
131     delete route_mgr;
132     delete current_panel;
133     delete soundmgr;
134
135     delete ATC_mgr;
136     delete AI_mgr;
137     delete controls;
138     delete viewmgr;
139
140 //     delete commands;
141     delete acmodel;
142     delete model_mgr;
143     delete channel_options_list;
144     delete initial_waypoints;
145     delete tile_mgr;
146     delete scenery;
147     delete io;
148     delete fontcache;
149
150     delete navlist;
151     delete loclist;
152     delete gslist;
153     delete dmelist;
154     delete tacanlist;
155     delete carrierlist;
156     delete channellist;
157     delete airwaynet;
158     delete multiplayer_mgr;
159 }
160
161
162 // set the fg_root path
163 void FGGlobals::set_fg_root (const string &root) {
164     fg_root = root;
165
166     // append /data to root if it exists
167     SGPath tmp( fg_root );
168     tmp.append( "data" );
169     tmp.append( "version" );
170     if ( ulFileExists( tmp.c_str() ) ) {
171         fgGetNode("BAD_FG_ROOT", true)->setStringValue(fg_root);
172         fg_root += "/data";
173         fgGetNode("GOOD_FG_ROOT", true)->setStringValue(fg_root);
174         SG_LOG(SG_GENERAL, SG_ALERT, "***\n***\n*** Warning: changing bad FG_ROOT/--fg-root to '"
175                 << fg_root << "'\n***\n***");
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