From 2c8aad12ba1caf9071c2c07fc1599d1e9e9e5e04 Mon Sep 17 00:00:00 2001 From: Richard Harrison Date: Wed, 5 Jul 2017 01:23:24 +0200 Subject: [PATCH] Model relative property tree root binding. Change fgcommand to take an optional property tree root element. This fixes the animation bindings to use the defined property tree root - to support multiplayer (or other) model that can bind to the correct part of the property tree. Requires a corresponding fix in sg to allow the command methods to take an optional root parameter. What this means is that when inside someone else's multiplayer model (e.g. backseat, or co-pilot), the multipalyer (AI) model will correctly modify properties inside the correct part of the property tree inside (/ai), rather than modifying the properties inside the same part of the tree as the non-ai model. This means that a properly setup model will operate within it's own space in the property tree; and permit more generic multiplayer code to be written. This is probably responsible for some of the pollution of the root property tree with MP aircraft properties. --- src/AIModel/AIManager.cxx | 6 +- src/AIModel/AIManager.hxx | 4 +- src/ATC/atcdialog.cxx | 4 +- src/ATC/atcdialog.hxx | 2 +- src/Autopilot/digitalfilter.cxx | 53 +++++++--- src/Autopilot/inputvalue.cxx | 3 +- src/Autopilot/route_mgr.cxx | 18 ++-- src/Autopilot/route_mgr.hxx | 4 +- src/Environment/fgclouds.cxx | 6 +- src/Environment/fgclouds.hxx | 6 +- src/Environment/realwx_ctrl.cxx | 4 +- src/GUI/FGPUIMenuBar.cxx | 2 +- src/GUI/MessageBox.cxx | 2 +- src/GUI/MouseCursor.cxx | 2 +- src/GUI/MouseCursor.hxx | 2 +- src/GUI/gui.cxx | 4 +- src/Input/FGJoystickInput.cxx | 2 +- src/Input/FGKeyboardInput.cxx | 2 +- src/Input/FGMouseInput.cxx | 6 +- src/Instrumentation/KLN89/kln89.cxx | 24 ++--- src/Main/fg_commands.cxx | 102 +++++++++++-------- src/Main/fg_scene_commands.cxx | 54 +++++----- src/Main/subsystemFactory.cxx | 12 +-- src/Model/panelnode.cxx | 2 +- src/Model/panelnode.hxx | 2 +- src/MultiPlayer/multiplaymgr.cxx | 37 +++++-- src/MultiPlayer/multiplaymgr.hxx | 1 + src/Network/http/PropertyChangeWebsocket.cxx | 2 +- src/Network/http/RunUriHandler.cxx | 2 +- src/Network/props.cxx | 4 +- src/Scripting/NasalSys.cxx | 12 ++- src/Scripting/NasalSys.hxx | 5 +- src/Sound/soundmanager.cxx | 2 +- src/Sound/soundmanager.hxx | 2 +- src/Time/TimeManager.cxx | 2 +- src/Viewer/GraphicsWindowQt5.cpp | 4 +- 36 files changed, 240 insertions(+), 161 deletions(-) diff --git a/src/AIModel/AIManager.cxx b/src/AIModel/AIManager.cxx index e890983f3..7baf44f20 100644 --- a/src/AIModel/AIManager.cxx +++ b/src/AIModel/AIManager.cxx @@ -339,7 +339,7 @@ FGAIManager::processThermal( double dt, FGAIThermal* thermal ) { } -bool FGAIManager::loadScenarioCommand(const SGPropertyNode* args) +bool FGAIManager::loadScenarioCommand(const SGPropertyNode* args, SGPropertyNode *) { std::string name = args->getStringValue("name"); if (args->hasChild("load-property")) { @@ -370,9 +370,9 @@ bool FGAIManager::loadScenarioCommand(const SGPropertyNode* args) return ok; } -bool FGAIManager::unloadScenarioCommand(const SGPropertyNode* args) +bool FGAIManager::unloadScenarioCommand(const SGPropertyNode * arg, SGPropertyNode * root) { - std::string name = args->getStringValue("name"); + std::string name = arg->getStringValue("name"); return unloadScenario(name); } diff --git a/src/AIModel/AIManager.hxx b/src/AIModel/AIManager.hxx index 545f8e5d0..91fe06f84 100644 --- a/src/AIModel/AIManager.hxx +++ b/src/AIModel/AIManager.hxx @@ -97,8 +97,8 @@ private: void removeDeadItem(FGAIBase* base); - bool loadScenarioCommand(const SGPropertyNode* args); - bool unloadScenarioCommand(const SGPropertyNode* args); + bool loadScenarioCommand(const SGPropertyNode* args, SGPropertyNode* root); + bool unloadScenarioCommand(const SGPropertyNode* args, SGPropertyNode* root); bool addObjectCommand(const SGPropertyNode* definition); bool removeObject(const SGPropertyNode* args); diff --git a/src/ATC/atcdialog.cxx b/src/ATC/atcdialog.cxx index d15127928..b98893f28 100644 --- a/src/ATC/atcdialog.cxx +++ b/src/ATC/atcdialog.cxx @@ -167,13 +167,13 @@ void FGATCDialogNew::frequencyDisplay(const std::string& ident) _gui->showDialog(dialog_name); } -static bool doFrequencySearch( const SGPropertyNode* ) +static bool doFrequencySearch( const SGPropertyNode*, SGPropertyNode * ) { FGATCDialogNew::instance()->frequencySearch(); return true; } -static bool doFrequencyDisplay( const SGPropertyNode* args ) +static bool doFrequencyDisplay( const SGPropertyNode* args, SGPropertyNode * root) { std::string icao = args->getStringValue("icao"); if (icao.empty()) { diff --git a/src/ATC/atcdialog.hxx b/src/ATC/atcdialog.hxx index a5d460e43..fda90200a 100644 --- a/src/ATC/atcdialog.hxx +++ b/src/ATC/atcdialog.hxx @@ -58,7 +58,7 @@ public: void addEntry(int, const std::string&); void removeEntry(int); - static bool popup( const SGPropertyNode * ) { + static bool popup( const SGPropertyNode *, SGPropertyNode * root) { instance()->PopupDialog(); return true; } diff --git a/src/Autopilot/digitalfilter.cxx b/src/Autopilot/digitalfilter.cxx index ffd6dade5..2ecd2eedc 100644 --- a/src/Autopilot/digitalfilter.cxx +++ b/src/Autopilot/digitalfilter.cxx @@ -589,23 +589,50 @@ void HighPassFilterImplementation::initialize( double initvalue ) _output_1 = initvalue; } -double HighPassFilterImplementation::compute( double dt, double input ) +//double HighPassFilterImplementation::compute( double dt, double input ) +//{ +// input = GainFilterImplementation::compute( dt, input ); +// double tf = _TfInput.get_value(); +// +// double output; +// +// // avoid negative filter times +// // and div by zero if -tf == dt +// +// double alpha = tf > 0.0 ? 1 / ((tf/dt) + 1) : 1.0; +// output = (1 - alpha) * (input - _input_1 + _output_1); +// _input_1 = input; +// _output_1 = output; +// return output; +//} + +double HighPassFilterImplementation::compute(double dt, double input) { - input = GainFilterImplementation::compute( dt, input ); - double tf = _TfInput.get_value(); + if (_isnan(input)) + SG_LOG(SG_AUTOPILOT, SG_ALERT, "High pass filter output is NaN."); - double output; + input = GainFilterImplementation::compute(dt, input); + double tf = _TfInput.get_value(); - // avoid negative filter times - // and div by zero if -tf == dt + double output; - double alpha = tf > 0.0 ? 1 / ((tf/dt) + 1) : 1.0; - output = (1 - alpha) * (input - _input_1 + _output_1); - _input_1 = input; - _output_1 = output; - return output; + // avoid negative filter times + // and div by zero if -tf == dt + + + double alpha = tf > 0.0 ? 1 / ((tf / dt) + 1) : 1.0; + output = (1 - alpha) * (input - _input_1 + _output_1); + _input_1 = input; + + // Catch NaN before it causes damage + + if (output != output) { + SG_LOG(SG_AUTOPILOT, SG_ALERT, "High pass filter output is NaN."); + output = 0.0; + } + _output_1 = output; + return output; } - //------------------------------------------------------------------------------ bool HighPassFilterImplementation::configure( SGPropertyNode& cfg_node, const std::string& cfg_name, @@ -803,6 +830,8 @@ void DigitalFilter::update( bool firstTime, double dt) } double input = _valueInput.get_value() - _referenceInput.get_value(); + if (_isnan(input)) + input = _valueInput.get_value() - _referenceInput.get_value(); double output = _implementation->compute( dt, input ); set_output_value( output ); diff --git a/src/Autopilot/inputvalue.cxx b/src/Autopilot/inputvalue.cxx index 21f633738..2e190d151 100644 --- a/src/Autopilot/inputvalue.cxx +++ b/src/Autopilot/inputvalue.cxx @@ -205,7 +205,8 @@ double InputValue::get_value() const if( _periodical ) { value = _periodical->normalize( value ); } - + if (_isnan(value)) + SG_LOG(SG_AUTOPILOT, SG_ALERT, "input is NaN." ); return _abs ? fabs(value) : value; } diff --git a/src/Autopilot/route_mgr.cxx b/src/Autopilot/route_mgr.cxx index b322c02e8..abf80d7c6 100644 --- a/src/Autopilot/route_mgr.cxx +++ b/src/Autopilot/route_mgr.cxx @@ -63,14 +63,14 @@ using namespace flightgear; using std::string; -static bool commandLoadFlightPlan(const SGPropertyNode* arg) +static bool commandLoadFlightPlan(const SGPropertyNode* arg, SGPropertyNode *) { FGRouteMgr* self = (FGRouteMgr*) globals->get_subsystem("route-manager"); SGPath path = SGPath::fromUtf8(arg->getStringValue("path")); return self->loadRoute(path); } -static bool commandSaveFlightPlan(const SGPropertyNode* arg) +static bool commandSaveFlightPlan(const SGPropertyNode* arg, SGPropertyNode *) { FGRouteMgr* self = (FGRouteMgr*) globals->get_subsystem("route-manager"); SGPath path = SGPath::fromUtf8(arg->getStringValue("path")); @@ -92,7 +92,7 @@ static bool commandSaveFlightPlan(const SGPropertyNode* arg) } } -static bool commandActivateFlightPlan(const SGPropertyNode* arg) +static bool commandActivateFlightPlan(const SGPropertyNode* arg, SGPropertyNode *) { FGRouteMgr* self = (FGRouteMgr*) globals->get_subsystem("route-manager"); bool activate = arg->getBoolValue("activate", true); @@ -105,14 +105,14 @@ static bool commandActivateFlightPlan(const SGPropertyNode* arg) return true; } -static bool commandClearFlightPlan(const SGPropertyNode*) +static bool commandClearFlightPlan(const SGPropertyNode*, SGPropertyNode *) { FGRouteMgr* self = (FGRouteMgr*) globals->get_subsystem("route-manager"); self->clearRoute(); return true; } -static bool commandSetActiveWaypt(const SGPropertyNode* arg) +static bool commandSetActiveWaypt(const SGPropertyNode* arg, SGPropertyNode *) { FGRouteMgr* self = (FGRouteMgr*) globals->get_subsystem("route-manager"); int index = arg->getIntValue("index"); @@ -124,7 +124,7 @@ static bool commandSetActiveWaypt(const SGPropertyNode* arg) return true; } -static bool commandInsertWaypt(const SGPropertyNode* arg) +static bool commandInsertWaypt(const SGPropertyNode* arg, SGPropertyNode *) { FGRouteMgr* self = (FGRouteMgr*) globals->get_subsystem("route-manager"); int index = arg->getIntValue("index"); @@ -213,7 +213,7 @@ static bool commandInsertWaypt(const SGPropertyNode* arg) return true; } -static bool commandDeleteWaypt(const SGPropertyNode* arg) +static bool commandDeleteWaypt(const SGPropertyNode* arg, SGPropertyNode *) { FGRouteMgr* self = (FGRouteMgr*) globals->get_subsystem("route-manager"); int index = arg->getIntValue("index"); @@ -1187,7 +1187,7 @@ SGPropertyNode_ptr FGRouteMgr::wayptNodeAtIndex(int index) const return mirror->getChild("wp", index); } -bool FGRouteMgr::commandDefineUserWaypoint(const SGPropertyNode* arg) +bool FGRouteMgr::commandDefineUserWaypoint(const SGPropertyNode * arg, SGPropertyNode * root) { std::string ident = arg->getStringValue("ident"); if (ident.empty()) { @@ -1209,7 +1209,7 @@ bool FGRouteMgr::commandDefineUserWaypoint(const SGPropertyNode* arg) return true; } -bool FGRouteMgr::commandDeleteUserWaypoint(const SGPropertyNode* arg) +bool FGRouteMgr::commandDeleteUserWaypoint(const SGPropertyNode * arg, SGPropertyNode * root) { std::string ident = arg->getStringValue("ident"); if (ident.empty()) { diff --git a/src/Autopilot/route_mgr.hxx b/src/Autopilot/route_mgr.hxx index 05b49dd41..361b1ab57 100644 --- a/src/Autopilot/route_mgr.hxx +++ b/src/Autopilot/route_mgr.hxx @@ -102,8 +102,8 @@ public: static const char* subsystemName() { return "route-manager"; } private: - bool commandDefineUserWaypoint(const SGPropertyNode* arg); - bool commandDeleteUserWaypoint(const SGPropertyNode* arg); + bool commandDefineUserWaypoint(const SGPropertyNode * arg, SGPropertyNode * root); + bool commandDeleteUserWaypoint(const SGPropertyNode * arg, SGPropertyNode * root); flightgear::FlightPlanRef _plan; diff --git a/src/Environment/fgclouds.cxx b/src/Environment/fgclouds.cxx index 13e2e1d1c..759313b85 100644 --- a/src/Environment/fgclouds.cxx +++ b/src/Environment/fgclouds.cxx @@ -346,7 +346,7 @@ bool FGClouds::get_3dClouds() const * (Various) - cloud definition properties. See README.3DClouds * */ - bool FGClouds::add3DCloud(const SGPropertyNode *arg) + bool FGClouds::add3DCloud(const SGPropertyNode *arg, SGPropertyNode * root) { int l = arg->getIntValue("layer", 0); int index = arg->getIntValue("index", 0); @@ -381,7 +381,7 @@ bool FGClouds::get_3dClouds() const * index - the cloud index * */ - bool FGClouds::delete3DCloud(const SGPropertyNode *arg) + bool FGClouds::delete3DCloud(const SGPropertyNode *arg, SGPropertyNode * root) { int l = arg->getIntValue("layer", 0); int i = arg->getIntValue("index", 0); @@ -400,7 +400,7 @@ bool FGClouds::get_3dClouds() const * lon/lat/alt - the position for the cloud * */ -bool FGClouds::move3DCloud(const SGPropertyNode *arg) +bool FGClouds::move3DCloud(const SGPropertyNode *arg, SGPropertyNode * root) { int l = arg->getIntValue("layer", 0); int i = arg->getIntValue("index", 0); diff --git a/src/Environment/fgclouds.hxx b/src/Environment/fgclouds.hxx index cd6df0c3b..136f2bdbc 100644 --- a/src/Environment/fgclouds.hxx +++ b/src/Environment/fgclouds.hxx @@ -42,9 +42,9 @@ private: bool clouds_3d_enabled; int index; - bool add3DCloud(const SGPropertyNode *arg); - bool delete3DCloud(const SGPropertyNode *arg); - bool move3DCloud(const SGPropertyNode *arg); + bool add3DCloud(const SGPropertyNode *arg, SGPropertyNode * root); + bool delete3DCloud(const SGPropertyNode *arg, SGPropertyNode * root); + bool move3DCloud(const SGPropertyNode *arg, SGPropertyNode * root); public: FGClouds(); diff --git a/src/Environment/realwx_ctrl.cxx b/src/Environment/realwx_ctrl.cxx index 17ded3034..37f09c32c 100644 --- a/src/Environment/realwx_ctrl.cxx +++ b/src/Environment/realwx_ctrl.cxx @@ -193,7 +193,7 @@ protected: }; -static bool commandRequestMetar(const SGPropertyNode* arg) +static bool commandRequestMetar(const SGPropertyNode * arg, SGPropertyNode * root) { SGSubsystemGroup* envMgr = (SGSubsystemGroup*) globals->get_subsystem("environment"); if (!envMgr) { @@ -212,7 +212,7 @@ static bool commandRequestMetar(const SGPropertyNode* arg) return true; } -static bool commandClearMetar(const SGPropertyNode* arg) +static bool commandClearMetar(const SGPropertyNode * arg, SGPropertyNode * root) { SGSubsystemGroup* envMgr = (SGSubsystemGroup*) globals->get_subsystem("environment"); if (!envMgr) { diff --git a/src/GUI/FGPUIMenuBar.cxx b/src/GUI/FGPUIMenuBar.cxx index 4833058b7..0815a35df 100644 --- a/src/GUI/FGPUIMenuBar.cxx +++ b/src/GUI/FGPUIMenuBar.cxx @@ -33,7 +33,7 @@ using std::map; #if defined(TR_HIRES_SNAP) extern void dumpHiResSnapShot (); static bool -do_hires_snapshot_dialog (const SGPropertyNode * arg) +do_hires_snapshot_dialog (const SGPropertyNode * arg, SGPropertyNode * root) { dumpHiResSnapShot(); return true; diff --git a/src/GUI/MessageBox.cxx b/src/GUI/MessageBox.cxx index 01cc07401..04e59df6a 100644 --- a/src/GUI/MessageBox.cxx +++ b/src/GUI/MessageBox.cxx @@ -117,7 +117,7 @@ MessageBoxResult modalMessageBox(const std::string& caption, args->setStringValue("caption", caption); args->setStringValue("message", msg); args->setStringValue("more", moreText); - globals->get_commands()->execute("canvas-message-box", args); + globals->get_commands()->execute("canvas-message-box", args, nullptr); // how to make it modal? diff --git a/src/GUI/MouseCursor.cxx b/src/GUI/MouseCursor.cxx index 5d8bff6ac..6283658ac 100644 --- a/src/GUI/MouseCursor.cxx +++ b/src/GUI/MouseCursor.cxx @@ -194,7 +194,7 @@ void FGMouseCursor::setAutoHideTimeMsec(unsigned int aMsec) } -bool FGMouseCursor::setCursorCommand(const SGPropertyNode* arg) +bool FGMouseCursor::setCursorCommand(const SGPropertyNode* arg, SGPropertyNode*) { // JMT 2013 - I would prefer this was a seperate 'warp' command, but // historically set-cursor has done both. diff --git a/src/GUI/MouseCursor.hxx b/src/GUI/MouseCursor.hxx index 077504cf1..c07b83f53 100644 --- a/src/GUI/MouseCursor.hxx +++ b/src/GUI/MouseCursor.hxx @@ -57,7 +57,7 @@ public: protected: FGMouseCursor(); - bool setCursorCommand(const SGPropertyNode* arg); + bool setCursorCommand(const SGPropertyNode* arg, SGPropertyNode*); unsigned int mAutoHideTimeMsec; }; diff --git a/src/GUI/gui.cxx b/src/GUI/gui.cxx index 733fb5cf9..ba639cb09 100644 --- a/src/GUI/gui.cxx +++ b/src/GUI/gui.cxx @@ -197,9 +197,9 @@ void syncPausePopupState() args->setStringValue("id", "sim-pause"); if (paused && fgGetBool("/sim/view-name-popup")) { args->setStringValue("label", "Simulation is paused"); - globals->get_commands()->execute("show-message", args); + globals->get_commands()->execute("show-message", args, nullptr); } else { - globals->get_commands()->execute("clear-message", args); + globals->get_commands()->execute("clear-message", args, nullptr); } } diff --git a/src/Input/FGJoystickInput.cxx b/src/Input/FGJoystickInput.cxx index 069e9d824..559e1db74 100644 --- a/src/Input/FGJoystickInput.cxx +++ b/src/Input/FGJoystickInput.cxx @@ -214,7 +214,7 @@ void FGJoystickInput::postinit() unsigned int j; for (j = 0; j < nasal.size(); j++) { nasal[j]->setStringValue("module", module.c_str()); - nasalsys->handleCommand(nasal[j]); + nasalsys->handleCommand(nasal[j],nullptr); } // diff --git a/src/Input/FGKeyboardInput.cxx b/src/Input/FGKeyboardInput.cxx index 3476c2c35..c762f6fe5 100644 --- a/src/Input/FGKeyboardInput.cxx +++ b/src/Input/FGKeyboardInput.cxx @@ -112,7 +112,7 @@ void FGKeyboardInput::postinit() PropertyList nasal = key_nodes->getChildren("nasal"); for (unsigned int j = 0; j < nasal.size(); j++) { nasal[j]->setStringValue("module", module.c_str()); - nasalsys->handleCommand(nasal[j]); + nasalsys->handleCommand(nasal[j], nullptr); } PropertyList keys = key_nodes->getChildren("key"); diff --git a/src/Input/FGMouseInput.cxx b/src/Input/FGMouseInput.cxx index ccef542bf..c4ee97822 100644 --- a/src/Input/FGMouseInput.cxx +++ b/src/Input/FGMouseInput.cxx @@ -263,7 +263,7 @@ public: FGMouseCursor::instance()->setCursor(cur); if (!didPick) { SGPropertyNode_ptr args(new SGPropertyNode); - globals->get_commands()->execute("update-hover", args); + globals->get_commands()->execute("update-hover", args, nullptr); } } @@ -501,7 +501,7 @@ void FGMouseInput::update ( double dt ) { d->tooltipTimeoutDone = true; SGPropertyNode_ptr arg(new SGPropertyNode); - globals->get_commands()->execute("tooltip-timeout", arg); + globals->get_commands()->execute("tooltip-timeout", arg, nullptr); } if ( d->hideCursor ) { @@ -610,7 +610,7 @@ void FGMouseInput::doMouseClick (int b, int updown, int x, int y, bool mainWindo if (d->clickTriggersTooltip) { SGPropertyNode_ptr args(new SGPropertyNode); args->setStringValue("reason", "click"); - globals->get_commands()->execute("tooltip-timeout", args); + globals->get_commands()->execute("tooltip-timeout", args, nullptr); d->tooltipTimeoutDone = true; } } else { diff --git a/src/Instrumentation/KLN89/kln89.cxx b/src/Instrumentation/KLN89/kln89.cxx index c0c72773e..36f663b5b 100644 --- a/src/Instrumentation/KLN89/kln89.cxx +++ b/src/Instrumentation/KLN89/kln89.cxx @@ -55,76 +55,76 @@ using std::string; // Command callbacks for FlightGear -static bool do_kln89_msg_pressed(const SGPropertyNode* arg) { +static bool do_kln89_msg_pressed(const SGPropertyNode * arg, SGPropertyNode * root) { //cout << "do_kln89_msg_pressed called!\n"; KLN89* gps = (KLN89*)globals->get_subsystem("kln89"); gps->MsgPressed(); return(true); } -static bool do_kln89_obs_pressed(const SGPropertyNode* arg) { +static bool do_kln89_obs_pressed(const SGPropertyNode * arg, SGPropertyNode * root) { //cout << "do_kln89_obs_pressed called!\n"; KLN89* gps = (KLN89*)globals->get_subsystem("kln89"); gps->OBSPressed(); return(true); } -static bool do_kln89_alt_pressed(const SGPropertyNode* arg) { +static bool do_kln89_alt_pressed(const SGPropertyNode * arg, SGPropertyNode * root) { //cout << "do_kln89_alt_pressed called!\n"; KLN89* gps = (KLN89*)globals->get_subsystem("kln89"); gps->AltPressed(); return(true); } -static bool do_kln89_nrst_pressed(const SGPropertyNode* arg) { +static bool do_kln89_nrst_pressed(const SGPropertyNode * arg, SGPropertyNode * root) { KLN89* gps = (KLN89*)globals->get_subsystem("kln89"); gps->NrstPressed(); return(true); } -static bool do_kln89_dto_pressed(const SGPropertyNode* arg) { +static bool do_kln89_dto_pressed(const SGPropertyNode * arg, SGPropertyNode * root) { KLN89* gps = (KLN89*)globals->get_subsystem("kln89"); gps->DtoPressed(); return(true); } -static bool do_kln89_clr_pressed(const SGPropertyNode* arg) { +static bool do_kln89_clr_pressed(const SGPropertyNode * arg, SGPropertyNode * root) { KLN89* gps = (KLN89*)globals->get_subsystem("kln89"); gps->ClrPressed(); return(true); } -static bool do_kln89_ent_pressed(const SGPropertyNode* arg) { +static bool do_kln89_ent_pressed(const SGPropertyNode * arg, SGPropertyNode * root) { KLN89* gps = (KLN89*)globals->get_subsystem("kln89"); gps->EntPressed(); return(true); } -static bool do_kln89_crsr_pressed(const SGPropertyNode* arg) { +static bool do_kln89_crsr_pressed(const SGPropertyNode * arg, SGPropertyNode * root) { KLN89* gps = (KLN89*)globals->get_subsystem("kln89"); gps->CrsrPressed(); return(true); } -static bool do_kln89_knob1left1(const SGPropertyNode* arg) { +static bool do_kln89_knob1left1(const SGPropertyNode * arg, SGPropertyNode * root) { KLN89* gps = (KLN89*)globals->get_subsystem("kln89"); gps->Knob1Left1(); return(true); } -static bool do_kln89_knob1right1(const SGPropertyNode* arg) { +static bool do_kln89_knob1right1(const SGPropertyNode * arg, SGPropertyNode * root) { KLN89* gps = (KLN89*)globals->get_subsystem("kln89"); gps->Knob1Right1(); return(true); } -static bool do_kln89_knob2left1(const SGPropertyNode* arg) { +static bool do_kln89_knob2left1(const SGPropertyNode * arg, SGPropertyNode * root) { KLN89* gps = (KLN89*)globals->get_subsystem("kln89"); gps->Knob2Left1(); return(true); } -static bool do_kln89_knob2right1(const SGPropertyNode* arg) { +static bool do_kln89_knob2right1(const SGPropertyNode * arg, SGPropertyNode * root) { KLN89* gps = (KLN89*)globals->get_subsystem("kln89"); gps->Knob2Right1(); return(true); diff --git a/src/Main/fg_commands.cxx b/src/Main/fg_commands.cxx index 4ed34d63e..eb070930f 100644 --- a/src/Main/fg_commands.cxx +++ b/src/Main/fg_commands.cxx @@ -62,14 +62,36 @@ using std::ofstream; static inline SGPropertyNode * -get_prop (const SGPropertyNode * arg) +get_prop (const SGPropertyNode * arg, SGPropertyNode * root) { + if (root != nullptr) + { + SGPropertyNode *rv = nullptr; + rv = root->getNode(arg->getStringValue("property[0]", "/null"), 0, true); + if (rv == nullptr) + { + rv = root->getNode(arg->getStringValue("property[0]", "/null"), 0, true); + return fgGetNode(arg->getStringValue("property[0]", "/null"), true); + } + return rv; + } return fgGetNode(arg->getStringValue("property[0]", "/null"), true); } static inline SGPropertyNode * -get_prop2 (const SGPropertyNode * arg) +get_prop2 (const SGPropertyNode * arg, SGPropertyNode * root) { + if (root != nullptr) + { + SGPropertyNode *rv = nullptr; + rv = root->getNode(arg->getStringValue("property[1]", "/null"), 0, true); + if (rv == nullptr) + { + rv = root->getNode(arg->getStringValue("property[1]", "/null"), 0, true); + return fgGetNode(arg->getStringValue("property[1]", "/null"), true); + } + return rv; + } return fgGetNode(arg->getStringValue("property[1]", "/null"), true); } @@ -163,7 +185,7 @@ compare_values (SGPropertyNode * value1, SGPropertyNode * value2) * Built-in command: do nothing. */ static bool -do_null (const SGPropertyNode * arg) +do_null (const SGPropertyNode * arg, SGPropertyNode * root) { return true; } @@ -172,16 +194,16 @@ do_null (const SGPropertyNode * arg) * Built-in command: run a Nasal script. */ static bool -do_nasal (const SGPropertyNode * arg) +do_nasal (const SGPropertyNode * arg, SGPropertyNode * root) { - return ((FGNasalSys*)globals->get_subsystem("nasal"))->handleCommand(arg); + return ((FGNasalSys*)globals->get_subsystem("nasal"))->handleCommand(arg, root); } /** * Built-in command: replay the FDR buffer */ static bool -do_replay (const SGPropertyNode * arg) +do_replay (const SGPropertyNode * arg, SGPropertyNode * root) { FGReplay *r = (FGReplay *)(globals->get_subsystem( "replay" )); return r->start(); @@ -191,7 +213,7 @@ do_replay (const SGPropertyNode * arg) * Built-in command: pause/unpause the sim */ static bool -do_pause (const SGPropertyNode * arg) +do_pause (const SGPropertyNode * arg, SGPropertyNode * root) { bool forcePause = arg->getBoolValue("force-pause", false ); bool forcePlay = arg->getBoolValue("force-play", false ); @@ -203,7 +225,7 @@ do_pause (const SGPropertyNode * arg) if (paused && (fgGetInt("/sim/freeze/replay-state",0)>0)) { - do_replay(NULL); + do_replay(NULL, nullptr); } else { @@ -222,7 +244,7 @@ do_pause (const SGPropertyNode * arg) * directory). Defaults to "fgfs.sav" */ static bool -do_load (const SGPropertyNode * arg) +do_load (const SGPropertyNode * arg, SGPropertyNode * root) { SGPath file(arg->getStringValue("file", "fgfs.sav")); @@ -255,7 +277,7 @@ do_load (const SGPropertyNode * arg) * current directory). Defaults to "fgfs.sav". */ static bool -do_save (const SGPropertyNode * arg) +do_save (const SGPropertyNode * arg, SGPropertyNode * root) { SGPath file(arg->getStringValue("file", "fgfs.sav")); @@ -287,7 +309,7 @@ do_save (const SGPropertyNode * arg) * */ static bool -do_save_tape (const SGPropertyNode * arg) +do_save_tape (const SGPropertyNode * arg, SGPropertyNode * root) { FGReplay* replay = (FGReplay*) globals->get_subsystem("replay"); replay->saveTape(arg); @@ -299,7 +321,7 @@ do_save_tape (const SGPropertyNode * arg) * */ static bool -do_load_tape (const SGPropertyNode * arg) +do_load_tape (const SGPropertyNode * arg, SGPropertyNode * root) { FGReplay* replay = (FGReplay*) globals->get_subsystem("replay"); replay->loadTape(arg); @@ -333,7 +355,7 @@ do_view_prev(bool do_it) * Built-in command: cycle view. */ static bool -do_view_cycle (const SGPropertyNode * arg) +do_view_cycle (const SGPropertyNode * arg, SGPropertyNode * root) { globals->get_current_view()->setHeadingOffset_deg(0.0); globals->get_viewmgr()->next_view(); @@ -346,9 +368,9 @@ do_view_cycle (const SGPropertyNode * arg) * property: The name of the property to toggle. */ static bool -do_property_toggle (const SGPropertyNode * arg) +do_property_toggle (const SGPropertyNode * arg, SGPropertyNode * root) { - SGPropertyNode * prop = get_prop(arg); + SGPropertyNode * prop = get_prop(arg, root); return prop->setBoolValue(!prop->getBoolValue()); } @@ -361,16 +383,16 @@ do_property_toggle (const SGPropertyNode * arg) * property[1]: the property to copy from. */ static bool -do_property_assign (const SGPropertyNode * arg) +do_property_assign (const SGPropertyNode * arg, SGPropertyNode * root) { - SGPropertyNode * prop = get_prop(arg); + SGPropertyNode * prop = get_prop(arg,root); const SGPropertyNode * value = arg->getNode("value"); if (value != 0) return prop->setUnspecifiedValue(value->getStringValue()); else { - const SGPropertyNode * prop2 = get_prop2(arg); + const SGPropertyNode * prop2 = get_prop2(arg,root); if (prop2) return prop->setUnspecifiedValue(prop2->getStringValue()); else @@ -400,9 +422,9 @@ do_property_assign (const SGPropertyNode * arg) * false). */ static bool -do_property_adjust (const SGPropertyNode * arg) +do_property_adjust (const SGPropertyNode * arg, SGPropertyNode * root) { - SGPropertyNode * prop = get_prop(arg); + SGPropertyNode * prop = get_prop(arg,root); double amount = 0; if (arg->hasValue("step")) @@ -438,9 +460,9 @@ do_property_adjust (const SGPropertyNode * arg) * false). */ static bool -do_property_multiply (const SGPropertyNode * arg) +do_property_multiply (const SGPropertyNode * arg, SGPropertyNode * root) { - SGPropertyNode * prop = get_prop(arg); + SGPropertyNode * prop = get_prop(arg,root); double factor = arg->getDoubleValue("factor", 1); double unmodifiable, modifiable; @@ -462,10 +484,10 @@ do_property_multiply (const SGPropertyNode * arg) * property[1]: the name of the second property. */ static bool -do_property_swap (const SGPropertyNode * arg) +do_property_swap (const SGPropertyNode * arg, SGPropertyNode * root) { - SGPropertyNode * prop1 = get_prop(arg); - SGPropertyNode * prop2 = get_prop2(arg); + SGPropertyNode * prop1 = get_prop(arg,root); + SGPropertyNode * prop2 = get_prop2(arg,root); // FIXME: inefficient const string & tmp = prop1->getStringValue(); @@ -483,9 +505,9 @@ do_property_swap (const SGPropertyNode * arg) * factor: the factor to multiply by (use negative to reverse). */ static bool -do_property_scale (const SGPropertyNode * arg) +do_property_scale (const SGPropertyNode * arg, SGPropertyNode * root) { - SGPropertyNode * prop = get_prop(arg); + SGPropertyNode * prop = get_prop(arg,root); double setting = arg->getDoubleValue("setting"); double offset = arg->getDoubleValue("offset", 0.0); double factor = arg->getDoubleValue("factor", 1.0); @@ -527,9 +549,9 @@ do_property_scale (const SGPropertyNode * arg) * value[*]: the list of values to cycle through. */ static bool -do_property_cycle (const SGPropertyNode * arg) +do_property_cycle (const SGPropertyNode * arg, SGPropertyNode * root) { - SGPropertyNode * prop = get_prop(arg); + SGPropertyNode * prop = get_prop(arg,root); std::vector values = arg->getChildren("value"); bool wrap = arg->getBoolValue("wrap", true); @@ -576,9 +598,9 @@ do_property_cycle (const SGPropertyNode * arg) * max: the maximum allowed value. */ static bool -do_property_randomize (const SGPropertyNode * arg) +do_property_randomize (const SGPropertyNode * arg, SGPropertyNode * root) { - SGPropertyNode * prop = get_prop(arg); + SGPropertyNode * prop = get_prop(arg,root); double min = arg->getDoubleValue("min", DBL_MIN); double max = arg->getDoubleValue("max", DBL_MAX); prop->setDoubleValue(sg_random() * (max - min) + min); @@ -604,9 +626,9 @@ do_property_randomize (const SGPropertyNode * arg) * the property value at the given speed. */ static bool -do_property_interpolate (const SGPropertyNode * arg) +do_property_interpolate (const SGPropertyNode * arg, SGPropertyNode * root) { - SGPropertyNode * prop = get_prop(arg); + SGPropertyNode * prop = get_prop(arg,root); if( !prop ) return false; @@ -675,7 +697,7 @@ do_property_interpolate (const SGPropertyNode * arg) * current contents of the /logger tree. */ static bool -do_data_logging_commit (const SGPropertyNode * arg) +do_data_logging_commit (const SGPropertyNode * arg, SGPropertyNode * root) { FGLogger *log = (FGLogger *)globals->get_subsystem("logger"); log->reinit(); @@ -686,7 +708,7 @@ do_data_logging_commit (const SGPropertyNode * arg) * Built-in command: set log level (0 ... 7) */ static bool -do_log_level (const SGPropertyNode * arg) +do_log_level (const SGPropertyNode * arg, SGPropertyNode * root) { sglog().setLogLevels( SG_ALL, (sgDebugPriority)arg->getIntValue() ); @@ -706,7 +728,7 @@ do_log_level (const SGPropertyNode * arg) */ static bool -do_load_xml_to_proptree(const SGPropertyNode * arg) +do_load_xml_to_proptree(const SGPropertyNode * arg, SGPropertyNode * root) { SGPath file(arg->getStringValue("filename")); if (file.isNull()) @@ -760,7 +782,7 @@ do_load_xml_to_proptree(const SGPropertyNode * arg) } static bool -do_load_xml_from_url(const SGPropertyNode * arg) +do_load_xml_from_url(const SGPropertyNode * arg, SGPropertyNode * root) { FGHTTPClient* http = static_cast(globals->get_subsystem("http")); if (!http) { @@ -810,7 +832,7 @@ do_load_xml_from_url(const SGPropertyNode * arg) */ static bool -do_save_xml_from_proptree(const SGPropertyNode * arg) +do_save_xml_from_proptree(const SGPropertyNode * arg, SGPropertyNode * root) { SGPath file(arg->getStringValue("filename")); if (file.isNull()) @@ -861,7 +883,7 @@ no_profiling_support() #endif static bool -do_profiler_start(const SGPropertyNode *arg) +do_profiler_start(const SGPropertyNode *arg, SGPropertyNode *root) { #if FG_HAVE_GPERFTOOLS const char *filename = arg->getStringValue("filename", "fgfs.profile"); @@ -874,7 +896,7 @@ do_profiler_start(const SGPropertyNode *arg) } static bool -do_profiler_stop(const SGPropertyNode *arg) +do_profiler_stop(const SGPropertyNode *arg, SGPropertyNode *root) { #if FG_HAVE_GPERFTOOLS ProfilerStop(); diff --git a/src/Main/fg_scene_commands.cxx b/src/Main/fg_scene_commands.cxx index 7e1ed2ddf..7337a3f30 100644 --- a/src/Main/fg_scene_commands.cxx +++ b/src/Main/fg_scene_commands.cxx @@ -71,7 +71,7 @@ * status: the exit status to return to the operating system (defaults to 0) */ static bool -do_exit (const SGPropertyNode * arg) +do_exit (const SGPropertyNode * arg, SGPropertyNode * root) { SG_LOG(SG_INPUT, SG_INFO, "Program exit requested."); fgSetBool("/sim/signals/exit", true); @@ -85,7 +85,7 @@ do_exit (const SGPropertyNode * arg) * Reset FlightGear (Shift-Escape or Menu->File->Reset) */ static bool -do_reset (const SGPropertyNode * arg) +do_reset (const SGPropertyNode * arg, SGPropertyNode * root) { fgResetIdleState(); return true; @@ -96,7 +96,7 @@ do_reset (const SGPropertyNode * arg) * Change aircraft */ static bool -do_switch_aircraft (const SGPropertyNode * arg) +do_switch_aircraft (const SGPropertyNode * arg, SGPropertyNode * root) { fgSetString("/sim/aircraft", arg->getStringValue("aircraft")); // start a reset @@ -107,7 +107,7 @@ do_switch_aircraft (const SGPropertyNode * arg) /** */ static bool -do_reposition (const SGPropertyNode * arg) +do_reposition (const SGPropertyNode * arg, SGPropertyNode * root) { fgStartReposition(); return true; @@ -121,7 +121,7 @@ do_reposition (const SGPropertyNode * arg) * and if that's unspecified, to "Panels/Default/default.xml". */ static bool -do_panel_load (const SGPropertyNode * arg) +do_panel_load (const SGPropertyNode * arg, SGPropertyNode * root) { string panel_path = arg->getStringValue("path"); if (!panel_path.empty()) { @@ -139,7 +139,7 @@ do_panel_load (const SGPropertyNode * arg) * to FG_ROOT). Defaults to "preferences.xml". */ static bool -do_preferences_load (const SGPropertyNode * arg) +do_preferences_load (const SGPropertyNode * arg, SGPropertyNode * root) { // disabling this command which was formerly used to reload 'preferences.xml' // reloading the defaults doesn't make sense (better to reset the simulator), @@ -154,7 +154,7 @@ do_preferences_load (const SGPropertyNode * arg) * No parameters. */ static bool -do_toggle_fullscreen(const SGPropertyNode *arg) +do_toggle_fullscreen(const SGPropertyNode*, SGPropertyNode*) { fgOSFullScreen(); return true; @@ -164,27 +164,27 @@ do_toggle_fullscreen(const SGPropertyNode *arg) * Built-in command: capture screen. */ static bool -do_screen_capture (const SGPropertyNode * arg) +do_screen_capture(const SGPropertyNode*, SGPropertyNode*) { return fgDumpSnapShot(); } static bool -do_reload_shaders (const SGPropertyNode*) +do_reload_shaders (const SGPropertyNode*, SGPropertyNode*) { simgear::reload_shaders(); return true; } static bool -do_dump_scene_graph (const SGPropertyNode*) +do_dump_scene_graph (const SGPropertyNode*, SGPropertyNode*) { fgDumpSceneGraph(); return true; } static bool -do_dump_terrain_branch (const SGPropertyNode*) +do_dump_terrain_branch (const SGPropertyNode*, SGPropertyNode*) { fgDumpTerrainBranch(); @@ -201,7 +201,7 @@ do_dump_terrain_branch (const SGPropertyNode*) } static bool -do_print_visible_scene_info(const SGPropertyNode*) +do_print_visible_scene_info(const SGPropertyNode*, SGPropertyNode*) { fgPrintVisibleSceneInfoCommand(); return true; @@ -211,7 +211,7 @@ do_print_visible_scene_info(const SGPropertyNode*) * Built-in command: hires capture screen. */ static bool -do_hires_screen_capture (const SGPropertyNode * arg) +do_hires_screen_capture (const SGPropertyNode * arg, SGPropertyNode * root) { fgHiResDump(); return true; @@ -222,7 +222,7 @@ do_hires_screen_capture (const SGPropertyNode * arg) * Reload the tile cache. */ static bool -do_tile_cache_reload (const SGPropertyNode * arg) +do_tile_cache_reload (const SGPropertyNode * arg, SGPropertyNode * root) { SGPropertyNode *master_freeze = fgGetNode("/sim/freeze/master"); bool freeze = master_freeze->getBoolValue(); @@ -243,7 +243,7 @@ do_tile_cache_reload (const SGPropertyNode * arg) * Reload the materials definition */ static bool -do_materials_reload (const SGPropertyNode * arg) +do_materials_reload (const SGPropertyNode * arg, SGPropertyNode * root) { SG_LOG(SG_INPUT, SG_INFO, "Reloading Materials"); SGMaterialLib* new_matlib = new SGMaterialLib; @@ -274,7 +274,7 @@ do_materials_reload (const SGPropertyNode * arg) * name: the name of the GUI dialog for future reference. */ static bool -do_dialog_new (const SGPropertyNode * arg) +do_dialog_new (const SGPropertyNode * arg, SGPropertyNode * root) { NewGUI * gui = (NewGUI *)globals->get_subsystem("gui"); if (!gui) { @@ -298,7 +298,7 @@ do_dialog_new (const SGPropertyNode * arg) * dialog-name: the name of the GUI dialog to display. */ static bool -do_dialog_show (const SGPropertyNode * arg) +do_dialog_show (const SGPropertyNode * arg, SGPropertyNode * root) { NewGUI * gui = (NewGUI *)globals->get_subsystem("gui"); gui->showDialog(arg->getStringValue("dialog-name")); @@ -310,7 +310,7 @@ do_dialog_show (const SGPropertyNode * arg) * Built-in Command: Hide the active XML-configured dialog. */ static bool -do_dialog_close (const SGPropertyNode * arg) +do_dialog_close (const SGPropertyNode * arg, SGPropertyNode * root) { NewGUI * gui = (NewGUI *)globals->get_subsystem("gui"); if(arg->hasValue("dialog-name")) @@ -325,7 +325,7 @@ do_dialog_close (const SGPropertyNode * arg) * object-name: The name of the GUI object(s) (all GUI objects if omitted). */ static bool -do_dialog_update (const SGPropertyNode * arg) +do_dialog_update (const SGPropertyNode * arg, SGPropertyNode * root) { NewGUI * gui = (NewGUI *)globals->get_subsystem("gui"); FGDialog * dialog; @@ -343,7 +343,7 @@ do_dialog_update (const SGPropertyNode * arg) } static bool -do_open_browser (const SGPropertyNode * arg) +do_open_browser (const SGPropertyNode * arg, SGPropertyNode * root) { string path; if (arg->hasValue("path")) @@ -358,7 +358,7 @@ do_open_browser (const SGPropertyNode * arg) } static bool -do_open_launcher(const SGPropertyNode *) +do_open_launcher(const SGPropertyNode*, SGPropertyNode*) { #if defined(HAVE_QT) bool ok = flightgear::runInAppLauncherDialog(); @@ -378,7 +378,7 @@ do_open_launcher(const SGPropertyNode *) * object-name: The name of the GUI object(s) (all GUI objects if omitted). */ static bool -do_dialog_apply (const SGPropertyNode * arg) +do_dialog_apply (const SGPropertyNode * arg, SGPropertyNode * root) { NewGUI * gui = (NewGUI *)globals->get_subsystem("gui"); FGDialog * dialog; @@ -401,7 +401,7 @@ do_dialog_apply (const SGPropertyNode * arg) * unlike reinit(). */ static bool -do_gui_redraw (const SGPropertyNode * arg) +do_gui_redraw (const SGPropertyNode * arg, SGPropertyNode * root) { NewGUI * gui = (NewGUI *)globals->get_subsystem("gui"); gui->redraw(); @@ -414,7 +414,7 @@ do_gui_redraw (const SGPropertyNode * arg) * is returned in property "property". */ static bool -do_add_model (const SGPropertyNode * arg) +do_add_model (const SGPropertyNode * arg, SGPropertyNode * root) { SGPropertyNode * model = fgGetNode("models", true); int i; @@ -434,7 +434,7 @@ do_add_model (const SGPropertyNode * arg) * Built-in command: commit presets (read from in /sim/presets/) */ static bool -do_presets_commit (const SGPropertyNode * arg) +do_presets_commit (const SGPropertyNode * arg, SGPropertyNode * root) { if (fgGetBool("/sim/initialized", false)) { fgResetIdleState(); @@ -449,7 +449,7 @@ do_presets_commit (const SGPropertyNode * arg) } static bool -do_press_cockpit_button (const SGPropertyNode *arg) +do_press_cockpit_button (const SGPropertyNode * arg, SGPropertyNode * root) { const char *prefix = arg->getStringValue("prefix"); @@ -471,7 +471,7 @@ do_press_cockpit_button (const SGPropertyNode *arg) } static bool -do_release_cockpit_button (const SGPropertyNode *arg) +do_release_cockpit_button (const SGPropertyNode * arg, SGPropertyNode * root) { const char *prefix = arg->getStringValue("prefix"); diff --git a/src/Main/subsystemFactory.cxx b/src/Main/subsystemFactory.cxx index aeb61aa56..05fce574d 100644 --- a/src/Main/subsystemFactory.cxx +++ b/src/Main/subsystemFactory.cxx @@ -188,18 +188,18 @@ static SGSubsystem* getSubsystem(const SGPropertyNode* arg, bool create) } static bool -do_check_subsystem_running(const SGPropertyNode* arg) +do_check_subsystem_running(const SGPropertyNode * arg, SGPropertyNode * root) { return getSubsystem(arg, false) != 0; } static bool -do_add_subsystem (const SGPropertyNode * arg) +do_add_subsystem (const SGPropertyNode * arg, SGPropertyNode * root) { return getSubsystem(arg, true) != 0; } -static bool do_remove_subsystem(const SGPropertyNode * arg) +static bool do_remove_subsystem(const SGPropertyNode * arg, SGPropertyNode * root) { std::string name = arg->getStringValue("subsystem"); @@ -226,7 +226,7 @@ static bool do_remove_subsystem(const SGPropertyNode * arg) * none is specified, reinitialize all of them. */ static bool -do_reinit (const SGPropertyNode * arg) +do_reinit (const SGPropertyNode * arg, SGPropertyNode * root) { bool result = true; @@ -258,7 +258,7 @@ do_reinit (const SGPropertyNode * arg) * subsystem[*] - the name(s) of the subsystem(s) to suspend. */ static bool -do_suspend (const SGPropertyNode * arg) +do_suspend (const SGPropertyNode * arg, SGPropertyNode * root) { bool result = true; @@ -282,7 +282,7 @@ do_suspend (const SGPropertyNode * arg) * subsystem[*] - the name(s) of the subsystem(s) to suspend. */ static bool -do_resume (const SGPropertyNode * arg) +do_resume (const SGPropertyNode * arg, SGPropertyNode * root) { bool result = true; diff --git a/src/Model/panelnode.cxx b/src/Model/panelnode.cxx index 0c725d4e4..72224fdc7 100644 --- a/src/Model/panelnode.cxx +++ b/src/Model/panelnode.cxx @@ -430,7 +430,7 @@ osg::Node* FGPanelNode::load(SGPropertyNode *n) * y-pos: the y position of the mouse click. */ bool -FGPanelNode::panelMouseClickCommand(const SGPropertyNode * arg) +FGPanelNode::panelMouseClickCommand(const SGPropertyNode * arg, SGPropertyNode * root) { return _panel->doMouseAction(arg->getIntValue("button"), arg->getBoolValue("is-down") ? PU_DOWN : PU_UP, diff --git a/src/Model/panelnode.hxx b/src/Model/panelnode.hxx index debeb414f..05748d147 100644 --- a/src/Model/panelnode.hxx +++ b/src/Model/panelnode.hxx @@ -64,7 +64,7 @@ private: void commonInit(); void initWithPanel(); - bool panelMouseClickCommand(const SGPropertyNode * arg); + bool panelMouseClickCommand(const SGPropertyNode * arg, SGPropertyNode * root); const bool _is2d; SGSharedPtr _panel; diff --git a/src/MultiPlayer/multiplaymgr.cxx b/src/MultiPlayer/multiplaymgr.cxx index 78fcb8763..b785ea1ea 100644 --- a/src/MultiPlayer/multiplaymgr.cxx +++ b/src/MultiPlayer/multiplaymgr.cxx @@ -57,8 +57,7 @@ using namespace std; #define MAX_PACKET_SIZE 1200 -#define MAX_TEXT_SIZE 128 - +#define MAX_TEXT_SIZE 768 // Increased for 2017.3 to allow for long Emesary messages. /* * With the MP2017(V2) protocol it should be possible to transmit using a different type/encoding than the property has, * so it should be possible to transmit a bool as @@ -102,7 +101,21 @@ const int V2_PAD_MAGIC = 0x1face002; * These parameters define where these are mapped and how they are sent. * The blocks should be in the same property range (with no other properties inside the range) */ -const int BOOLARRAY_BLOCKSIZE = 40; +const int BOOLARRAY_BLOCKSIZE = 40; + +/* +* 2017.3 introduces a new Generic Packet concept. +* This allows a model to choose to only transmit a few essential properties, which leaves the packet at around 380 bytes. +* The rest of the packet can then be used for bridged Emesary notifications, which over allow much more control +* at the model level, including different notifications being sent. +* see $FGData/Nasal/Notifications.nas and $FGData/Nasal/emesary_mp_bridge.nas +*/ +static inline bool IsIncludedInGenericPacket(int property_id) +{ + return property_id >= 10002 + || (property_id >= 1500 && property_id < 1600); // include chat and generic properties. +} + const int BOOLARRAY_BASE_1 = 11000; const int BOOLARRAY_BASE_2 = BOOLARRAY_BASE_1 + BOOLARRAY_BLOCKSIZE; const int BOOLARRAY_BASE_3 = BOOLARRAY_BASE_2 + BOOLARRAY_BLOCKSIZE; @@ -718,7 +731,7 @@ private: // txport: outgoing port number (default: 5000) // rxport: incoming port number (default: 5000) ////////////////////////////////////////////////////////////////////// -static bool do_multiplayer_connect(const SGPropertyNode * arg) { +static bool do_multiplayer_connect(const SGPropertyNode * arg, SGPropertyNode * root) { FGMultiplayMgr * self = (FGMultiplayMgr*) globals->get_subsystem("mp"); if (!self) { SG_LOG(SG_NETWORK, SG_WARN, "Multiplayer subsystem not available."); @@ -753,7 +766,7 @@ static bool do_multiplayer_connect(const SGPropertyNode * arg) { // disconnect args: // none ////////////////////////////////////////////////////////////////////// -static bool do_multiplayer_disconnect(const SGPropertyNode * arg) { +static bool do_multiplayer_disconnect(const SGPropertyNode * arg, SGPropertyNode * root) { FGMultiplayMgr * self = (FGMultiplayMgr*) globals->get_subsystem("mp"); if (!self) { SG_LOG(SG_NETWORK, SG_WARN, "Multiplayer subsystem not available."); @@ -774,7 +787,7 @@ static bool do_multiplayer_disconnect(const SGPropertyNode * arg) { ////////////////////////////////////////////////////////////////////// static bool -do_multiplayer_refreshserverlist (const SGPropertyNode * arg) +do_multiplayer_refreshserverlist (const SGPropertyNode * arg, SGPropertyNode * root) { using namespace simgear; @@ -844,6 +857,7 @@ FGMultiplayMgr::FGMultiplayMgr() pXmitLen = fgGetNode("/sim/multiplay/last-xmit-packet-len", true); pProtocolVersion = fgGetNode("/sim/multiplay/protocol-version", true); pMultiPlayDebugLevel = fgGetNode("/sim/multiplay/debug-level", true); + pMultiPlayTransmitOnlyGenerics = fgGetNode("/sim/multiplay/transmit-only-generics", true); pMultiPlayRange = fgGetNode("/sim/multiplay/visibility-range-nm", true); pMultiPlayRange->setIntValue(100); } // FGMultiplayMgr::FGMultiplayMgr() @@ -1106,7 +1120,7 @@ void FGMultiplayMgr::SendMyPosition(const FGExternalMotionData& motionInfo) { int protocolToUse = getProtocolToUse(); - + int transmitOnlyGenerics = pMultiPlayTransmitOnlyGenerics->getIntValue(); if ((! mInitialised) || (! mHaveServer)) return; @@ -1214,7 +1228,14 @@ FGMultiplayMgr::SendMyPosition(const FGExternalMotionData& motionInfo) ++it; continue; } - + /* + * If requested only transmit the generic properties. + */ + if (transmitOnlyGenerics && !IsIncludedInGenericPacket(propDef->id)) + { + ++it; + continue; + } /* * 2017.2 partitions the buffer sent into protocol versions. Originally this was intended to allow * compatability with older clients; however this will only work in the future or with support from fgms diff --git a/src/MultiPlayer/multiplaymgr.hxx b/src/MultiPlayer/multiplaymgr.hxx index a2ad31ef8..800009516 100644 --- a/src/MultiPlayer/multiplaymgr.hxx +++ b/src/MultiPlayer/multiplaymgr.hxx @@ -115,6 +115,7 @@ private: SGPropertyNode *pXmitLen; SGPropertyNode *pMultiPlayDebugLevel; SGPropertyNode *pMultiPlayRange; + SGPropertyNode *pMultiPlayTransmitOnlyGenerics; typedef std::map PropertyDefinitionMap; PropertyDefinitionMap mPropertyDefinition; diff --git a/src/Network/http/PropertyChangeWebsocket.cxx b/src/Network/http/PropertyChangeWebsocket.cxx index 0c70061f1..81f3ab501 100644 --- a/src/Network/http/PropertyChangeWebsocket.cxx +++ b/src/Network/http/PropertyChangeWebsocket.cxx @@ -114,7 +114,7 @@ static void handleExecCommand(cJSON* json) SGPropertyNode_ptr arg(new SGPropertyNode); JSON::addChildrenToProp( json, arg ); - globals->get_commands()->execute(name->valuestring, arg); + globals->get_commands()->execute(name->valuestring, arg, nullptr); } PropertyChangeWebsocket::PropertyChangeWebsocket(PropertyChangeObserver * propertyChangeObserver) diff --git a/src/Network/http/RunUriHandler.cxx b/src/Network/http/RunUriHandler.cxx index 1b3f7005c..963760834 100644 --- a/src/Network/http/RunUriHandler.cxx +++ b/src/Network/http/RunUriHandler.cxx @@ -50,7 +50,7 @@ bool RunUriHandler::handleRequest( const HTTPRequest & request, HTTPResponse & r SG_LOG( SG_NETWORK, SG_INFO, "RunUriHandler("<< request.Content << "): command='" << command << "', arg='" << JSON::toJsonString(false,args,5) << "'"); cJSON_Delete( json ); - if ( globals->get_commands()->execute(command.c_str(), args) ) { + if ( globals->get_commands()->execute(command.c_str(), args, nullptr) ) { response.Content = "ok."; return true; } diff --git a/src/Network/props.cxx b/src/Network/props.cxx index 5574b3402..df9179787 100644 --- a/src/Network/props.cxx +++ b/src/Network/props.cxx @@ -384,7 +384,7 @@ PropsChannel::foundTerminator() node->setStringValue( tokens[i].c_str() ); } if ( !globals->get_commands() - ->execute( "reinit", &args) ) + ->execute( "reinit", &args, nullptr) ) { SG_LOG( SG_NETWORK, SG_ALERT, "Command " << tokens[1] << " failed."); @@ -449,7 +449,7 @@ PropsChannel::foundTerminator() } } if ( !globals->get_commands() - ->execute(tokens[1].c_str(), &args) ) + ->execute(tokens[1].c_str(), &args, nullptr) ) { SG_LOG( SG_NETWORK, SG_ALERT, "Command " << tokens[1] << " failed."); diff --git a/src/Scripting/NasalSys.cxx b/src/Scripting/NasalSys.cxx index 36657a970..89a1e0f96 100644 --- a/src/Scripting/NasalSys.cxx +++ b/src/Scripting/NasalSys.cxx @@ -490,7 +490,7 @@ static naRef f_fgcommand(naContext c, naRef me, int argc, naRef* args) else node = new SGPropertyNode; - return naNum(globals->get_commands()->execute(naStr_data(cmd), node)); + return naNum(globals->get_commands()->execute(naStr_data(cmd), node, nullptr)); } // settimer(func, dt, simtime) extension function. Falls through to @@ -662,7 +662,7 @@ public: _sys->gcRelease(_gcRoot); } - virtual bool operator()(const SGPropertyNode* aNode) + virtual bool operator()(const SGPropertyNode* aNode, SGPropertyNode * root) { _sys->setCmdArg(const_cast(aNode)); naRef args[1]; @@ -1278,7 +1278,8 @@ naRef FGNasalSys::parse(naContext ctx, const char* filename, const char* buf, in bool FGNasalSys::handleCommand( const char* moduleName, const char* fileName, const char* src, - const SGPropertyNode* arg ) + const SGPropertyNode* arg, + SGPropertyNode* root) { naContext ctx = naNewContext(); naRef code = parse(ctx, fileName, src, strlen(src)); @@ -1310,7 +1311,7 @@ bool FGNasalSys::handleCommand( const char* moduleName, return true; } -bool FGNasalSys::handleCommand(const SGPropertyNode* arg) +bool FGNasalSys::handleCommand(const SGPropertyNode * arg, SGPropertyNode * root) { const char* src = arg->getStringValue("script"); const char* moduleName = arg->getStringValue("module"); @@ -1318,7 +1319,8 @@ bool FGNasalSys::handleCommand(const SGPropertyNode* arg) return handleCommand( moduleName, arg->getPath(true).c_str(), src, - arg ); + arg, + root); } // settimer(func, dt, simtime) extension function. The first argument diff --git a/src/Scripting/NasalSys.hxx b/src/Scripting/NasalSys.hxx index 429ed55cb..a25f0d6c5 100644 --- a/src/Scripting/NasalSys.hxx +++ b/src/Scripting/NasalSys.hxx @@ -80,8 +80,9 @@ public: virtual bool handleCommand( const char* moduleName, const char* fileName, const char* src, - const SGPropertyNode* arg = 0 ); - virtual bool handleCommand(const SGPropertyNode* arg); + const SGPropertyNode* arg = 0, + SGPropertyNode* root = 0); + virtual bool handleCommand(const SGPropertyNode* arg, SGPropertyNode *root); bool createModule(const char* moduleName, const char* fileName, const char* src, int len, const SGPropertyNode* cmdarg=0, diff --git a/src/Sound/soundmanager.cxx b/src/Sound/soundmanager.cxx index 925c09910..45a921ac0 100644 --- a/src/Sound/soundmanager.cxx +++ b/src/Sound/soundmanager.cxx @@ -208,7 +208,7 @@ void FGSoundManager::update(double dt) * into a queue. Messages are played sequentially so they do not * overlap. */ -bool FGSoundManager::playAudioSampleCommand(const SGPropertyNode * arg) +bool FGSoundManager::playAudioSampleCommand(const SGPropertyNode * arg, SGPropertyNode * root) { string path = arg->getStringValue("path"); string file = arg->getStringValue("file"); diff --git a/src/Sound/soundmanager.hxx b/src/Sound/soundmanager.hxx index 72324a72f..a200e21df 100644 --- a/src/Sound/soundmanager.hxx +++ b/src/Sound/soundmanager.hxx @@ -53,7 +53,7 @@ public: private: bool stationaryView() const; - bool playAudioSampleCommand(const SGPropertyNode * arg); + bool playAudioSampleCommand(const SGPropertyNode * arg, SGPropertyNode * root); SGSharedPtr _chatterQueue; diff --git a/src/Time/TimeManager.cxx b/src/Time/TimeManager.cxx index 2dabccd00..7a64f101d 100644 --- a/src/Time/TimeManager.cxx +++ b/src/Time/TimeManager.cxx @@ -37,7 +37,7 @@ using std::string; -static bool do_timeofday (const SGPropertyNode * arg) +static bool do_timeofday (const SGPropertyNode * arg, SGPropertyNode * root) { const string &offset_type = arg->getStringValue("timeofday", "noon"); int offset = arg->getIntValue("offset", 0); diff --git a/src/Viewer/GraphicsWindowQt5.cpp b/src/Viewer/GraphicsWindowQt5.cpp index f01ab2086..cc630e0cf 100644 --- a/src/Viewer/GraphicsWindowQt5.cpp +++ b/src/Viewer/GraphicsWindowQt5.cpp @@ -900,7 +900,9 @@ namespace flightgear void initQtWindowingSystem() { -osg::GraphicsContext::setWindowingSystemInterface(Qt5WindowingSystem::getInterface()); +#if OSG_VERSION_LESS_THAN(3,5,2) + osg::GraphicsContext::setWindowingSystemInterface(Qt5WindowingSystem::getInterface()); +#endif } } // of namespace flightgear