1
0
Fork 0

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.
This commit is contained in:
Richard Harrison 2017-07-05 01:23:24 +02:00
parent a70e34dc21
commit 2c8aad12ba
36 changed files with 240 additions and 161 deletions

View file

@ -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"); std::string name = args->getStringValue("name");
if (args->hasChild("load-property")) { if (args->hasChild("load-property")) {
@ -370,9 +370,9 @@ bool FGAIManager::loadScenarioCommand(const SGPropertyNode* args)
return ok; 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); return unloadScenario(name);
} }

View file

@ -97,8 +97,8 @@ private:
void removeDeadItem(FGAIBase* base); void removeDeadItem(FGAIBase* base);
bool loadScenarioCommand(const SGPropertyNode* args); bool loadScenarioCommand(const SGPropertyNode* args, SGPropertyNode* root);
bool unloadScenarioCommand(const SGPropertyNode* args); bool unloadScenarioCommand(const SGPropertyNode* args, SGPropertyNode* root);
bool addObjectCommand(const SGPropertyNode* definition); bool addObjectCommand(const SGPropertyNode* definition);
bool removeObject(const SGPropertyNode* args); bool removeObject(const SGPropertyNode* args);

View file

@ -167,13 +167,13 @@ void FGATCDialogNew::frequencyDisplay(const std::string& ident)
_gui->showDialog(dialog_name); _gui->showDialog(dialog_name);
} }
static bool doFrequencySearch( const SGPropertyNode* ) static bool doFrequencySearch( const SGPropertyNode*, SGPropertyNode * )
{ {
FGATCDialogNew::instance()->frequencySearch(); FGATCDialogNew::instance()->frequencySearch();
return true; return true;
} }
static bool doFrequencyDisplay( const SGPropertyNode* args ) static bool doFrequencyDisplay( const SGPropertyNode* args, SGPropertyNode * root)
{ {
std::string icao = args->getStringValue("icao"); std::string icao = args->getStringValue("icao");
if (icao.empty()) { if (icao.empty()) {

View file

@ -58,7 +58,7 @@ public:
void addEntry(int, const std::string&); void addEntry(int, const std::string&);
void removeEntry(int); void removeEntry(int);
static bool popup( const SGPropertyNode * ) { static bool popup( const SGPropertyNode *, SGPropertyNode * root) {
instance()->PopupDialog(); instance()->PopupDialog();
return true; return true;
} }

View file

@ -589,23 +589,50 @@ void HighPassFilterImplementation::initialize( double initvalue )
_output_1 = 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 ); if (_isnan(input))
double tf = _TfInput.get_value(); 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 double output;
// and div by zero if -tf == dt
double alpha = tf > 0.0 ? 1 / ((tf/dt) + 1) : 1.0; // avoid negative filter times
output = (1 - alpha) * (input - _input_1 + _output_1); // and div by zero if -tf == dt
_input_1 = input;
_output_1 = output;
return output; 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, bool HighPassFilterImplementation::configure( SGPropertyNode& cfg_node,
const std::string& cfg_name, const std::string& cfg_name,
@ -803,6 +830,8 @@ void DigitalFilter::update( bool firstTime, double dt)
} }
double input = _valueInput.get_value() - _referenceInput.get_value(); double input = _valueInput.get_value() - _referenceInput.get_value();
if (_isnan(input))
input = _valueInput.get_value() - _referenceInput.get_value();
double output = _implementation->compute( dt, input ); double output = _implementation->compute( dt, input );
set_output_value( output ); set_output_value( output );

View file

@ -205,7 +205,8 @@ double InputValue::get_value() const
if( _periodical ) { if( _periodical ) {
value = _periodical->normalize( value ); value = _periodical->normalize( value );
} }
if (_isnan(value))
SG_LOG(SG_AUTOPILOT, SG_ALERT, "input is NaN." );
return _abs ? fabs(value) : value; return _abs ? fabs(value) : value;
} }

View file

@ -63,14 +63,14 @@
using namespace flightgear; using namespace flightgear;
using std::string; using std::string;
static bool commandLoadFlightPlan(const SGPropertyNode* arg) static bool commandLoadFlightPlan(const SGPropertyNode* arg, SGPropertyNode *)
{ {
FGRouteMgr* self = (FGRouteMgr*) globals->get_subsystem("route-manager"); FGRouteMgr* self = (FGRouteMgr*) globals->get_subsystem("route-manager");
SGPath path = SGPath::fromUtf8(arg->getStringValue("path")); SGPath path = SGPath::fromUtf8(arg->getStringValue("path"));
return self->loadRoute(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"); FGRouteMgr* self = (FGRouteMgr*) globals->get_subsystem("route-manager");
SGPath path = SGPath::fromUtf8(arg->getStringValue("path")); 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"); FGRouteMgr* self = (FGRouteMgr*) globals->get_subsystem("route-manager");
bool activate = arg->getBoolValue("activate", true); bool activate = arg->getBoolValue("activate", true);
@ -105,14 +105,14 @@ static bool commandActivateFlightPlan(const SGPropertyNode* arg)
return true; return true;
} }
static bool commandClearFlightPlan(const SGPropertyNode*) static bool commandClearFlightPlan(const SGPropertyNode*, SGPropertyNode *)
{ {
FGRouteMgr* self = (FGRouteMgr*) globals->get_subsystem("route-manager"); FGRouteMgr* self = (FGRouteMgr*) globals->get_subsystem("route-manager");
self->clearRoute(); self->clearRoute();
return true; return true;
} }
static bool commandSetActiveWaypt(const SGPropertyNode* arg) static bool commandSetActiveWaypt(const SGPropertyNode* arg, SGPropertyNode *)
{ {
FGRouteMgr* self = (FGRouteMgr*) globals->get_subsystem("route-manager"); FGRouteMgr* self = (FGRouteMgr*) globals->get_subsystem("route-manager");
int index = arg->getIntValue("index"); int index = arg->getIntValue("index");
@ -124,7 +124,7 @@ static bool commandSetActiveWaypt(const SGPropertyNode* arg)
return true; return true;
} }
static bool commandInsertWaypt(const SGPropertyNode* arg) static bool commandInsertWaypt(const SGPropertyNode* arg, SGPropertyNode *)
{ {
FGRouteMgr* self = (FGRouteMgr*) globals->get_subsystem("route-manager"); FGRouteMgr* self = (FGRouteMgr*) globals->get_subsystem("route-manager");
int index = arg->getIntValue("index"); int index = arg->getIntValue("index");
@ -213,7 +213,7 @@ static bool commandInsertWaypt(const SGPropertyNode* arg)
return true; return true;
} }
static bool commandDeleteWaypt(const SGPropertyNode* arg) static bool commandDeleteWaypt(const SGPropertyNode* arg, SGPropertyNode *)
{ {
FGRouteMgr* self = (FGRouteMgr*) globals->get_subsystem("route-manager"); FGRouteMgr* self = (FGRouteMgr*) globals->get_subsystem("route-manager");
int index = arg->getIntValue("index"); int index = arg->getIntValue("index");
@ -1187,7 +1187,7 @@ SGPropertyNode_ptr FGRouteMgr::wayptNodeAtIndex(int index) const
return mirror->getChild("wp", index); 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"); std::string ident = arg->getStringValue("ident");
if (ident.empty()) { if (ident.empty()) {
@ -1209,7 +1209,7 @@ bool FGRouteMgr::commandDefineUserWaypoint(const SGPropertyNode* arg)
return true; return true;
} }
bool FGRouteMgr::commandDeleteUserWaypoint(const SGPropertyNode* arg) bool FGRouteMgr::commandDeleteUserWaypoint(const SGPropertyNode * arg, SGPropertyNode * root)
{ {
std::string ident = arg->getStringValue("ident"); std::string ident = arg->getStringValue("ident");
if (ident.empty()) { if (ident.empty()) {

View file

@ -102,8 +102,8 @@ public:
static const char* subsystemName() { return "route-manager"; } static const char* subsystemName() { return "route-manager"; }
private: private:
bool commandDefineUserWaypoint(const SGPropertyNode* arg); bool commandDefineUserWaypoint(const SGPropertyNode * arg, SGPropertyNode * root);
bool commandDeleteUserWaypoint(const SGPropertyNode* arg); bool commandDeleteUserWaypoint(const SGPropertyNode * arg, SGPropertyNode * root);
flightgear::FlightPlanRef _plan; flightgear::FlightPlanRef _plan;

View file

@ -346,7 +346,7 @@ bool FGClouds::get_3dClouds() const
* (Various) - cloud definition properties. See README.3DClouds * (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 l = arg->getIntValue("layer", 0);
int index = arg->getIntValue("index", 0); int index = arg->getIntValue("index", 0);
@ -381,7 +381,7 @@ bool FGClouds::get_3dClouds() const
* index - the cloud index * 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 l = arg->getIntValue("layer", 0);
int i = arg->getIntValue("index", 0); int i = arg->getIntValue("index", 0);
@ -400,7 +400,7 @@ bool FGClouds::get_3dClouds() const
* lon/lat/alt - the position for the cloud * 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 l = arg->getIntValue("layer", 0);
int i = arg->getIntValue("index", 0); int i = arg->getIntValue("index", 0);

View file

@ -42,9 +42,9 @@ private:
bool clouds_3d_enabled; bool clouds_3d_enabled;
int index; int index;
bool add3DCloud(const SGPropertyNode *arg); bool add3DCloud(const SGPropertyNode *arg, SGPropertyNode * root);
bool delete3DCloud(const SGPropertyNode *arg); bool delete3DCloud(const SGPropertyNode *arg, SGPropertyNode * root);
bool move3DCloud(const SGPropertyNode *arg); bool move3DCloud(const SGPropertyNode *arg, SGPropertyNode * root);
public: public:
FGClouds(); FGClouds();

View file

@ -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"); SGSubsystemGroup* envMgr = (SGSubsystemGroup*) globals->get_subsystem("environment");
if (!envMgr) { if (!envMgr) {
@ -212,7 +212,7 @@ static bool commandRequestMetar(const SGPropertyNode* arg)
return true; return true;
} }
static bool commandClearMetar(const SGPropertyNode* arg) static bool commandClearMetar(const SGPropertyNode * arg, SGPropertyNode * root)
{ {
SGSubsystemGroup* envMgr = (SGSubsystemGroup*) globals->get_subsystem("environment"); SGSubsystemGroup* envMgr = (SGSubsystemGroup*) globals->get_subsystem("environment");
if (!envMgr) { if (!envMgr) {

View file

@ -33,7 +33,7 @@ using std::map;
#if defined(TR_HIRES_SNAP) #if defined(TR_HIRES_SNAP)
extern void dumpHiResSnapShot (); extern void dumpHiResSnapShot ();
static bool static bool
do_hires_snapshot_dialog (const SGPropertyNode * arg) do_hires_snapshot_dialog (const SGPropertyNode * arg, SGPropertyNode * root)
{ {
dumpHiResSnapShot(); dumpHiResSnapShot();
return true; return true;

View file

@ -117,7 +117,7 @@ MessageBoxResult modalMessageBox(const std::string& caption,
args->setStringValue("caption", caption); args->setStringValue("caption", caption);
args->setStringValue("message", msg); args->setStringValue("message", msg);
args->setStringValue("more", moreText); 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? // how to make it modal?

View file

@ -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 // JMT 2013 - I would prefer this was a seperate 'warp' command, but
// historically set-cursor has done both. // historically set-cursor has done both.

View file

@ -57,7 +57,7 @@ public:
protected: protected:
FGMouseCursor(); FGMouseCursor();
bool setCursorCommand(const SGPropertyNode* arg); bool setCursorCommand(const SGPropertyNode* arg, SGPropertyNode*);
unsigned int mAutoHideTimeMsec; unsigned int mAutoHideTimeMsec;
}; };

View file

@ -197,9 +197,9 @@ void syncPausePopupState()
args->setStringValue("id", "sim-pause"); args->setStringValue("id", "sim-pause");
if (paused && fgGetBool("/sim/view-name-popup")) { if (paused && fgGetBool("/sim/view-name-popup")) {
args->setStringValue("label", "Simulation is paused"); args->setStringValue("label", "Simulation is paused");
globals->get_commands()->execute("show-message", args); globals->get_commands()->execute("show-message", args, nullptr);
} else { } else {
globals->get_commands()->execute("clear-message", args); globals->get_commands()->execute("clear-message", args, nullptr);
} }
} }

View file

@ -214,7 +214,7 @@ void FGJoystickInput::postinit()
unsigned int j; unsigned int j;
for (j = 0; j < nasal.size(); j++) { for (j = 0; j < nasal.size(); j++) {
nasal[j]->setStringValue("module", module.c_str()); nasal[j]->setStringValue("module", module.c_str());
nasalsys->handleCommand(nasal[j]); nasalsys->handleCommand(nasal[j],nullptr);
} }
// //

View file

@ -112,7 +112,7 @@ void FGKeyboardInput::postinit()
PropertyList nasal = key_nodes->getChildren("nasal"); PropertyList nasal = key_nodes->getChildren("nasal");
for (unsigned int j = 0; j < nasal.size(); j++) { for (unsigned int j = 0; j < nasal.size(); j++) {
nasal[j]->setStringValue("module", module.c_str()); nasal[j]->setStringValue("module", module.c_str());
nasalsys->handleCommand(nasal[j]); nasalsys->handleCommand(nasal[j], nullptr);
} }
PropertyList keys = key_nodes->getChildren("key"); PropertyList keys = key_nodes->getChildren("key");

View file

@ -263,7 +263,7 @@ public:
FGMouseCursor::instance()->setCursor(cur); FGMouseCursor::instance()->setCursor(cur);
if (!didPick) { if (!didPick) {
SGPropertyNode_ptr args(new SGPropertyNode); 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; d->tooltipTimeoutDone = true;
SGPropertyNode_ptr arg(new SGPropertyNode); SGPropertyNode_ptr arg(new SGPropertyNode);
globals->get_commands()->execute("tooltip-timeout", arg); globals->get_commands()->execute("tooltip-timeout", arg, nullptr);
} }
if ( d->hideCursor ) { if ( d->hideCursor ) {
@ -610,7 +610,7 @@ void FGMouseInput::doMouseClick (int b, int updown, int x, int y, bool mainWindo
if (d->clickTriggersTooltip) { if (d->clickTriggersTooltip) {
SGPropertyNode_ptr args(new SGPropertyNode); SGPropertyNode_ptr args(new SGPropertyNode);
args->setStringValue("reason", "click"); args->setStringValue("reason", "click");
globals->get_commands()->execute("tooltip-timeout", args); globals->get_commands()->execute("tooltip-timeout", args, nullptr);
d->tooltipTimeoutDone = true; d->tooltipTimeoutDone = true;
} }
} else { } else {

View file

@ -55,76 +55,76 @@ using std::string;
// Command callbacks for FlightGear // 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"; //cout << "do_kln89_msg_pressed called!\n";
KLN89* gps = (KLN89*)globals->get_subsystem("kln89"); KLN89* gps = (KLN89*)globals->get_subsystem("kln89");
gps->MsgPressed(); gps->MsgPressed();
return(true); 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"; //cout << "do_kln89_obs_pressed called!\n";
KLN89* gps = (KLN89*)globals->get_subsystem("kln89"); KLN89* gps = (KLN89*)globals->get_subsystem("kln89");
gps->OBSPressed(); gps->OBSPressed();
return(true); 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"; //cout << "do_kln89_alt_pressed called!\n";
KLN89* gps = (KLN89*)globals->get_subsystem("kln89"); KLN89* gps = (KLN89*)globals->get_subsystem("kln89");
gps->AltPressed(); gps->AltPressed();
return(true); 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"); KLN89* gps = (KLN89*)globals->get_subsystem("kln89");
gps->NrstPressed(); gps->NrstPressed();
return(true); 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"); KLN89* gps = (KLN89*)globals->get_subsystem("kln89");
gps->DtoPressed(); gps->DtoPressed();
return(true); 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"); KLN89* gps = (KLN89*)globals->get_subsystem("kln89");
gps->ClrPressed(); gps->ClrPressed();
return(true); 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"); KLN89* gps = (KLN89*)globals->get_subsystem("kln89");
gps->EntPressed(); gps->EntPressed();
return(true); 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"); KLN89* gps = (KLN89*)globals->get_subsystem("kln89");
gps->CrsrPressed(); gps->CrsrPressed();
return(true); 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"); KLN89* gps = (KLN89*)globals->get_subsystem("kln89");
gps->Knob1Left1(); gps->Knob1Left1();
return(true); 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"); KLN89* gps = (KLN89*)globals->get_subsystem("kln89");
gps->Knob1Right1(); gps->Knob1Right1();
return(true); 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"); KLN89* gps = (KLN89*)globals->get_subsystem("kln89");
gps->Knob2Left1(); gps->Knob2Left1();
return(true); 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"); KLN89* gps = (KLN89*)globals->get_subsystem("kln89");
gps->Knob2Right1(); gps->Knob2Right1();
return(true); return(true);

View file

@ -62,14 +62,36 @@ using std::ofstream;
static inline SGPropertyNode * 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); return fgGetNode(arg->getStringValue("property[0]", "/null"), true);
} }
static inline SGPropertyNode * 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); return fgGetNode(arg->getStringValue("property[1]", "/null"), true);
} }
@ -163,7 +185,7 @@ compare_values (SGPropertyNode * value1, SGPropertyNode * value2)
* Built-in command: do nothing. * Built-in command: do nothing.
*/ */
static bool static bool
do_null (const SGPropertyNode * arg) do_null (const SGPropertyNode * arg, SGPropertyNode * root)
{ {
return true; return true;
} }
@ -172,16 +194,16 @@ do_null (const SGPropertyNode * arg)
* Built-in command: run a Nasal script. * Built-in command: run a Nasal script.
*/ */
static bool 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 * Built-in command: replay the FDR buffer
*/ */
static bool static bool
do_replay (const SGPropertyNode * arg) do_replay (const SGPropertyNode * arg, SGPropertyNode * root)
{ {
FGReplay *r = (FGReplay *)(globals->get_subsystem( "replay" )); FGReplay *r = (FGReplay *)(globals->get_subsystem( "replay" ));
return r->start(); return r->start();
@ -191,7 +213,7 @@ do_replay (const SGPropertyNode * arg)
* Built-in command: pause/unpause the sim * Built-in command: pause/unpause the sim
*/ */
static bool static bool
do_pause (const SGPropertyNode * arg) do_pause (const SGPropertyNode * arg, SGPropertyNode * root)
{ {
bool forcePause = arg->getBoolValue("force-pause", false ); bool forcePause = arg->getBoolValue("force-pause", false );
bool forcePlay = arg->getBoolValue("force-play", 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)) if (paused && (fgGetInt("/sim/freeze/replay-state",0)>0))
{ {
do_replay(NULL); do_replay(NULL, nullptr);
} }
else else
{ {
@ -222,7 +244,7 @@ do_pause (const SGPropertyNode * arg)
* directory). Defaults to "fgfs.sav" * directory). Defaults to "fgfs.sav"
*/ */
static bool static bool
do_load (const SGPropertyNode * arg) do_load (const SGPropertyNode * arg, SGPropertyNode * root)
{ {
SGPath file(arg->getStringValue("file", "fgfs.sav")); SGPath file(arg->getStringValue("file", "fgfs.sav"));
@ -255,7 +277,7 @@ do_load (const SGPropertyNode * arg)
* current directory). Defaults to "fgfs.sav". * current directory). Defaults to "fgfs.sav".
*/ */
static bool static bool
do_save (const SGPropertyNode * arg) do_save (const SGPropertyNode * arg, SGPropertyNode * root)
{ {
SGPath file(arg->getStringValue("file", "fgfs.sav")); SGPath file(arg->getStringValue("file", "fgfs.sav"));
@ -287,7 +309,7 @@ do_save (const SGPropertyNode * arg)
* *
*/ */
static bool static bool
do_save_tape (const SGPropertyNode * arg) do_save_tape (const SGPropertyNode * arg, SGPropertyNode * root)
{ {
FGReplay* replay = (FGReplay*) globals->get_subsystem("replay"); FGReplay* replay = (FGReplay*) globals->get_subsystem("replay");
replay->saveTape(arg); replay->saveTape(arg);
@ -299,7 +321,7 @@ do_save_tape (const SGPropertyNode * arg)
* *
*/ */
static bool static bool
do_load_tape (const SGPropertyNode * arg) do_load_tape (const SGPropertyNode * arg, SGPropertyNode * root)
{ {
FGReplay* replay = (FGReplay*) globals->get_subsystem("replay"); FGReplay* replay = (FGReplay*) globals->get_subsystem("replay");
replay->loadTape(arg); replay->loadTape(arg);
@ -333,7 +355,7 @@ do_view_prev(bool do_it)
* Built-in command: cycle view. * Built-in command: cycle view.
*/ */
static bool 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_current_view()->setHeadingOffset_deg(0.0);
globals->get_viewmgr()->next_view(); globals->get_viewmgr()->next_view();
@ -346,9 +368,9 @@ do_view_cycle (const SGPropertyNode * arg)
* property: The name of the property to toggle. * property: The name of the property to toggle.
*/ */
static bool 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()); return prop->setBoolValue(!prop->getBoolValue());
} }
@ -361,16 +383,16 @@ do_property_toggle (const SGPropertyNode * arg)
* property[1]: the property to copy from. * property[1]: the property to copy from.
*/ */
static bool 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"); const SGPropertyNode * value = arg->getNode("value");
if (value != 0) if (value != 0)
return prop->setUnspecifiedValue(value->getStringValue()); return prop->setUnspecifiedValue(value->getStringValue());
else else
{ {
const SGPropertyNode * prop2 = get_prop2(arg); const SGPropertyNode * prop2 = get_prop2(arg,root);
if (prop2) if (prop2)
return prop->setUnspecifiedValue(prop2->getStringValue()); return prop->setUnspecifiedValue(prop2->getStringValue());
else else
@ -400,9 +422,9 @@ do_property_assign (const SGPropertyNode * arg)
* false). * false).
*/ */
static bool 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; double amount = 0;
if (arg->hasValue("step")) if (arg->hasValue("step"))
@ -438,9 +460,9 @@ do_property_adjust (const SGPropertyNode * arg)
* false). * false).
*/ */
static bool 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 factor = arg->getDoubleValue("factor", 1);
double unmodifiable, modifiable; double unmodifiable, modifiable;
@ -462,10 +484,10 @@ do_property_multiply (const SGPropertyNode * arg)
* property[1]: the name of the second property. * property[1]: the name of the second property.
*/ */
static bool static bool
do_property_swap (const SGPropertyNode * arg) do_property_swap (const SGPropertyNode * arg, SGPropertyNode * root)
{ {
SGPropertyNode * prop1 = get_prop(arg); SGPropertyNode * prop1 = get_prop(arg,root);
SGPropertyNode * prop2 = get_prop2(arg); SGPropertyNode * prop2 = get_prop2(arg,root);
// FIXME: inefficient // FIXME: inefficient
const string & tmp = prop1->getStringValue(); 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). * factor: the factor to multiply by (use negative to reverse).
*/ */
static bool 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 setting = arg->getDoubleValue("setting");
double offset = arg->getDoubleValue("offset", 0.0); double offset = arg->getDoubleValue("offset", 0.0);
double factor = arg->getDoubleValue("factor", 1.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. * value[*]: the list of values to cycle through.
*/ */
static bool 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<SGPropertyNode_ptr> values = arg->getChildren("value"); std::vector<SGPropertyNode_ptr> values = arg->getChildren("value");
bool wrap = arg->getBoolValue("wrap", true); bool wrap = arg->getBoolValue("wrap", true);
@ -576,9 +598,9 @@ do_property_cycle (const SGPropertyNode * arg)
* max: the maximum allowed value. * max: the maximum allowed value.
*/ */
static bool 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 min = arg->getDoubleValue("min", DBL_MIN);
double max = arg->getDoubleValue("max", DBL_MAX); double max = arg->getDoubleValue("max", DBL_MAX);
prop->setDoubleValue(sg_random() * (max - min) + min); prop->setDoubleValue(sg_random() * (max - min) + min);
@ -604,9 +626,9 @@ do_property_randomize (const SGPropertyNode * arg)
* the property value at the given speed. * the property value at the given speed.
*/ */
static bool 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 ) if( !prop )
return false; return false;
@ -675,7 +697,7 @@ do_property_interpolate (const SGPropertyNode * arg)
* current contents of the /logger tree. * current contents of the /logger tree.
*/ */
static bool 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"); FGLogger *log = (FGLogger *)globals->get_subsystem("logger");
log->reinit(); log->reinit();
@ -686,7 +708,7 @@ do_data_logging_commit (const SGPropertyNode * arg)
* Built-in command: set log level (0 ... 7) * Built-in command: set log level (0 ... 7)
*/ */
static bool static bool
do_log_level (const SGPropertyNode * arg) do_log_level (const SGPropertyNode * arg, SGPropertyNode * root)
{ {
sglog().setLogLevels( SG_ALL, (sgDebugPriority)arg->getIntValue() ); sglog().setLogLevels( SG_ALL, (sgDebugPriority)arg->getIntValue() );
@ -706,7 +728,7 @@ do_log_level (const SGPropertyNode * arg)
*/ */
static bool 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")); SGPath file(arg->getStringValue("filename"));
if (file.isNull()) if (file.isNull())
@ -760,7 +782,7 @@ do_load_xml_to_proptree(const SGPropertyNode * arg)
} }
static bool static bool
do_load_xml_from_url(const SGPropertyNode * arg) do_load_xml_from_url(const SGPropertyNode * arg, SGPropertyNode * root)
{ {
FGHTTPClient* http = static_cast<FGHTTPClient*>(globals->get_subsystem("http")); FGHTTPClient* http = static_cast<FGHTTPClient*>(globals->get_subsystem("http"));
if (!http) { if (!http) {
@ -810,7 +832,7 @@ do_load_xml_from_url(const SGPropertyNode * arg)
*/ */
static bool 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")); SGPath file(arg->getStringValue("filename"));
if (file.isNull()) if (file.isNull())
@ -861,7 +883,7 @@ no_profiling_support()
#endif #endif
static bool static bool
do_profiler_start(const SGPropertyNode *arg) do_profiler_start(const SGPropertyNode *arg, SGPropertyNode *root)
{ {
#if FG_HAVE_GPERFTOOLS #if FG_HAVE_GPERFTOOLS
const char *filename = arg->getStringValue("filename", "fgfs.profile"); const char *filename = arg->getStringValue("filename", "fgfs.profile");
@ -874,7 +896,7 @@ do_profiler_start(const SGPropertyNode *arg)
} }
static bool static bool
do_profiler_stop(const SGPropertyNode *arg) do_profiler_stop(const SGPropertyNode *arg, SGPropertyNode *root)
{ {
#if FG_HAVE_GPERFTOOLS #if FG_HAVE_GPERFTOOLS
ProfilerStop(); ProfilerStop();

View file

@ -71,7 +71,7 @@
* status: the exit status to return to the operating system (defaults to 0) * status: the exit status to return to the operating system (defaults to 0)
*/ */
static bool static bool
do_exit (const SGPropertyNode * arg) do_exit (const SGPropertyNode * arg, SGPropertyNode * root)
{ {
SG_LOG(SG_INPUT, SG_INFO, "Program exit requested."); SG_LOG(SG_INPUT, SG_INFO, "Program exit requested.");
fgSetBool("/sim/signals/exit", true); fgSetBool("/sim/signals/exit", true);
@ -85,7 +85,7 @@ do_exit (const SGPropertyNode * arg)
* Reset FlightGear (Shift-Escape or Menu->File->Reset) * Reset FlightGear (Shift-Escape or Menu->File->Reset)
*/ */
static bool static bool
do_reset (const SGPropertyNode * arg) do_reset (const SGPropertyNode * arg, SGPropertyNode * root)
{ {
fgResetIdleState(); fgResetIdleState();
return true; return true;
@ -96,7 +96,7 @@ do_reset (const SGPropertyNode * arg)
* Change aircraft * Change aircraft
*/ */
static bool static bool
do_switch_aircraft (const SGPropertyNode * arg) do_switch_aircraft (const SGPropertyNode * arg, SGPropertyNode * root)
{ {
fgSetString("/sim/aircraft", arg->getStringValue("aircraft")); fgSetString("/sim/aircraft", arg->getStringValue("aircraft"));
// start a reset // start a reset
@ -107,7 +107,7 @@ do_switch_aircraft (const SGPropertyNode * arg)
/** /**
*/ */
static bool static bool
do_reposition (const SGPropertyNode * arg) do_reposition (const SGPropertyNode * arg, SGPropertyNode * root)
{ {
fgStartReposition(); fgStartReposition();
return true; return true;
@ -121,7 +121,7 @@ do_reposition (const SGPropertyNode * arg)
* and if that's unspecified, to "Panels/Default/default.xml". * and if that's unspecified, to "Panels/Default/default.xml".
*/ */
static bool static bool
do_panel_load (const SGPropertyNode * arg) do_panel_load (const SGPropertyNode * arg, SGPropertyNode * root)
{ {
string panel_path = arg->getStringValue("path"); string panel_path = arg->getStringValue("path");
if (!panel_path.empty()) { if (!panel_path.empty()) {
@ -139,7 +139,7 @@ do_panel_load (const SGPropertyNode * arg)
* to FG_ROOT). Defaults to "preferences.xml". * to FG_ROOT). Defaults to "preferences.xml".
*/ */
static bool 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' // disabling this command which was formerly used to reload 'preferences.xml'
// reloading the defaults doesn't make sense (better to reset the simulator), // reloading the defaults doesn't make sense (better to reset the simulator),
@ -154,7 +154,7 @@ do_preferences_load (const SGPropertyNode * arg)
* No parameters. * No parameters.
*/ */
static bool static bool
do_toggle_fullscreen(const SGPropertyNode *arg) do_toggle_fullscreen(const SGPropertyNode*, SGPropertyNode*)
{ {
fgOSFullScreen(); fgOSFullScreen();
return true; return true;
@ -164,27 +164,27 @@ do_toggle_fullscreen(const SGPropertyNode *arg)
* Built-in command: capture screen. * Built-in command: capture screen.
*/ */
static bool static bool
do_screen_capture (const SGPropertyNode * arg) do_screen_capture(const SGPropertyNode*, SGPropertyNode*)
{ {
return fgDumpSnapShot(); return fgDumpSnapShot();
} }
static bool static bool
do_reload_shaders (const SGPropertyNode*) do_reload_shaders (const SGPropertyNode*, SGPropertyNode*)
{ {
simgear::reload_shaders(); simgear::reload_shaders();
return true; return true;
} }
static bool static bool
do_dump_scene_graph (const SGPropertyNode*) do_dump_scene_graph (const SGPropertyNode*, SGPropertyNode*)
{ {
fgDumpSceneGraph(); fgDumpSceneGraph();
return true; return true;
} }
static bool static bool
do_dump_terrain_branch (const SGPropertyNode*) do_dump_terrain_branch (const SGPropertyNode*, SGPropertyNode*)
{ {
fgDumpTerrainBranch(); fgDumpTerrainBranch();
@ -201,7 +201,7 @@ do_dump_terrain_branch (const SGPropertyNode*)
} }
static bool static bool
do_print_visible_scene_info(const SGPropertyNode*) do_print_visible_scene_info(const SGPropertyNode*, SGPropertyNode*)
{ {
fgPrintVisibleSceneInfoCommand(); fgPrintVisibleSceneInfoCommand();
return true; return true;
@ -211,7 +211,7 @@ do_print_visible_scene_info(const SGPropertyNode*)
* Built-in command: hires capture screen. * Built-in command: hires capture screen.
*/ */
static bool static bool
do_hires_screen_capture (const SGPropertyNode * arg) do_hires_screen_capture (const SGPropertyNode * arg, SGPropertyNode * root)
{ {
fgHiResDump(); fgHiResDump();
return true; return true;
@ -222,7 +222,7 @@ do_hires_screen_capture (const SGPropertyNode * arg)
* Reload the tile cache. * Reload the tile cache.
*/ */
static bool 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"); SGPropertyNode *master_freeze = fgGetNode("/sim/freeze/master");
bool freeze = master_freeze->getBoolValue(); bool freeze = master_freeze->getBoolValue();
@ -243,7 +243,7 @@ do_tile_cache_reload (const SGPropertyNode * arg)
* Reload the materials definition * Reload the materials definition
*/ */
static bool static bool
do_materials_reload (const SGPropertyNode * arg) do_materials_reload (const SGPropertyNode * arg, SGPropertyNode * root)
{ {
SG_LOG(SG_INPUT, SG_INFO, "Reloading Materials"); SG_LOG(SG_INPUT, SG_INFO, "Reloading Materials");
SGMaterialLib* new_matlib = new SGMaterialLib; 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. * name: the name of the GUI dialog for future reference.
*/ */
static bool static bool
do_dialog_new (const SGPropertyNode * arg) do_dialog_new (const SGPropertyNode * arg, SGPropertyNode * root)
{ {
NewGUI * gui = (NewGUI *)globals->get_subsystem("gui"); NewGUI * gui = (NewGUI *)globals->get_subsystem("gui");
if (!gui) { if (!gui) {
@ -298,7 +298,7 @@ do_dialog_new (const SGPropertyNode * arg)
* dialog-name: the name of the GUI dialog to display. * dialog-name: the name of the GUI dialog to display.
*/ */
static bool static bool
do_dialog_show (const SGPropertyNode * arg) do_dialog_show (const SGPropertyNode * arg, SGPropertyNode * root)
{ {
NewGUI * gui = (NewGUI *)globals->get_subsystem("gui"); NewGUI * gui = (NewGUI *)globals->get_subsystem("gui");
gui->showDialog(arg->getStringValue("dialog-name")); 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. * Built-in Command: Hide the active XML-configured dialog.
*/ */
static bool static bool
do_dialog_close (const SGPropertyNode * arg) do_dialog_close (const SGPropertyNode * arg, SGPropertyNode * root)
{ {
NewGUI * gui = (NewGUI *)globals->get_subsystem("gui"); NewGUI * gui = (NewGUI *)globals->get_subsystem("gui");
if(arg->hasValue("dialog-name")) 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). * object-name: The name of the GUI object(s) (all GUI objects if omitted).
*/ */
static bool static bool
do_dialog_update (const SGPropertyNode * arg) do_dialog_update (const SGPropertyNode * arg, SGPropertyNode * root)
{ {
NewGUI * gui = (NewGUI *)globals->get_subsystem("gui"); NewGUI * gui = (NewGUI *)globals->get_subsystem("gui");
FGDialog * dialog; FGDialog * dialog;
@ -343,7 +343,7 @@ do_dialog_update (const SGPropertyNode * arg)
} }
static bool static bool
do_open_browser (const SGPropertyNode * arg) do_open_browser (const SGPropertyNode * arg, SGPropertyNode * root)
{ {
string path; string path;
if (arg->hasValue("path")) if (arg->hasValue("path"))
@ -358,7 +358,7 @@ do_open_browser (const SGPropertyNode * arg)
} }
static bool static bool
do_open_launcher(const SGPropertyNode *) do_open_launcher(const SGPropertyNode*, SGPropertyNode*)
{ {
#if defined(HAVE_QT) #if defined(HAVE_QT)
bool ok = flightgear::runInAppLauncherDialog(); 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). * object-name: The name of the GUI object(s) (all GUI objects if omitted).
*/ */
static bool static bool
do_dialog_apply (const SGPropertyNode * arg) do_dialog_apply (const SGPropertyNode * arg, SGPropertyNode * root)
{ {
NewGUI * gui = (NewGUI *)globals->get_subsystem("gui"); NewGUI * gui = (NewGUI *)globals->get_subsystem("gui");
FGDialog * dialog; FGDialog * dialog;
@ -401,7 +401,7 @@ do_dialog_apply (const SGPropertyNode * arg)
* unlike reinit(). * unlike reinit().
*/ */
static bool static bool
do_gui_redraw (const SGPropertyNode * arg) do_gui_redraw (const SGPropertyNode * arg, SGPropertyNode * root)
{ {
NewGUI * gui = (NewGUI *)globals->get_subsystem("gui"); NewGUI * gui = (NewGUI *)globals->get_subsystem("gui");
gui->redraw(); gui->redraw();
@ -414,7 +414,7 @@ do_gui_redraw (const SGPropertyNode * arg)
* is returned in property "property". * is returned in property "property".
*/ */
static bool static bool
do_add_model (const SGPropertyNode * arg) do_add_model (const SGPropertyNode * arg, SGPropertyNode * root)
{ {
SGPropertyNode * model = fgGetNode("models", true); SGPropertyNode * model = fgGetNode("models", true);
int i; int i;
@ -434,7 +434,7 @@ do_add_model (const SGPropertyNode * arg)
* Built-in command: commit presets (read from in /sim/presets/) * Built-in command: commit presets (read from in /sim/presets/)
*/ */
static bool static bool
do_presets_commit (const SGPropertyNode * arg) do_presets_commit (const SGPropertyNode * arg, SGPropertyNode * root)
{ {
if (fgGetBool("/sim/initialized", false)) { if (fgGetBool("/sim/initialized", false)) {
fgResetIdleState(); fgResetIdleState();
@ -449,7 +449,7 @@ do_presets_commit (const SGPropertyNode * arg)
} }
static bool static bool
do_press_cockpit_button (const SGPropertyNode *arg) do_press_cockpit_button (const SGPropertyNode * arg, SGPropertyNode * root)
{ {
const char *prefix = arg->getStringValue("prefix"); const char *prefix = arg->getStringValue("prefix");
@ -471,7 +471,7 @@ do_press_cockpit_button (const SGPropertyNode *arg)
} }
static bool static bool
do_release_cockpit_button (const SGPropertyNode *arg) do_release_cockpit_button (const SGPropertyNode * arg, SGPropertyNode * root)
{ {
const char *prefix = arg->getStringValue("prefix"); const char *prefix = arg->getStringValue("prefix");

View file

@ -188,18 +188,18 @@ static SGSubsystem* getSubsystem(const SGPropertyNode* arg, bool create)
} }
static bool static bool
do_check_subsystem_running(const SGPropertyNode* arg) do_check_subsystem_running(const SGPropertyNode * arg, SGPropertyNode * root)
{ {
return getSubsystem(arg, false) != 0; return getSubsystem(arg, false) != 0;
} }
static bool static bool
do_add_subsystem (const SGPropertyNode * arg) do_add_subsystem (const SGPropertyNode * arg, SGPropertyNode * root)
{ {
return getSubsystem(arg, true) != 0; 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"); 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. * none is specified, reinitialize all of them.
*/ */
static bool static bool
do_reinit (const SGPropertyNode * arg) do_reinit (const SGPropertyNode * arg, SGPropertyNode * root)
{ {
bool result = true; bool result = true;
@ -258,7 +258,7 @@ do_reinit (const SGPropertyNode * arg)
* subsystem[*] - the name(s) of the subsystem(s) to suspend. * subsystem[*] - the name(s) of the subsystem(s) to suspend.
*/ */
static bool static bool
do_suspend (const SGPropertyNode * arg) do_suspend (const SGPropertyNode * arg, SGPropertyNode * root)
{ {
bool result = true; bool result = true;
@ -282,7 +282,7 @@ do_suspend (const SGPropertyNode * arg)
* subsystem[*] - the name(s) of the subsystem(s) to suspend. * subsystem[*] - the name(s) of the subsystem(s) to suspend.
*/ */
static bool static bool
do_resume (const SGPropertyNode * arg) do_resume (const SGPropertyNode * arg, SGPropertyNode * root)
{ {
bool result = true; bool result = true;

View file

@ -430,7 +430,7 @@ osg::Node* FGPanelNode::load(SGPropertyNode *n)
* y-pos: the y position of the mouse click. * y-pos: the y position of the mouse click.
*/ */
bool bool
FGPanelNode::panelMouseClickCommand(const SGPropertyNode * arg) FGPanelNode::panelMouseClickCommand(const SGPropertyNode * arg, SGPropertyNode * root)
{ {
return _panel->doMouseAction(arg->getIntValue("button"), return _panel->doMouseAction(arg->getIntValue("button"),
arg->getBoolValue("is-down") ? PU_DOWN : PU_UP, arg->getBoolValue("is-down") ? PU_DOWN : PU_UP,

View file

@ -64,7 +64,7 @@ private:
void commonInit(); void commonInit();
void initWithPanel(); void initWithPanel();
bool panelMouseClickCommand(const SGPropertyNode * arg); bool panelMouseClickCommand(const SGPropertyNode * arg, SGPropertyNode * root);
const bool _is2d; const bool _is2d;
SGSharedPtr<FGPanel> _panel; SGSharedPtr<FGPanel> _panel;

View file

@ -57,8 +57,7 @@
using namespace std; using namespace std;
#define MAX_PACKET_SIZE 1200 #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, * 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 * 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. * 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) * 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_1 = 11000;
const int BOOLARRAY_BASE_2 = BOOLARRAY_BASE_1 + BOOLARRAY_BLOCKSIZE; const int BOOLARRAY_BASE_2 = BOOLARRAY_BASE_1 + BOOLARRAY_BLOCKSIZE;
const int BOOLARRAY_BASE_3 = BOOLARRAY_BASE_2 + BOOLARRAY_BLOCKSIZE; const int BOOLARRAY_BASE_3 = BOOLARRAY_BASE_2 + BOOLARRAY_BLOCKSIZE;
@ -718,7 +731,7 @@ private:
// txport: outgoing port number (default: 5000) // txport: outgoing port number (default: 5000)
// rxport: incoming 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"); FGMultiplayMgr * self = (FGMultiplayMgr*) globals->get_subsystem("mp");
if (!self) { if (!self) {
SG_LOG(SG_NETWORK, SG_WARN, "Multiplayer subsystem not available."); SG_LOG(SG_NETWORK, SG_WARN, "Multiplayer subsystem not available.");
@ -753,7 +766,7 @@ static bool do_multiplayer_connect(const SGPropertyNode * arg) {
// disconnect args: // disconnect args:
// none // 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"); FGMultiplayMgr * self = (FGMultiplayMgr*) globals->get_subsystem("mp");
if (!self) { if (!self) {
SG_LOG(SG_NETWORK, SG_WARN, "Multiplayer subsystem not available."); SG_LOG(SG_NETWORK, SG_WARN, "Multiplayer subsystem not available.");
@ -774,7 +787,7 @@ static bool do_multiplayer_disconnect(const SGPropertyNode * arg) {
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
static bool static bool
do_multiplayer_refreshserverlist (const SGPropertyNode * arg) do_multiplayer_refreshserverlist (const SGPropertyNode * arg, SGPropertyNode * root)
{ {
using namespace simgear; using namespace simgear;
@ -844,6 +857,7 @@ FGMultiplayMgr::FGMultiplayMgr()
pXmitLen = fgGetNode("/sim/multiplay/last-xmit-packet-len", true); pXmitLen = fgGetNode("/sim/multiplay/last-xmit-packet-len", true);
pProtocolVersion = fgGetNode("/sim/multiplay/protocol-version", true); pProtocolVersion = fgGetNode("/sim/multiplay/protocol-version", true);
pMultiPlayDebugLevel = fgGetNode("/sim/multiplay/debug-level", 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 = fgGetNode("/sim/multiplay/visibility-range-nm", true);
pMultiPlayRange->setIntValue(100); pMultiPlayRange->setIntValue(100);
} // FGMultiplayMgr::FGMultiplayMgr() } // FGMultiplayMgr::FGMultiplayMgr()
@ -1106,7 +1120,7 @@ void
FGMultiplayMgr::SendMyPosition(const FGExternalMotionData& motionInfo) FGMultiplayMgr::SendMyPosition(const FGExternalMotionData& motionInfo)
{ {
int protocolToUse = getProtocolToUse(); int protocolToUse = getProtocolToUse();
int transmitOnlyGenerics = pMultiPlayTransmitOnlyGenerics->getIntValue();
if ((! mInitialised) || (! mHaveServer)) if ((! mInitialised) || (! mHaveServer))
return; return;
@ -1214,7 +1228,14 @@ FGMultiplayMgr::SendMyPosition(const FGExternalMotionData& motionInfo)
++it; ++it;
continue; 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 * 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 * compatability with older clients; however this will only work in the future or with support from fgms

View file

@ -115,6 +115,7 @@ private:
SGPropertyNode *pXmitLen; SGPropertyNode *pXmitLen;
SGPropertyNode *pMultiPlayDebugLevel; SGPropertyNode *pMultiPlayDebugLevel;
SGPropertyNode *pMultiPlayRange; SGPropertyNode *pMultiPlayRange;
SGPropertyNode *pMultiPlayTransmitOnlyGenerics;
typedef std::map<unsigned int, const struct IdPropertyList*> PropertyDefinitionMap; typedef std::map<unsigned int, const struct IdPropertyList*> PropertyDefinitionMap;
PropertyDefinitionMap mPropertyDefinition; PropertyDefinitionMap mPropertyDefinition;

View file

@ -114,7 +114,7 @@ static void handleExecCommand(cJSON* json)
SGPropertyNode_ptr arg(new SGPropertyNode); SGPropertyNode_ptr arg(new SGPropertyNode);
JSON::addChildrenToProp( json, arg ); JSON::addChildrenToProp( json, arg );
globals->get_commands()->execute(name->valuestring, arg); globals->get_commands()->execute(name->valuestring, arg, nullptr);
} }
PropertyChangeWebsocket::PropertyChangeWebsocket(PropertyChangeObserver * propertyChangeObserver) PropertyChangeWebsocket::PropertyChangeWebsocket(PropertyChangeObserver * propertyChangeObserver)

View file

@ -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) << "'"); SG_LOG( SG_NETWORK, SG_INFO, "RunUriHandler("<< request.Content << "): command='" << command << "', arg='" << JSON::toJsonString(false,args,5) << "'");
cJSON_Delete( json ); 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."; response.Content = "ok.";
return true; return true;
} }

View file

@ -384,7 +384,7 @@ PropsChannel::foundTerminator()
node->setStringValue( tokens[i].c_str() ); node->setStringValue( tokens[i].c_str() );
} }
if ( !globals->get_commands() if ( !globals->get_commands()
->execute( "reinit", &args) ) ->execute( "reinit", &args, nullptr) )
{ {
SG_LOG( SG_NETWORK, SG_ALERT, SG_LOG( SG_NETWORK, SG_ALERT,
"Command " << tokens[1] << " failed."); "Command " << tokens[1] << " failed.");
@ -449,7 +449,7 @@ PropsChannel::foundTerminator()
} }
} }
if ( !globals->get_commands() if ( !globals->get_commands()
->execute(tokens[1].c_str(), &args) ) ->execute(tokens[1].c_str(), &args, nullptr) )
{ {
SG_LOG( SG_NETWORK, SG_ALERT, SG_LOG( SG_NETWORK, SG_ALERT,
"Command " << tokens[1] << " failed."); "Command " << tokens[1] << " failed.");

View file

@ -490,7 +490,7 @@ static naRef f_fgcommand(naContext c, naRef me, int argc, naRef* args)
else else
node = new SGPropertyNode; 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 // settimer(func, dt, simtime) extension function. Falls through to
@ -662,7 +662,7 @@ public:
_sys->gcRelease(_gcRoot); _sys->gcRelease(_gcRoot);
} }
virtual bool operator()(const SGPropertyNode* aNode) virtual bool operator()(const SGPropertyNode* aNode, SGPropertyNode * root)
{ {
_sys->setCmdArg(const_cast<SGPropertyNode*>(aNode)); _sys->setCmdArg(const_cast<SGPropertyNode*>(aNode));
naRef args[1]; 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, bool FGNasalSys::handleCommand( const char* moduleName,
const char* fileName, const char* fileName,
const char* src, const char* src,
const SGPropertyNode* arg ) const SGPropertyNode* arg,
SGPropertyNode* root)
{ {
naContext ctx = naNewContext(); naContext ctx = naNewContext();
naRef code = parse(ctx, fileName, src, strlen(src)); naRef code = parse(ctx, fileName, src, strlen(src));
@ -1310,7 +1311,7 @@ bool FGNasalSys::handleCommand( const char* moduleName,
return true; return true;
} }
bool FGNasalSys::handleCommand(const SGPropertyNode* arg) bool FGNasalSys::handleCommand(const SGPropertyNode * arg, SGPropertyNode * root)
{ {
const char* src = arg->getStringValue("script"); const char* src = arg->getStringValue("script");
const char* moduleName = arg->getStringValue("module"); const char* moduleName = arg->getStringValue("module");
@ -1318,7 +1319,8 @@ bool FGNasalSys::handleCommand(const SGPropertyNode* arg)
return handleCommand( moduleName, return handleCommand( moduleName,
arg->getPath(true).c_str(), arg->getPath(true).c_str(),
src, src,
arg ); arg,
root);
} }
// settimer(func, dt, simtime) extension function. The first argument // settimer(func, dt, simtime) extension function. The first argument

View file

@ -80,8 +80,9 @@ public:
virtual bool handleCommand( const char* moduleName, virtual bool handleCommand( const char* moduleName,
const char* fileName, const char* fileName,
const char* src, const char* src,
const SGPropertyNode* arg = 0 ); const SGPropertyNode* arg = 0,
virtual bool handleCommand(const SGPropertyNode* arg); SGPropertyNode* root = 0);
virtual bool handleCommand(const SGPropertyNode* arg, SGPropertyNode *root);
bool createModule(const char* moduleName, const char* fileName, bool createModule(const char* moduleName, const char* fileName,
const char* src, int len, const SGPropertyNode* cmdarg=0, const char* src, int len, const SGPropertyNode* cmdarg=0,

View file

@ -208,7 +208,7 @@ void FGSoundManager::update(double dt)
* into a queue. Messages are played sequentially so they do not * into a queue. Messages are played sequentially so they do not
* overlap. * overlap.
*/ */
bool FGSoundManager::playAudioSampleCommand(const SGPropertyNode * arg) bool FGSoundManager::playAudioSampleCommand(const SGPropertyNode * arg, SGPropertyNode * root)
{ {
string path = arg->getStringValue("path"); string path = arg->getStringValue("path");
string file = arg->getStringValue("file"); string file = arg->getStringValue("file");

View file

@ -53,7 +53,7 @@ public:
private: private:
bool stationaryView() const; bool stationaryView() const;
bool playAudioSampleCommand(const SGPropertyNode * arg); bool playAudioSampleCommand(const SGPropertyNode * arg, SGPropertyNode * root);
SGSharedPtr<FGSampleQueue> _chatterQueue; SGSharedPtr<FGSampleQueue> _chatterQueue;

View file

@ -37,7 +37,7 @@
using std::string; 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"); const string &offset_type = arg->getStringValue("timeofday", "noon");
int offset = arg->getIntValue("offset", 0); int offset = arg->getIntValue("offset", 0);

View file

@ -900,7 +900,9 @@ namespace flightgear
void initQtWindowingSystem() void initQtWindowingSystem()
{ {
osg::GraphicsContext::setWindowingSystemInterface(Qt5WindowingSystem::getInterface()); #if OSG_VERSION_LESS_THAN(3,5,2)
osg::GraphicsContext::setWindowingSystemInterface(Qt5WindowingSystem::getInterface());
#endif
} }
} // of namespace flightgear } // of namespace flightgear