]> git.mxchange.org Git - flightgear.git/blob - src/Main/globals.cxx
Tatsuhiro NISHIOKA: initialize classes (fixes segfault on exit on MacOS)
[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/scene/model/modellib.hxx>
28 #include <simgear/sound/soundmgr_openal.hxx>
29 #include <simgear/structure/commands.hxx>
30 #include <simgear/misc/sg_path.hxx>
31 #include <simgear/timing/sg_time.hxx>
32 #include <simgear/ephemeris/ephemeris.hxx>
33 #include <simgear/magvar/magvar.hxx>
34 #include <simgear/scene/material/matlib.hxx>
35
36 #include <Aircraft/controls.hxx>
37 #include <Airports/runways.hxx>
38 #include <ATC/AIMgr.hxx>
39 #include <ATC/ATCmgr.hxx>
40 #include <Autopilot/route_mgr.hxx>
41 #include <Cockpit/panel.hxx>
42 #include <GUI/new_gui.hxx>
43 #include <Model/acmodel.hxx>
44 #include <Model/modelmgr.hxx>
45 #include <MultiPlayer/multiplaymgr.hxx>
46 #include <Navaids/awynet.hxx>
47 #include <Scenery/scenery.hxx>
48 #include <Scenery/tilemgr.hxx>
49
50 #include "globals.hxx"
51 #include "renderer.hxx"
52 #include "viewmgr.hxx"
53
54 #include "fg_props.hxx"
55 #include "fg_io.hxx"
56
57 \f
58 ////////////////////////////////////////////////////////////////////////
59 // Implementation of FGGlobals.
60 ////////////////////////////////////////////////////////////////////////
61
62 // global global :-)
63 FGGlobals *globals;
64
65
66 // Constructor
67 FGGlobals::FGGlobals() :
68     renderer( new FGRenderer ),
69     subsystem_mgr( new SGSubsystemMgr ),
70     event_mgr( new SGEventMgr ),
71     sim_time_sec( 0.0 ),
72     fg_root( "" ),
73 #if defined(FX) && defined(XMESA)
74     fullscreen( true ),
75 #endif
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     airports( NULL ),
86     runways( 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     model_lib( NULL ),
96     acmodel( NULL ),
97     model_mgr( NULL ),
98     channel_options_list( NULL ),
99     initial_waypoints( NULL ),
100     scenery( NULL ),
101     tile_mgr( NULL ),
102     io( new FGIO ),
103     fontcache ( new FGFontCache ),
104     navlist( NULL ),
105     loclist( NULL ),
106     gslist( NULL ),
107     dmelist( NULL ),
108     mkrlist( NULL ),
109     tacanlist( NULL ),
110     carrierlist( NULL ),
111     channellist( NULL ),
112     fixlist( NULL ),
113     airwaynet( NULL ),
114     multiplayer_mgr( NULL )
115 {
116 }
117
118
119 // Destructor
120 FGGlobals::~FGGlobals() 
121 {
122     delete renderer;
123 // The AIModels manager performs a number of actions upon
124     // Shutdown that implicitly assume that other subsystems
125     // are still operational (Due to the dynamic allocation and
126     // deallocation of AIModel objects. To ensure we can safely
127     // shut down all subsystems, make sure we take down the 
128     // AIModels system first.
129     subsystem_mgr->get_group(SGSubsystemMgr::GENERAL)->remove_subsystem("ai_model");
130      delete subsystem_mgr;
131      delete event_mgr;
132      delete time_params;
133      delete ephem;
134      delete mag;
135      delete matlib;
136      delete route_mgr;
137      delete current_panel;
138      delete soundmgr;
139      delete airports;
140
141      delete runways;
142      delete ATC_mgr;
143      delete AI_mgr;
144      delete controls;
145      delete viewmgr;
146
147      delete initial_state;
148 //     //delete locale; Don't delete locale
149 //     delete commands;
150      delete model_lib;
151      delete acmodel;
152      delete model_mgr;
153      delete channel_options_list;
154      delete initial_waypoints;
155      delete scenery;
156      //delete tile_mgr; // Don't delete tile manager yet, because loader thread problems
157      delete io;
158      delete fontcache;
159
160     delete navlist;
161     delete loclist;
162     delete gslist;
163     delete dmelist;
164     delete mkrlist;
165     delete tacanlist;
166     delete carrierlist;
167     delete channellist;
168     delete fixlist;
169     delete airwaynet;
170     delete multiplayer_mgr;
171  
172     delete props;
173 }
174
175
176 // set the fg_root path
177 void FGGlobals::set_fg_root (const string &root) {
178     fg_root = root;
179     
180     // append /data to root if it exists
181     SGPath tmp( fg_root );
182     tmp.append( "data" );
183     tmp.append( "version" );
184     if ( ulFileExists( tmp.c_str() ) ) {
185         fg_root += "/data";
186     }
187
188     fgSetString("/sim/fg-root", fg_root.c_str());   
189 }
190
191 void FGGlobals::set_fg_scenery (const string &scenery) {
192     SGPath s;
193     if (scenery.empty()) {
194         s.set( fg_root );
195         s.append( "Scenery" );
196     } else
197         s.set( scenery );
198
199     string_list path_list = sgPathSplit( s.str() );
200     fg_scenery.clear();
201
202     for (unsigned i = 0; i < path_list.size(); i++) {
203
204         ulDir *d = ulOpenDir( path_list[i].c_str() );
205         if (d == NULL)
206             continue;
207         ulCloseDir( d );
208
209         SGPath pt( path_list[i] ), po( path_list[i] );
210         pt.append("Terrain");
211         po.append("Objects");
212
213         ulDir *td = ulOpenDir( pt.c_str() );
214         ulDir *od = ulOpenDir( po.c_str() );
215
216         if (td == NULL && od == NULL)
217             fg_scenery.push_back( path_list[i] );
218         else {
219             if (td != NULL) {
220                 fg_scenery.push_back( pt.str() );
221                 ulCloseDir( td );
222             }
223             if (od != NULL) {
224                 fg_scenery.push_back( po.str() );
225                 ulCloseDir( od );
226             }
227         }
228         // insert a marker for FGTileEntry::load(), so that
229         // FG_SCENERY=A:B becomes list ["A/Terrain", "A/Objects", "",
230         // "B/Terrain", "B/Objects", ""]
231         fg_scenery.push_back("");
232     }
233 }
234
235
236 FGRenderer *
237 FGGlobals::get_renderer () const
238 {
239    return renderer;
240 }
241
242 SGSubsystemMgr *
243 FGGlobals::get_subsystem_mgr () const
244 {
245     return subsystem_mgr;
246 }
247
248 SGSubsystem *
249 FGGlobals::get_subsystem (const char * name)
250 {
251     return subsystem_mgr->get_subsystem(name);
252 }
253
254 void
255 FGGlobals::add_subsystem (const char * name,
256                           SGSubsystem * subsystem,
257                           SGSubsystemMgr::GroupType type,
258                           double min_time_sec)
259 {
260     subsystem_mgr->add(name, subsystem, type, min_time_sec);
261 }
262
263
264 SGEventMgr *
265 FGGlobals::get_event_mgr () const
266 {
267     return event_mgr;
268 }
269
270
271 // Save the current state as the initial state.
272 void
273 FGGlobals::saveInitialState ()
274 {
275   delete initial_state;
276   initial_state = new SGPropertyNode();
277
278   if (!copyProperties(props, initial_state))
279     SG_LOG(SG_GENERAL, SG_ALERT, "Error saving initial state");
280 }
281
282
283 // Restore the saved initial state, if any
284 void
285 FGGlobals::restoreInitialState ()
286 {
287     if ( initial_state == 0 ) {
288         SG_LOG(SG_GENERAL, SG_ALERT,
289                "No initial state available to restore!!!");
290         return;
291     }
292
293     SGPropertyNode *currentPresets = new SGPropertyNode;
294     SGPropertyNode *targetNode = fgGetNode( "/sim/presets" );
295
296     // stash the /sim/presets tree
297     if ( !copyProperties(targetNode, currentPresets) ) {
298         SG_LOG( SG_GENERAL, SG_ALERT, "Failed to save /sim/presets subtree" );
299     }
300     
301     if ( copyProperties(initial_state, props) ) {
302         SG_LOG( SG_GENERAL, SG_INFO, "Initial state restored successfully" );
303     } else {
304         SG_LOG( SG_GENERAL, SG_INFO,
305                 "Some errors restoring initial state (read-only props?)" );
306     }
307
308     // recover the /sim/presets tree
309     if ( !copyProperties(currentPresets, targetNode) ) {
310         SG_LOG( SG_GENERAL, SG_ALERT,
311                 "Failed to restore /sim/presets subtree" );
312     }
313
314    delete currentPresets;
315 }
316
317 FGViewer *
318 FGGlobals::get_current_view () const
319 {
320   return viewmgr->get_current_view();
321 }
322
323 // end of globals.cxx