~ubuntu-branches/debian/sid/flightgear/sid

« back to all changes in this revision

Viewing changes to src/Main/globals.cxx

  • Committer: Package Import Robot
  • Author(s): Markus Wanner, Markus Wanner, Rebecca Palmer
  • Date: 2014-01-21 22:31:02 UTC
  • mfrom: (1.3.1) (15.1.2 experimental)
  • Revision ID: package-import@ubuntu.com-20140121223102-cjw7g9le25acd119
Tags: 3.0.0~git20140204+c99ea4-1
[ Markus Wanner ]
* Upload to unstable.
* Adjust B-D to allow building on kfreebsd-*. Closes: #724686.
* Add a lintian-overrides on autotools; we use cmake.
* Upstream corrected the fgfs manpage. Closes: #556362.
* Drop unnecessary man page for gl-info. Closes: #698308.
* Drop README.Linux: it's outdated to the point of uselessness.
  Closes: #574173.
* Add an upper limit of libsimgear-dev versions that flightgear can be
  built with. Closes: #738436.
* Drop the libsvn-dev dependency, neither flightgear nor simgear depend
  on libsvn, anymore. Closes: #682947.
* List icons in debian/install rather than copying around from rules.
* Update menu entry for flightgear, add one for fgcom; add .xpm icons.
  Closes: #713924.
* flightgear.desktop: add German translation
* Bump Standards-Version to 3.9.5; no changes needed.

[ Rebecca Palmer ]
* New upstream release.
* Install the icons (based on code by Saikrishna Arcot).  (Not a
  complete fix for LP908153 as it only sets the menu/Dash icon, not the
  running window's icon, but better than nothing).
* Disable screensaver while running. Closes: LP#793599. Add required
  libdbus-1-dev dependency.
* Remove outdated README.Debian.
* Terrasync now works after just ticking the box. Closes: #252899.
* Always set Terrasync directory.

Show diffs side-by-side

added added

removed removed

Lines of Context:
27
27
#include <boost/foreach.hpp>
28
28
#include <algorithm>
29
29
 
 
30
#include <osgViewer/Viewer>
 
31
#include <osgDB/Registry>
 
32
 
30
33
#include <simgear/structure/commands.hxx>
31
34
#include <simgear/misc/sg_path.hxx>
32
35
#include <simgear/misc/sg_dir.hxx>
39
42
#include <simgear/misc/ResourceManager.hxx>
40
43
#include <simgear/props/propertyObject.hxx>
41
44
#include <simgear/props/props_io.hxx>
 
45
#include <simgear/scene/model/modellib.hxx>
42
46
 
43
47
#include <Aircraft/controls.hxx>
44
48
#include <Airports/runways.hxx>
52
56
#include <Navaids/navlist.hxx>
53
57
#include <Viewer/renderer.hxx>
54
58
#include <Viewer/viewmgr.hxx>
 
59
#include <Sound/sample_queue.hxx>
55
60
 
56
61
#include "globals.hxx"
57
62
#include "locale.hxx"
85
90
        }
86
91
        
87
92
        if (r.exists()) {
88
 
          SG_LOG(SG_IO, SG_DEBUG, "found path:" << aResource << " via /sim/aircraft-dir: " << r.str());
89
93
          return r;
90
94
        }
91
95
    }
97
101
    for (; it != dirs.end(); ++it) {
98
102
      SGPath p(*it, res);
99
103
      if (p.exists()) {
100
 
        SG_LOG(SG_IO, SG_DEBUG, "found path:" << aResource << " in aircraft dir: " << *it);
101
104
        return p;
102
105
      }
103
106
    } // of aircraft path iteration
128
131
////////////////////////////////////////////////////////////////////////
129
132
 
130
133
// global global :-)
131
 
FGGlobals *globals;
 
134
FGGlobals *globals = NULL;
132
135
 
133
136
 
134
137
// Constructor
135
138
FGGlobals::FGGlobals() :
136
 
    props( new SGPropertyNode ),
137
139
    initial_state( NULL ),
138
 
    locale( new FGLocale(props) ),
139
140
    renderer( new FGRenderer ),
140
141
    subsystem_mgr( new SGSubsystemMgr ),
141
142
    event_mgr( new SGEventMgr ),
144
145
    fg_home( "" ),
145
146
    time_params( NULL ),
146
147
    ephem( NULL ),
147
 
    matlib( NULL ),
148
148
    route_mgr( NULL ),
149
149
    ATIS_mgr( NULL ),
150
150
    controls( NULL ),
152
152
    commands( SGCommandMgr::instance() ),
153
153
    channel_options_list( NULL ),
154
154
    initial_waypoints( NULL ),
155
 
    scenery( NULL ),
156
 
    tile_mgr( NULL ),
157
155
    fontcache ( new FGFontCache ),
158
156
    channellist( NULL ),
159
 
    haveUserSettings(false)
160
 
{
161
 
  simgear::ResourceManager::instance()->addProvider(new AircraftResourceProvider);
162
 
  simgear::ResourceManager::instance()->addProvider(new CurrentAircraftDirProvider);
163
 
  simgear::PropertyObjectBase::setDefaultRoot(props);
164
 
  
165
 
  positionLon = props->getNode("position/longitude-deg", true);
166
 
  positionLat = props->getNode("position/latitude-deg", true);
167
 
  positionAlt = props->getNode("position/altitude-ft", true);
168
 
  
169
 
  viewLon = props->getNode("sim/current-view/viewer-lon-deg", true);
170
 
  viewLat = props->getNode("sim/current-view/viewer-lat-deg", true);
171
 
  viewAlt = props->getNode("sim/current-view/viewer-elev-ft", true);
172
 
  
173
 
  orientPitch = props->getNode("orientation/pitch-deg", true);
174
 
  orientHeading = props->getNode("orientation/heading-deg", true);
175
 
  orientRoll = props->getNode("orientation/roll-deg", true);
 
157
    haveUserSettings(false),
 
158
    _chatter_queue(NULL)
 
159
{
 
160
    SGPropertyNode* root = new SGPropertyNode;
 
161
    props = SGPropertyNode_ptr(root);
 
162
    locale = new FGLocale(props);
 
163
    
 
164
    simgear::ResourceManager::instance()->addProvider(new AircraftResourceProvider);
 
165
    simgear::ResourceManager::instance()->addProvider(new CurrentAircraftDirProvider);
 
166
    initProperties();
 
167
}
 
168
 
 
169
void FGGlobals::initProperties()
 
170
{
 
171
    simgear::PropertyObjectBase::setDefaultRoot(props);
 
172
    
 
173
    positionLon = props->getNode("position/longitude-deg", true);
 
174
    positionLat = props->getNode("position/latitude-deg", true);
 
175
    positionAlt = props->getNode("position/altitude-ft", true);
 
176
    
 
177
    viewLon = props->getNode("sim/current-view/viewer-lon-deg", true);
 
178
    viewLat = props->getNode("sim/current-view/viewer-lat-deg", true);
 
179
    viewAlt = props->getNode("sim/current-view/viewer-elev-ft", true);
 
180
    
 
181
    orientPitch = props->getNode("orientation/pitch-deg", true);
 
182
    orientHeading = props->getNode("orientation/heading-deg", true);
 
183
    orientRoll = props->getNode("orientation/roll-deg", true);
 
184
 
176
185
}
177
186
 
178
187
// Destructor
187
196
    // deallocation of AIModel objects. To ensure we can safely
188
197
    // shut down all subsystems, make sure we take down the 
189
198
    // AIModels system first.
190
 
    SGSubsystem* ai = subsystem_mgr->remove("ai-model");
 
199
    SGSubsystemRef ai = subsystem_mgr->get_subsystem("ai-model");
191
200
    if (ai) {
 
201
        subsystem_mgr->remove("ai-model");
192
202
        ai->unbind();
193
 
        delete ai;
 
203
        ai.clear(); // ensure AI is deleted now, not at end of this method
194
204
    }
195
 
    SGSubsystem* sound = subsystem_mgr->remove("sound");
196
 
 
 
205
    
197
206
    subsystem_mgr->shutdown();
198
 
    subsystem_mgr->unbind();
 
207
    subsystem_mgr->unbind();    
 
208
 
 
209
    subsystem_mgr->remove("aircraft-model");
 
210
    subsystem_mgr->remove("tile-manager");
 
211
    subsystem_mgr->remove("model-manager");
 
212
    _tile_mgr.clear();
 
213
 
 
214
    osg::ref_ptr<osgViewer::Viewer> vw(renderer->getViewer());
 
215
    if (vw) {
 
216
        // https://code.google.com/p/flightgear-bugs/issues/detail?id=1291
 
217
        // explicitly stop trheading before we delete the renderer or
 
218
        // viewMgr (which ultimately holds refs to the CameraGroup, and
 
219
        // GraphicsContext)
 
220
        vw->stopThreading();
 
221
    }
 
222
    
 
223
    // don't cancel the pager until after shutdown, since AIModels (and
 
224
    // potentially others) can queue delete requests on the pager.
 
225
    if (vw && vw->getDatabasePager()) {
 
226
        vw->getDatabasePager()->cancel();
 
227
        vw->getDatabasePager()->clear();
 
228
    }
 
229
    
 
230
    osgDB::Registry::instance()->clearObjectCache();
 
231
    
 
232
    // renderer touches subsystems during its destruction
 
233
    set_renderer(NULL);
 
234
    _scenery.clear();
 
235
    _chatter_queue.clear();
 
236
    
199
237
    delete subsystem_mgr;
200
 
    
201
 
    delete renderer;
202
 
    renderer = NULL;
203
 
    
 
238
    subsystem_mgr = NULL; // important so ::get_subsystem returns NULL
 
239
    vw = 0; // don't delete the viewer until now
 
240
 
204
241
    delete time_params;
205
 
    delete matlib;
 
242
    set_matlib(NULL);
206
243
    delete route_mgr;
207
 
 
208
244
    delete ATIS_mgr;
209
 
 
210
245
    delete channel_options_list;
211
246
    delete initial_waypoints;
212
 
    delete scenery;
213
247
    delete fontcache;
214
 
 
215
248
    delete channellist;
216
 
    delete sound;
217
249
 
 
250
    simgear::PropertyObjectBase::setDefaultRoot(NULL);
 
251
    simgear::SGModelLib::resetPropertyRoot();
 
252
    
218
253
    delete locale;
219
254
    locale = NULL;
 
255
    
 
256
    cleanupListeners();
 
257
    
 
258
    props.clear();
 
259
    
 
260
    delete commands;
220
261
}
221
262
 
222
263
// set the fg_root path
223
 
void FGGlobals::set_fg_root (const string &root) {
 
264
void FGGlobals::set_fg_root (const std::string &root) {
224
265
    SGPath tmp(root);
225
266
    fg_root = tmp.realpath();
226
267
 
247
288
}
248
289
 
249
290
// set the fg_home path
250
 
void FGGlobals::set_fg_home (const string &home) {
 
291
void FGGlobals::set_fg_home (const std::string &home) {
251
292
    SGPath tmp(home);
252
293
    fg_home = tmp.realpath();
253
294
}
254
295
 
255
 
void FGGlobals::append_fg_scenery (const string &paths)
 
296
PathList FGGlobals::get_data_paths() const
 
297
{
 
298
    PathList r(additional_data_paths);
 
299
    r.push_back(SGPath(fg_root));
 
300
    return r;
 
301
}
 
302
 
 
303
PathList FGGlobals::get_data_paths(const std::string& suffix) const
 
304
{
 
305
    PathList r;
 
306
    BOOST_FOREACH(SGPath p, get_data_paths()) {
 
307
        p.append(suffix);
 
308
        if (p.exists()) {
 
309
            r.push_back(p);
 
310
        }
 
311
    }
 
312
 
 
313
    return r;
 
314
}
 
315
 
 
316
void FGGlobals::append_data_path(const SGPath& path)
 
317
{
 
318
    if (!path.exists()) {
 
319
        SG_LOG(SG_GENERAL, SG_WARN, "adding non-existant data path:" << path);
 
320
    }
 
321
    
 
322
    additional_data_paths.push_back(path);
 
323
}
 
324
 
 
325
SGPath FGGlobals::find_data_dir(const std::string& pathSuffix) const
 
326
{
 
327
    BOOST_FOREACH(SGPath p, additional_data_paths) {
 
328
        p.append(pathSuffix);
 
329
        if (p.exists()) {
 
330
            return p;
 
331
        }
 
332
    }
 
333
    
 
334
    SGPath rootPath(fg_root);
 
335
    rootPath.append(pathSuffix);
 
336
    if (rootPath.exists()) {
 
337
        return rootPath;
 
338
    }
 
339
    
 
340
    SG_LOG(SG_GENERAL, SG_WARN, "dir not found in any data path:" << pathSuffix);
 
341
    return SGPath();
 
342
}
 
343
 
 
344
void FGGlobals::append_fg_scenery (const std::string &paths)
256
345
{
257
346
//    fg_scenery.clear();
258
347
    SGPropertyNode* sim = fgGetNode("/sim", true);
311
400
{
312
401
  SGPath dirPath(path);
313
402
  if (!dirPath.exists()) {
314
 
    SG_LOG(SG_GENERAL, SG_WARN, "aircraft path not found:" << path);
 
403
    SG_LOG(SG_GENERAL, SG_ALERT, "aircraft path not found:" << path);
315
404
    return;
316
405
  }
 
406
    
 
407
  SGPath acSubdir(dirPath);
 
408
  acSubdir.append("Aircraft");
 
409
  if (acSubdir.exists()) {
 
410
      SG_LOG(SG_GENERAL, SG_WARN, "Specified an aircraft-dir with an 'Aircraft' subdirectory:" << dirPath
 
411
                 << ", will instead use child directory:" << acSubdir);
 
412
      dirPath = acSubdir;
 
413
  }
 
414
    
317
415
  std::string abspath = dirPath.realpath();
318
 
  
319
416
  unsigned int index = fg_aircraft_dirs.size();  
320
417
  fg_aircraft_dirs.push_back(abspath);
321
418
  
357
454
   return renderer;
358
455
}
359
456
 
 
457
void FGGlobals::set_renderer(FGRenderer *render)
 
458
{
 
459
    if (render == renderer) {
 
460
        return;
 
461
    }
 
462
    
 
463
    delete renderer;
 
464
    renderer = render;
 
465
}
 
466
 
360
467
SGSubsystemMgr *
361
468
FGGlobals::get_subsystem_mgr () const
362
469
{
366
473
SGSubsystem *
367
474
FGGlobals::get_subsystem (const char * name)
368
475
{
 
476
    if (!subsystem_mgr) {
 
477
        return NULL;
 
478
    }
 
479
    
369
480
    return subsystem_mgr->get_subsystem(name);
370
481
}
371
482
 
428
539
  return SGVec3d::fromGeod(get_view_position());
429
540
}
430
541
 
 
542
static void treeDumpRefCounts(int depth, SGPropertyNode* nd)
 
543
{
 
544
    for (int i=0; i<nd->nChildren(); ++i) {
 
545
        SGPropertyNode* cp = nd->getChild(i);
 
546
        if (SGReferenced::count(cp) > 1) {
 
547
            SG_LOG(SG_GENERAL, SG_INFO, "\t" << cp->getPath() << " refcount:" << SGReferenced::count(cp));
 
548
        }
 
549
        
 
550
        treeDumpRefCounts(depth + 1, cp);
 
551
    }
 
552
}
 
553
 
 
554
static void treeClearAliases(SGPropertyNode* nd)
 
555
{
 
556
    if (nd->isAlias()) {
 
557
        nd->unalias();
 
558
    }
 
559
    
 
560
    for (int i=0; i<nd->nChildren(); ++i) {
 
561
        SGPropertyNode* cp = nd->getChild(i);
 
562
        treeClearAliases(cp);
 
563
    }
 
564
}
 
565
 
 
566
void
 
567
FGGlobals::resetPropertyRoot()
 
568
{
 
569
    delete locale;
 
570
    
 
571
    cleanupListeners();
 
572
    
 
573
    // we don't strictly need to clear these (they will be reset when we
 
574
    // initProperties again), but trying to reduce false-positives when dumping
 
575
    // ref-counts.
 
576
    positionLon.clear();
 
577
    positionLat.clear();
 
578
    positionAlt.clear();
 
579
    viewLon.clear();
 
580
    viewLat.clear();
 
581
    viewAlt.clear();
 
582
    orientPitch.clear();
 
583
    orientHeading.clear();
 
584
    orientRoll.clear();
 
585
    
 
586
    // clear aliases so ref-counts are accurate when dumped
 
587
    treeClearAliases(props);
 
588
    
 
589
    SG_LOG(SG_GENERAL, SG_INFO, "root props refcount:" << props.getNumRefs());
 
590
    treeDumpRefCounts(0, props);
 
591
 
 
592
    //BaseStackSnapshot::dumpAll(std::cout);
 
593
    
 
594
    props = new SGPropertyNode;
 
595
    initProperties();
 
596
    locale = new FGLocale(props);
 
597
    
 
598
    // remove /sim/fg-root before writing to prevent hijacking
 
599
    SGPropertyNode *n = props->getNode("/sim", true);
 
600
    n->removeChild("fg-root", 0, false);
 
601
    n = n->getChild("fg-root", 0, true);
 
602
    n->setStringValue(fg_root.c_str());
 
603
    n->setAttribute(SGPropertyNode::WRITE, false);
 
604
}
 
605
 
431
606
// Save the current state as the initial state.
432
607
void
433
608
FGGlobals::saveInitialState ()
453
628
  }
454
629
}
455
630
 
 
631
static std::string autosaveName()
 
632
{
 
633
    std::ostringstream os;
 
634
    string_list versionParts = simgear::strutils::split(VERSION, ".");
 
635
    if (versionParts.size() < 2) {
 
636
        return "autosave.xml";
 
637
    }
 
638
    
 
639
    os << "autosave_" << versionParts[0] << "_" << versionParts[1] << ".xml";
 
640
    return os.str();
 
641
}
456
642
 
457
643
// Restore the saved initial state, if any
458
644
void
483
669
    // remember that we have (tried) to load any existing autsave.xml
484
670
    haveUserSettings = true;
485
671
 
486
 
    SGPath autosaveFile = simgear::Dir(dataPath).file("autosave.xml");
 
672
    SGPath autosaveFile = simgear::Dir(dataPath).file(autosaveName());
487
673
    SGPropertyNode autosave;
488
674
    if (autosaveFile.exists()) {
489
675
      SG_LOG(SG_INPUT, SG_INFO, "Reading user settings from " << autosaveFile.str());
511
697
      haveUserSettings = false;
512
698
 
513
699
      SGPath autosaveFile(globals->get_fg_home());
514
 
      autosaveFile.append( "autosave.xml" );
 
700
      autosaveFile.append(autosaveName());
515
701
      autosaveFile.create_dir( 0700 );
516
702
      SG_LOG(SG_IO, SG_INFO, "Saving user settings to " << autosaveFile.str());
517
703
      try {
518
704
        writeProperties(autosaveFile.str(), globals->get_props(), false, SGPropertyNode::USERARCHIVE);
519
705
      } catch (const sg_exception &e) {
520
 
        guiErrorMessage("Error writing autosave.xml: ", e);
 
706
        guiErrorMessage("Error writing autosave:", e);
521
707
      }
522
708
      SG_LOG(SG_INPUT, SG_DEBUG, "Finished Saving user settings");
523
709
    }
549
735
  fgSetInt("/sim/time/warp-delta", d);
550
736
}
551
737
 
 
738
FGScenery* FGGlobals::get_scenery () const
 
739
{
 
740
    return _scenery.get();
 
741
}
 
742
 
 
743
void FGGlobals::set_scenery ( FGScenery *s )
 
744
{
 
745
    _scenery = s;
 
746
}
 
747
 
 
748
FGTileMgr* FGGlobals::get_tile_mgr () const
 
749
{
 
750
    return _tile_mgr.get();
 
751
}
 
752
 
 
753
void FGGlobals::set_tile_mgr ( FGTileMgr *t )
 
754
{
 
755
    _tile_mgr = t;
 
756
}
 
757
 
 
758
void FGGlobals::set_matlib( SGMaterialLib *m )
 
759
{
 
760
    matlib = m;
 
761
}
 
762
 
 
763
FGSampleQueue* FGGlobals::get_chatter_queue() const
 
764
{
 
765
    return _chatter_queue;
 
766
}
 
767
 
 
768
void FGGlobals::set_chatter_queue(FGSampleQueue* queue)
 
769
{
 
770
    _chatter_queue = queue;
 
771
}
 
772
 
 
773
void FGGlobals::addListenerToCleanup(SGPropertyChangeListener* l)
 
774
{
 
775
    _listeners_to_cleanup.push_back(l);
 
776
}
 
777
 
 
778
void FGGlobals::cleanupListeners()
 
779
{
 
780
    SGPropertyChangeListenerVec::iterator i = _listeners_to_cleanup.begin();
 
781
    for (; i != _listeners_to_cleanup.end(); ++i) {
 
782
        delete *i;
 
783
    }
 
784
    _listeners_to_cleanup.clear();
 
785
}
 
786
 
552
787
// end of globals.cxx