From f1d39fad28d2fa29254dcfb94d420d96316322b2 Mon Sep 17 00:00:00 2001 From: mfranz <mfranz> Date: Thu, 14 May 2009 20:48:31 +0000 Subject: [PATCH] use safer and faster property methods instead of creating property paths via snprintf+strncat+absolute paths every time --- src/Environment/environment_ctrl.cxx | 97 +++++++++++----------------- 1 file changed, 38 insertions(+), 59 deletions(-) diff --git a/src/Environment/environment_ctrl.cxx b/src/Environment/environment_ctrl.cxx index 76f2942e9..14354efee 100644 --- a/src/Environment/environment_ctrl.cxx +++ b/src/Environment/environment_ctrl.cxx @@ -399,6 +399,10 @@ static void set_dewpoint_at_altitude( float dewpoint_degc, float altitude_ft ) { void FGMetarEnvironmentCtrl::update_env_config () { + // If we aren't in the METAR scenario, don't attempt to interpolate. + if (strcmp(fgGetString("/environment/weather-scenario", "METAR"), "METAR")) + return; + double dir_from; double dir_to; double speed; @@ -407,9 +411,9 @@ FGMetarEnvironmentCtrl::update_env_config () double pressure; double temp; double dewpoint; - - // If we aren't in the METAR scenario, don't attempt to interpolate. - if (strcmp(fgGetString("/environment/weather-scenario", "METAR"), "METAR")) return; + + const SGPropertyNode *metar_clouds = fgGetNode("/environment/metar/clouds", true); + SGPropertyNode *clouds = fgGetNode("/environment/clouds", true); if (metar_loaded) { // Generate interpolated values between the METAR and the current @@ -420,8 +424,8 @@ FGMetarEnvironmentCtrl::update_env_config () double metar_speed = fgGetDouble("/environment/metar/base-wind-speed-kt"); double metar_heading = fgGetDouble("/environment/metar/base-wind-range-from"); - metar[0] = metar_speed * sin((metar_heading / 180.0) * M_PI); - metar[1] = metar_speed * cos((metar_heading / 180.0) * M_PI); + metar[0] = metar_speed * sin(metar_heading * M_PI / 180.0); + metar[1] = metar_speed * cos(metar_heading * M_PI / 180.0); // Convert the current wind values and convert them into a vector double current[2]; @@ -430,8 +434,8 @@ FGMetarEnvironmentCtrl::update_env_config () double current_heading = fgGetDouble( "/environment/config/boundary/entry/wind-from-heading-deg"); - current[0] = current_speed * sin((current_heading / 180.0) * M_PI); - current[1] = current_speed * cos((current_heading / 180.0) * M_PI); + current[0] = current_speed * sin(current_heading * M_PI / 180.0); + current[1] = current_speed * cos(current_heading * M_PI / 180.0); // Determine the maximum component-wise value that the wind can change. // First we determine the fraction in the X and Y component, then @@ -498,20 +502,15 @@ FGMetarEnvironmentCtrl::update_env_config () dewpoint = fgGetDouble("/environment/metar/dewpoint-degc"); // Set the cloud layers by interpolating over the METAR versions. - SGPropertyNode * clouds = fgGetNode("/environment/metar/clouds"); - - vector<SGPropertyNode_ptr> layers = clouds->getChildren("layer"); + vector<SGPropertyNode_ptr> layers = metar_clouds->getChildren("layer"); vector<SGPropertyNode_ptr>::const_iterator layer; vector<SGPropertyNode_ptr>::const_iterator layers_end = layers.end(); - const char *cl = "/environment/clouds/layer[%i]"; double aircraft_alt = fgGetDouble("/position/altitude-ft"); - char s[128]; int i; for (i = 0, layer = layers.begin(); layer != layers_end; ++layer, i++) { - double currentval; - double requiredval; + SGPropertyNode *target = clouds->getChild("layer", i, true); // In the case of clouds, we want to avoid writing if nothing has // changed, as these properties are tied to the renderer and will @@ -520,16 +519,15 @@ FGMetarEnvironmentCtrl::update_env_config () // We don't interpolate the coverage values as no-matter how we // do it, it will be quite a sudden change of texture. Better to // have a single change than four or five. - snprintf(s, 128, cl, i); - strncat(s, "/coverage", 128); - const char* coverage = (*layer)->getStringValue("coverage", "clear"); - if (strncmp(fgGetString(s), coverage, 128) != 0) - fgSetString(s, coverage); + const char *coverage = (*layer)->getStringValue("coverage", "clear"); + SGPropertyNode *cov = target->getNode("coverage", true); + if (strcmp(cov->getStringValue(), coverage) != 0) + cov->setStringValue(coverage); - snprintf(s, 128, cl, i); - strncat(s, "/elevation-ft", 128); - double current_alt = fgGetDouble(s); double required_alt = (*layer)->getDoubleValue("elevation-ft"); + double current_alt = target->getDoubleValue("elevation-ft"); + double required_thickness = (*layer)->getDoubleValue("thickness-ft"); + SGPropertyNode *thickness = target->getNode("thickness-ft", true); if (current_alt < -9000 || required_alt < -9000 || fabs(aircraft_alt - required_alt) > MaxCloudInterpolationHeightFt || @@ -540,15 +538,11 @@ FGMetarEnvironmentCtrl::update_env_config () // - with too large a difference to make interpolation sensible // - to or from -9999 (used as a placeholder) // - any values that are too high above us, - snprintf(s, 128, cl, i); - strncat(s, "/elevation-ft", 128); if (current_alt != required_alt) - fgSetDouble(s, required_alt); + target->setDoubleValue("elevation-ft", required_alt); - snprintf(s, 128, cl, i); - strncat(s, "/thickness-ft", 128); - if (fgGetDouble(s) != (*layer)->getDoubleValue("thickness-ft")) - fgSetDouble(s, (*layer)->getDoubleValue("thickness-ft")); + if (thickness->getDoubleValue() != required_thickness) + thickness->setDoubleValue(required_thickness); } else { // Interpolate the other values in the usual way @@ -556,19 +550,16 @@ FGMetarEnvironmentCtrl::update_env_config () current_alt = interpolate_val(current_alt, required_alt, MaxCloudAltitudeChangeFtSec); - fgSetDouble(s, current_alt); + target->setDoubleValue("elevation-ft", current_alt); } - snprintf(s, 128, cl, i); - strncat(s, "/thickness-ft", 128); - currentval = fgGetDouble(s); - requiredval = (*layer)->getDoubleValue("thickness-ft"); + double current_thickness = thickness->getDoubleValue(); - if (currentval != requiredval) { - currentval = interpolate_val(currentval, - requiredval, + if (current_thickness != required_thickness) { + current_thickness = interpolate_val(current_thickness, + required_thickness, MaxCloudThicknessChangeFtSec); - fgSetDouble(s, currentval); + thickness->setDoubleValue(current_thickness); } } } @@ -584,33 +575,21 @@ FGMetarEnvironmentCtrl::update_env_config () temp = fgGetDouble("/environment/metar/temperature-degc"); dewpoint = fgGetDouble("/environment/metar/dewpoint-degc"); - // Set the cloud layers by copying over the METAR versions. - SGPropertyNode * clouds = fgGetNode("/environment/metar/clouds", true); - - vector<SGPropertyNode_ptr> layers = clouds->getChildren("layer"); + vector<SGPropertyNode_ptr> layers = metar_clouds->getChildren("layer"); vector<SGPropertyNode_ptr>::const_iterator layer; vector<SGPropertyNode_ptr>::const_iterator layers_end = layers.end(); - const char *cl = "/environment/clouds/layer[%i]"; - char s[128]; int i; - for (i = 0, layer = layers.begin(); layer != layers_end; ++layer, i++) { - snprintf(s, 128, cl, i); - strncat(s, "/coverage", 128); - fgSetString(s, (*layer)->getStringValue("coverage", "clear")); + SGPropertyNode *target = clouds->getChild("layer", i, true); - snprintf(s, 128, cl, i); - strncat(s, "/elevation-ft", 128); - fgSetDouble(s, (*layer)->getDoubleValue("elevation-ft")); - - snprintf(s, 128, cl, i); - strncat(s, "/thickness-ft", 128); - fgSetDouble(s, (*layer)->getDoubleValue("thickness-ft")); - - snprintf(s, 128, cl, i); - strncat(s, "/span-m", 128); - fgSetDouble(s, 40000.0); + target->setStringValue("coverage", + (*layer)->getStringValue("coverage", "clear")); + target->setDoubleValue("elevation-ft", + (*layer)->getDoubleValue("elevation-ft")); + target->setDoubleValue("thickness-ft", + (*layer)->getDoubleValue("thickness-ft")); + target->setDoubleValue("span-m", 40000.0); } // Force an update of the 3D clouds