]> git.mxchange.org Git - flightgear.git/blob - src/Main/globals.cxx
Merge branch 'maint' (early part) into next
[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         fg_root += "/data";
172         SG_LOG(SG_GENERAL, SG_WARN, "Warning: changing bad FG_ROOT/--fg-root to '"
173                 << fg_root << '\'');
174     }
175
176     // remove /sim/fg-root before writing to prevent hijacking
177     SGPropertyNode *n = fgGetNode("/sim", true);
178     n->removeChild("fg-root", 0, false);
179     n = n->getChild("fg-root", 0, true);
180     n->setStringValue(fg_root.c_str());
181     n->setAttribute(SGPropertyNode::WRITE, false);
182 }
183
184 void FGGlobals::set_fg_scenery (const string &scenery) {
185     SGPath s;
186     if (scenery.empty()) {
187         s.set( fg_root );
188         s.append( "Scenery" );
189     } else
190         s.set( scenery );
191
192     string_list path_list = sgPathSplit( s.str() );
193     fg_scenery.clear();
194
195     for (unsigned i = 0; i < path_list.size(); i++) {
196
197         ulDir *d = ulOpenDir( path_list[i].c_str() );
198         if (d == NULL)
199             continue;
200         ulCloseDir( d );
201
202         SGPath pt( path_list[i] ), po( path_list[i] );
203         pt.append("Terrain");
204         po.append("Objects");
205
206         ulDir *td = ulOpenDir( pt.c_str() );
207         ulDir *od = ulOpenDir( po.c_str() );
208
209         if (td == NULL && od == NULL)
210             fg_scenery.push_back( path_list[i] );
211         else {
212             if (td != NULL) {
213                 fg_scenery.push_back( pt.str() );
214                 ulCloseDir( td );
215             }
216             if (od != NULL) {
217                 fg_scenery.push_back( po.str() );
218                 ulCloseDir( od );
219             }
220         }
221         // insert a marker for FGTileEntry::load(), so that
222         // FG_SCENERY=A:B becomes list ["A/Terrain", "A/Objects", "",
223         // "B/Terrain", "B/Objects", ""]
224         fg_scenery.push_back("");
225     }
226 }
227
228
229 FGRenderer *
230 FGGlobals::get_renderer () const
231 {
232    return renderer;
233 }
234
235 SGSubsystemMgr *
236 FGGlobals::get_subsystem_mgr () const
237 {
238     return subsystem_mgr;
239 }
240
241 SGSubsystem *
242 FGGlobals::get_subsystem (const char * name)
243 {
244     return subsystem_mgr->get_subsystem(name);
245 }
246
247 void
248 FGGlobals::add_subsystem (const char * name,
249                           SGSubsystem * subsystem,
250                           SGSubsystemMgr::GroupType type,
251                           double min_time_sec)
252 {
253     subsystem_mgr->add(name, subsystem, type, min_time_sec);
254 }
255
256
257 SGEventMgr *
258 FGGlobals::get_event_mgr () const
259 {
260     return event_mgr;
261 }
262
263
264 // Save the current state as the initial state.
265 void
266 FGGlobals::saveInitialState ()
267 {
268   initial_state = new SGPropertyNode();
269
270   if (!copyProperties(props, initial_state))
271     SG_LOG(SG_GENERAL, SG_ALERT, "Error saving initial state");
272 }
273
274
275 // Restore the saved initial state, if any
276 void
277 FGGlobals::restoreInitialState ()
278 {
279     if ( initial_state == 0 ) {
280         SG_LOG(SG_GENERAL, SG_ALERT,
281                "No initial state available to restore!!!");
282         return;
283     }
284
285     SGPropertyNode *currentPresets = new SGPropertyNode;
286     SGPropertyNode *targetNode = fgGetNode( "/sim/presets" );
287
288     // stash the /sim/presets tree
289     if ( !copyProperties(targetNode, currentPresets) ) {
290         SG_LOG( SG_GENERAL, SG_ALERT, "Failed to save /sim/presets subtree" );
291     }
292     
293     if ( copyProperties(initial_state, props) ) {
294         SG_LOG( SG_GENERAL, SG_INFO, "Initial state restored successfully" );
295     } else {
296         SG_LOG( SG_GENERAL, SG_INFO,
297                 "Some errors restoring initial state (read-only props?)" );
298     }
299
300     // recover the /sim/presets tree
301     if ( !copyProperties(currentPresets, targetNode) ) {
302         SG_LOG( SG_GENERAL, SG_ALERT,
303                 "Failed to restore /sim/presets subtree" );
304     }
305
306    delete currentPresets;
307 }
308
309 FGViewer *
310 FGGlobals::get_current_view () const
311 {
312   return viewmgr->get_current_view();
313 }
314
315 // end of globals.cxx