]> git.mxchange.org Git - flightgear.git/blob - src/Main/globals.cxx
Development for two new features:
[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         // "Terrain" and "Airports" directory don't exist. add directory as is
212         // otherwise, automatically append either Terrain, Objects, or both
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