#include <simgear/structure/commands.hxx>
#include <simgear/misc/sg_path.hxx>
+#include <simgear/misc/sg_dir.hxx>
#include <simgear/timing/sg_time.hxx>
#include <simgear/ephemeris/ephemeris.hxx>
#include <simgear/magvar/magvar.hxx>
#include <simgear/structure/subsystem_mgr.hxx>
#include <simgear/structure/event_mgr.hxx>
#include <simgear/sound/soundmgr_openal.hxx>
+#include <simgear/misc/ResourceManager.hxx>
+#include <simgear/props/propertyObject.hxx>
#include <Aircraft/controls.hxx>
#include <Airports/runways.hxx>
-#include <ATCDCL/AIMgr.hxx>
#include <ATCDCL/ATCmgr.hxx>
#include <Autopilot/route_mgr.hxx>
#include <Cockpit/panel.hxx>
#include <Model/acmodel.hxx>
#include <Model/modelmgr.hxx>
#include <MultiPlayer/multiplaymgr.hxx>
-#include <Navaids/awynet.hxx>
#include <Scenery/scenery.hxx>
#include <Scenery/tilemgr.hxx>
#include <Navaids/navlist.hxx>
#include "fg_props.hxx"
#include "fg_io.hxx"
-\f
+class AircraftResourceProvider : public simgear::ResourceProvider
+{
+public:
+ AircraftResourceProvider() :
+ simgear::ResourceProvider(simgear::ResourceManager::PRIORITY_HIGH)
+ {
+ }
+
+ virtual SGPath resolve(const std::string& aResource, SGPath&) const
+ {
+ string_list pieces(sgPathBranchSplit(aResource));
+ if ((pieces.size() < 3) || (pieces.front() != "Aircraft")) {
+ return SGPath(); // not an Aircraft path
+ }
+
+ // test against the aircraft-dir property
+ const char* aircraftDir = fgGetString("/sim/aircraft-dir");
+ string_list aircraftDirPieces(sgPathBranchSplit(aircraftDir));
+ if (!aircraftDirPieces.empty() && (aircraftDirPieces.back() == pieces[1])) {
+ // current aircraft-dir matches resource aircraft
+ SGPath r(aircraftDir);
+ for (unsigned int i=2; i<pieces.size(); ++i) {
+ r.append(pieces[i]);
+ }
+
+ if (r.exists()) {
+ SG_LOG(SG_IO, SG_INFO, "found path:" << aResource << " via /sim/aircraft-dir: " << r.str());
+ return r;
+ }
+ }
+
+ // try each aircraft dir in turn
+ std::string res(aResource, 9); // resource path with 'Aircraft/' removed
+ const string_list& dirs(globals->get_aircraft_paths());
+ string_list::const_iterator it = dirs.begin();
+ for (; it != dirs.end(); ++it) {
+ SGPath p(*it, res);
+ if (p.exists()) {
+ SG_LOG(SG_IO, SG_INFO, "found path:" << aResource << " in aircraft dir: " << *it);
+ return p;
+ }
+ } // of aircraft path iteration
+
+ return SGPath(); // not found
+ }
+};
+
////////////////////////////////////////////////////////////////////////
// Implementation of FGGlobals.
////////////////////////////////////////////////////////////////////////
soundmgr( new SGSoundMgr ),
sim_time_sec( 0.0 ),
fg_root( "" ),
- warp( 0 ),
- warp_delta( 0 ),
time_params( NULL ),
ephem( NULL ),
mag( NULL ),
route_mgr( NULL ),
current_panel( NULL ),
ATC_mgr( NULL ),
- AI_mgr( NULL ),
controls( NULL ),
viewmgr( NULL ),
commands( SGCommandMgr::instance() ),
dmelist( NULL ),
tacanlist( NULL ),
carrierlist( NULL ),
- channellist( NULL ),
- airwaynet( NULL ),
- multiplayer_mgr( NULL )
+ channellist( NULL )
{
+ simgear::ResourceManager::instance()->addProvider(new AircraftResourceProvider());
+ simgear::PropertyObjectBase::setDefaultRoot(props);
}
FGGlobals::~FGGlobals()
{
delete renderer;
+ renderer = NULL;
+
// The AIModels manager performs a number of actions upon
// Shutdown that implicitly assume that other subsystems
// are still operational (Due to the dynamic allocation and
// deallocation of AIModel objects. To ensure we can safely
// shut down all subsystems, make sure we take down the
// AIModels system first.
- subsystem_mgr->get_group(SGSubsystemMgr::GENERAL)->remove_subsystem("ai_model");
- // FGInput (FGInputEvent) and FGDialog calls get_subsystem() in their destructors,
- // which is not safe since some subsystem are already deleted but can be referred.
- // So these subsystems must be deleted prior to deleting subsystem_mgr unless
- // ~SGSubsystemGroup and SGSubsystemMgr::get_subsystem are changed not to refer to
- // deleted subsystems.
- subsystem_mgr->get_group(SGSubsystemMgr::GENERAL)->remove_subsystem("input");
- subsystem_mgr->get_group(SGSubsystemMgr::GENERAL)->remove_subsystem("gui");
+ SGSubsystem* ai = subsystem_mgr->remove("ai_model");
+ if (ai) {
+ ai->unbind();
+ delete ai;
+ }
+
+ subsystem_mgr->shutdown();
subsystem_mgr->unbind();
delete subsystem_mgr;
- delete event_mgr;
+
delete time_params;
- delete ephem;
delete mag;
delete matlib;
delete route_mgr;
delete current_panel;
delete ATC_mgr;
- delete AI_mgr;
delete controls;
- delete viewmgr;
-// delete commands;
- delete acmodel;
- delete model_mgr;
delete channel_options_list;
delete initial_waypoints;
- delete tile_mgr;
delete scenery;
delete fontcache;
delete tacanlist;
delete carrierlist;
delete channellist;
- delete airwaynet;
- delete multiplayer_mgr;
soundmgr->unbind();
delete soundmgr;
n = n->getChild("fg-root", 0, true);
n->setStringValue(fg_root.c_str());
n->setAttribute(SGPropertyNode::WRITE, false);
+
+ simgear::ResourceManager::instance()->addBasePath(fg_root,
+ simgear::ResourceManager::PRIORITY_DEFAULT);
}
-void FGGlobals::set_fg_scenery (const string &scenery) {
+void FGGlobals::set_fg_scenery (const string &scenery)
+{
SGPath s;
if (scenery.empty()) {
s.set( fg_root );
fg_scenery.clear();
for (unsigned i = 0; i < path_list.size(); i++) {
-
- ulDir *d = ulOpenDir( path_list[i].c_str() );
- if (d == NULL)
- continue;
- ulCloseDir( d );
-
- SGPath pt( path_list[i] ), po( path_list[i] );
- pt.append("Terrain");
- po.append("Objects");
-
- ulDir *td = ulOpenDir( pt.c_str() );
- ulDir *od = ulOpenDir( po.c_str() );
-
- // "Terrain" and "Airports" directory don't exist. add directory as is
- // otherwise, automatically append either Terrain, Objects, or both
- //if (td == NULL && od == NULL)
- fg_scenery.push_back( path_list[i] );
- //else {
- if (td != NULL) {
- fg_scenery.push_back( pt.str() );
- ulCloseDir( td );
- }
- if (od != NULL) {
- fg_scenery.push_back( po.str() );
- ulCloseDir( od );
- }
- //}
+ SGPath path(path_list[i]);
+ if (!path.exists()) {
+ SG_LOG(SG_GENERAL, SG_WARN, "scenery path not found:" << path.str());
+ continue;
+ }
+
+ simgear::Dir dir(path);
+ SGPath terrainDir(dir.file("Terrain"));
+ SGPath objectsDir(dir.file("Objects"));
+
+ // this code used to add *either* the base dir, OR add the
+ // Terrain and Objects subdirs, but the conditional logic was commented
+ // out, such that all three dirs are added. Unfortunately there's
+ // no information as to why the change was made.
+ fg_scenery.push_back(path.str());
+
+ if (terrainDir.exists()) {
+ fg_scenery.push_back(terrainDir.str());
+ }
+
+ if (objectsDir.exists()) {
+ fg_scenery.push_back(objectsDir.str());
+ }
+
// insert a marker for FGTileEntry::load(), so that
// FG_SCENERY=A:B becomes list ["A/Terrain", "A/Objects", "",
// "B/Terrain", "B/Objects", ""]
fg_scenery.push_back("");
- }
+ } // of path list iteration
+}
+
+void FGGlobals::append_aircraft_path(const std::string& path)
+{
+ SGPath dirPath(path);
+ if (!dirPath.exists()) {
+ SG_LOG(SG_GENERAL, SG_WARN, "aircraft path not found:" << path);
+ return;
+ }
+
+ unsigned int index = fg_aircraft_dirs.size();
+ fg_aircraft_dirs.push_back(path);
+
+// make aircraft dirs available to Nasal
+ SGPropertyNode* sim = fgGetNode("/sim", true);
+ sim->removeChild("fg-aircraft", index, false);
+ SGPropertyNode* n = sim->getChild("fg-aircraft", index, true);
+ n->setStringValue(path);
+ n->setAttribute(SGPropertyNode::WRITE, false);
}
+void FGGlobals::append_aircraft_paths(const std::string& path)
+{
+ string_list paths = sgPathSplit(path);
+ for (unsigned int p = 0; p<paths.size(); ++p) {
+ append_aircraft_path(paths[p]);
+ }
+}
+
+SGPath FGGlobals::resolve_aircraft_path(const std::string& branch) const
+{
+ return simgear::ResourceManager::instance()->findPath(branch);
+}
+
+SGPath FGGlobals::resolve_maybe_aircraft_path(const std::string& branch) const
+{
+ return simgear::ResourceManager::instance()->findPath(branch);
+}
FGRenderer *
FGGlobals::get_renderer () const
if (!copyProperties(props, initial_state))
SG_LOG(SG_GENERAL, SG_ALERT, "Error saving initial state");
+
+ // delete various properties from the initial state, since we want to
+ // preserve their values even if doing a restore
+
+ SGPropertyNode* sim = initial_state->getChild("sim");
+ sim->removeChild("presets");
+ SGPropertyNode* simStartup = sim->getChild("startup");
+ simStartup->removeChild("xsize");
+ simStartup->removeChild("ysize");
+
+ SGPropertyNode* cameraGroupNode = sim->getNode("rendering/camera-group");
+ if (cameraGroupNode) {
+ cameraGroupNode->removeChild("camera");
+ cameraGroupNode->removeChild("gui");
+ }
}
return;
}
- SGPropertyNode *currentPresets = new SGPropertyNode;
- SGPropertyNode *targetNode = fgGetNode( "/sim/presets" );
-
- // stash the /sim/presets tree
- if ( !copyProperties(targetNode, currentPresets) ) {
- SG_LOG( SG_GENERAL, SG_ALERT, "Failed to save /sim/presets subtree" );
- }
-
if ( copyProperties(initial_state, props) ) {
SG_LOG( SG_GENERAL, SG_INFO, "Initial state restored successfully" );
} else {
"Some errors restoring initial state (read-only props?)" );
}
- // recover the /sim/presets tree
- if ( !copyProperties(currentPresets, targetNode) ) {
- SG_LOG( SG_GENERAL, SG_ALERT,
- "Failed to restore /sim/presets subtree" );
- }
-
- delete currentPresets;
}
FGViewer *
return viewmgr->get_current_view();
}
+long int FGGlobals::get_warp() const
+{
+ return fgGetInt("/sim/time/warp");
+}
+
+void FGGlobals::set_warp( long int w )
+{
+ fgSetInt("/sim/time/warp", w);
+}
+
+long int FGGlobals::get_warp_delta() const
+{
+ return fgGetInt("/sim/time/warp-delta");
+}
+
+void FGGlobals::set_warp_delta( long int d )
+{
+ fgSetInt("/sim/time/warp-delta", d);
+}
+
// end of globals.cxx