From 2b861fc1cda2eea3bd0bf5b1de641d0b69fb0708 Mon Sep 17 00:00:00 2001 From: James Turner Date: Fri, 17 Jun 2016 17:53:35 +0100 Subject: [PATCH] Aircraft-states feature. --- src/Aircraft/CMakeLists.txt | 2 + src/Aircraft/initialstate.cxx | 100 ++++++++++++++++++++++++++++++++++ src/Aircraft/initialstate.hxx | 41 ++++++++++++++ src/Main/fg_init.cxx | 11 +++- src/Main/options.cxx | 8 +++ 5 files changed, 160 insertions(+), 2 deletions(-) create mode 100644 src/Aircraft/initialstate.cxx create mode 100644 src/Aircraft/initialstate.hxx diff --git a/src/Aircraft/CMakeLists.txt b/src/Aircraft/CMakeLists.txt index 5c379f014..419923663 100644 --- a/src/Aircraft/CMakeLists.txt +++ b/src/Aircraft/CMakeLists.txt @@ -5,6 +5,7 @@ set(SOURCES replay.cxx flightrecorder.cxx FlightHistory.cxx + initialstate.cxx ) set(HEADERS @@ -12,6 +13,7 @@ set(HEADERS replay.hxx flightrecorder.hxx FlightHistory.hxx + initialstate.hxx ) diff --git a/src/Aircraft/initialstate.cxx b/src/Aircraft/initialstate.cxx new file mode 100644 index 000000000..240539a9d --- /dev/null +++ b/src/Aircraft/initialstate.cxx @@ -0,0 +1,100 @@ +// initialstate.cxx -- setup initial state of the aircraft +// +// Written by James Turner +// +// Copyright (C) 2016 James Turner +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +// $Id$ + +#include "config.h" + +#include "initialstate.hxx" + +#include + +#include +#include + +#include
+#include + +using namespace simgear; + +namespace { + + class NodeValue + { + public: + NodeValue(const std::string& s) : v(s) {} + bool operator()(const SGPropertyNode_ptr n) const + { + return (v == n->getStringValue()); + } + private: + std::string v; + }; + + SGPropertyNode_ptr nodeForState(const std::string& nm) + { + SGPropertyNode_ptr sim = fgGetNode("/sim"); + const PropertyList& states = sim->getChildren("state"); + PropertyList::const_iterator it; + for (it = states.begin(); it != states.end(); ++it) { + const PropertyList& names = (*it)->getChildren("name"); + if (std::find_if(names.begin(), names.end(), NodeValue(nm)) != names.end()) { + return *it; + } + } + + return SGPropertyNode_ptr(); + } + +} // of anonymous namespace + +namespace flightgear +{ + +bool isInitialStateName(const std::string& name) +{ + SGPropertyNode_ptr n = nodeForState(name); + return n.valid(); +} + +void applyInitialState() +{ + std::string nm = fgGetString("/sim/aircraft-state"); + if (nm.empty()) { + return; + } + + SGPropertyNode_ptr stateNode = nodeForState(nm); + if (!stateNode) { + SG_LOG(SG_AIRCRAFT, SG_WARN, "missing state node for:" << nm); + std::string aircraft = fgGetString("/sim/aircraft"); + modalMessageBox("Unknown aircraft state", + "The selected aircraft (" + aircraft + ") does not have a stage '" + nm + "')"); + + return; + } + + SG_LOG(SG_AIRCRAFT, SG_INFO, "Applying aircraft state:" << nm); + + // copy all overlay properties to the tree + copyProperties(stateNode->getChild("overlay"), globals->get_props()); +} + +} // of namespace flightgear \ No newline at end of file diff --git a/src/Aircraft/initialstate.hxx b/src/Aircraft/initialstate.hxx new file mode 100644 index 000000000..d7371c51c --- /dev/null +++ b/src/Aircraft/initialstate.hxx @@ -0,0 +1,41 @@ +// initialstate.hxx -- setup initial state of the aircraft +// +// Written by James Turner +// +// Copyright (C) 2016 James Turner +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +// $Id$ + + +#ifndef FG_AIRCRAFT_INITIAL_STATE_HXX +#define FG_AIRCRAFT_INITIAL_STATE_HXX + +#include + +namespace flightgear +{ + +/** + * @brief is the supplied name a defined initial-state, or alias of one + */ +bool isInitialStateName(const std::string& name); + + void applyInitialState(); + +} // of namespace flightgear + +#endif // FG_AIRCRAFT_INITIAL_STATE_HXX diff --git a/src/Main/fg_init.cxx b/src/Main/fg_init.cxx index 118dd1c12..8b724d134 100644 --- a/src/Main/fg_init.cxx +++ b/src/Main/fg_init.cxx @@ -78,6 +78,8 @@ #include #include #include +#include + #include #include #include @@ -216,7 +218,8 @@ public: e.getFormattedMessage()); return false; } - + // apply state after the -set.xml, but before any options are are set + flightgear::applyInitialState(); return true; } else { SG_LOG(SG_GENERAL, SG_ALERT, "aircraft '" << _searchAircraft << @@ -265,7 +268,11 @@ public: e.getFormattedMessage()); return false; } - + + // apply state after the -set.xml, but before any options are are set + flightgear::applyInitialState(); + + return true; } diff --git a/src/Main/options.cxx b/src/Main/options.cxx index 77cba345c..659c052c1 100644 --- a/src/Main/options.cxx +++ b/src/Main/options.cxx @@ -52,6 +52,7 @@ #include #include #include +#include #include #include @@ -1601,6 +1602,7 @@ struct OptionDesc { {"fdm", true, OPTION_STRING, "/sim/flight-model", false, "", 0 }, {"aero", true, OPTION_STRING, "/sim/aero", false, "", 0 }, {"aircraft-dir", true, OPTION_IGNORE, "", false, "", 0 }, + {"state", true, OPTION_IGNORE, "", false, "", 0 }, {"model-hz", true, OPTION_INT, "/sim/model-hz", false, "", 0 }, {"max-fps", true, OPTION_DOUBLE, "/sim/frame-rate-throttle-hz", false, "", 0 }, {"speed", true, OPTION_DOUBLE, "/sim/speed-up", false, "", 0 }, @@ -2087,6 +2089,12 @@ void Options::initAircraft() // or a scenery dir). fgSetString("/sim/aircraft-dir", aircraftDirPath.realpath().c_str()); } + + if (isOptionSet("state")) { + std::string stateName = valueForOption("state"); + // can't validate this until the -set.xml is parsed + fgSetString("/sim/aircraft-state", stateName); + } } void Options::processArgResult(int result) -- 2.39.5