Include standard header files and qualify with std:: where needed. Add "const" to various char parameters and variables.
640 lines
20 KiB
C++
640 lines
20 KiB
C++
/* -*-c++-*-
|
|
*
|
|
* Copyright (C) 2006-2007 Mathias Froehlich
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License as
|
|
* published by the Free Software Foundation; either version 2 of the
|
|
* License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
|
* MA 02110-1301, USA.
|
|
*
|
|
*/
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
# include <simgear_config.h>
|
|
#endif
|
|
|
|
#include "SGExpression.hxx"
|
|
|
|
#include <string>
|
|
#include <sstream>
|
|
#include <simgear/props/props.hxx>
|
|
|
|
template<typename T>
|
|
static bool
|
|
SGReadValueFromString(const char* str, T& value)
|
|
{
|
|
if (!str) {
|
|
SG_LOG(SG_IO, SG_ALERT, "Cannot read string content.");
|
|
return false;
|
|
}
|
|
std::stringstream s;
|
|
s.str(std::string(str));
|
|
s >> value;
|
|
if (s.fail()) {
|
|
SG_LOG(SG_IO, SG_ALERT, "Cannot read string content.");
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
template<>
|
|
bool
|
|
SGReadValueFromString(const char* str, bool& value)
|
|
{
|
|
if (!str) {
|
|
SG_LOG(SG_IO, SG_ALERT, "Cannot read string content.");
|
|
return false;
|
|
}
|
|
std::stringstream s;
|
|
s.str(std::string(str));
|
|
s >> value;
|
|
if (!s.fail())
|
|
return true;
|
|
|
|
std::string stdstr;
|
|
if (!SGReadValueFromString(str, stdstr))
|
|
return false;
|
|
|
|
if (stdstr == "true" || stdstr == "True" || stdstr == "TRUE") {
|
|
value = true;
|
|
return true;
|
|
}
|
|
if (stdstr == "false" || stdstr == "False" || stdstr == "FALSE") {
|
|
value = true;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
template<typename T>
|
|
static bool
|
|
SGReadValueFromContent(const SGPropertyNode *node, T& value)
|
|
{
|
|
if (!node)
|
|
return false;
|
|
return SGReadValueFromString(node->getStringValue(), value);
|
|
}
|
|
|
|
template<typename T>
|
|
static SGExpression<T>*
|
|
SGReadIExpression(SGPropertyNode *inputRoot, const SGPropertyNode *expression);
|
|
|
|
template<typename T>
|
|
static bool
|
|
SGReadNaryOperands(SGNaryExpression<T>* nary,
|
|
SGPropertyNode *inputRoot, const SGPropertyNode *expression)
|
|
{
|
|
for (int i = 0; i < expression->nChildren(); ++i) {
|
|
SGExpression<T>* inputExpression;
|
|
inputExpression = SGReadIExpression<T>(inputRoot, expression->getChild(i));
|
|
if (!inputExpression)
|
|
return false;
|
|
nary->addOperand(inputExpression);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
// template<typename T>
|
|
// static SGExpression<T>*
|
|
// SGReadBExpression(SGPropertyNode *inputRoot, const SGPropertyNode *expression)
|
|
// {
|
|
// if (!expression)
|
|
// return 0;
|
|
|
|
// std::string name = expression->getName();
|
|
// if (name == "value") {
|
|
// T value;
|
|
// if (!SGReadValueFromContent(expression, value)) {
|
|
// SG_LOG(SG_IO, SG_ALERT, "Cannot read \"value\" expression.");
|
|
// return 0;
|
|
// }
|
|
// return new SGConstExpression<T>(value);
|
|
// }
|
|
|
|
// return 0;
|
|
// }
|
|
|
|
template<typename T>
|
|
static SGExpression<T>*
|
|
SGReadIExpression(SGPropertyNode *inputRoot, const SGPropertyNode *expression)
|
|
{
|
|
if (!expression)
|
|
return 0;
|
|
|
|
std::string name = expression->getName();
|
|
if (name == "value") {
|
|
T value;
|
|
if (!SGReadValueFromContent(expression, value)) {
|
|
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"value\" expression.");
|
|
return 0;
|
|
}
|
|
return new SGConstExpression<T>(value);
|
|
}
|
|
|
|
if (name == "property") {
|
|
if (!inputRoot) {
|
|
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.\n"
|
|
"No inputRoot argument given!");
|
|
return 0;
|
|
}
|
|
if (!expression->getStringValue()) {
|
|
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
|
|
return 0;
|
|
}
|
|
SGPropertyNode* inputNode;
|
|
inputNode = inputRoot->getNode(expression->getStringValue(), true);
|
|
return new SGPropertyExpression<T>(inputNode);
|
|
}
|
|
|
|
if (name == "abs" || name == "fabs") {
|
|
if (expression->nChildren() != 1) {
|
|
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
|
|
return 0;
|
|
}
|
|
SGSharedPtr<SGExpression<T> > inputExpression;
|
|
inputExpression = SGReadIExpression<T>(inputRoot, expression->getChild(0));
|
|
if (!inputExpression) {
|
|
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
|
|
return 0;
|
|
}
|
|
return new SGAbsExpression<T>(inputExpression);
|
|
}
|
|
|
|
if (name == "sqr") {
|
|
if (expression->nChildren() != 1) {
|
|
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
|
|
return 0;
|
|
}
|
|
SGSharedPtr<SGExpression<T> > inputExpression;
|
|
inputExpression = SGReadIExpression<T>(inputRoot, expression->getChild(0));
|
|
if (!inputExpression) {
|
|
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
|
|
return 0;
|
|
}
|
|
return new SGSqrExpression<T>(inputExpression);
|
|
}
|
|
|
|
if (name == "clip") {
|
|
if (expression->nChildren() != 3) {
|
|
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
|
|
return 0;
|
|
}
|
|
const SGPropertyNode* minProperty = expression->getChild("clipMin");
|
|
T clipMin;
|
|
if (!SGReadValueFromContent(minProperty, clipMin))
|
|
clipMin = SGMisc<T>::min(SGLimits<T>::min(), -SGLimits<T>::max());
|
|
|
|
const SGPropertyNode* maxProperty = expression->getChild("clipMax");
|
|
T clipMax;
|
|
if (!SGReadValueFromContent(maxProperty, clipMax))
|
|
clipMin = SGLimits<T>::max();
|
|
|
|
SGSharedPtr<SGExpression<T> > inputExpression;
|
|
for (int i = 0; !inputExpression && i < expression->nChildren(); ++i)
|
|
inputExpression = SGReadIExpression<T>(inputRoot, expression->getChild(i));
|
|
if (!inputExpression) {
|
|
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
|
|
return 0;
|
|
}
|
|
return new SGClipExpression<T>(inputExpression, clipMin, clipMax);
|
|
}
|
|
|
|
if (name == "div") {
|
|
if (expression->nChildren() != 2) {
|
|
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
|
|
return 0;
|
|
}
|
|
SGSharedPtr<SGExpression<T> > inputExpressions[2] = {
|
|
SGReadIExpression<T>(inputRoot, expression->getChild(0)),
|
|
SGReadIExpression<T>(inputRoot, expression->getChild(1))
|
|
};
|
|
if (!inputExpressions[0] || !inputExpressions[1]) {
|
|
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
|
|
return 0;
|
|
}
|
|
return new SGDivExpression<T>(inputExpressions[0], inputExpressions[1]);
|
|
}
|
|
if (name == "mod") {
|
|
if (expression->nChildren() != 2) {
|
|
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
|
|
return 0;
|
|
}
|
|
SGSharedPtr<SGExpression<T> > inputExpressions[2] = {
|
|
SGReadIExpression<T>(inputRoot, expression->getChild(0)),
|
|
SGReadIExpression<T>(inputRoot, expression->getChild(1))
|
|
};
|
|
if (!inputExpressions[0] || !inputExpressions[1]) {
|
|
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
|
|
return 0;
|
|
}
|
|
return new SGModExpression<T>(inputExpressions[0], inputExpressions[1]);
|
|
}
|
|
|
|
if (name == "sum") {
|
|
if (expression->nChildren() < 1) {
|
|
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
|
|
return 0;
|
|
}
|
|
SGSumExpression<T>* output = new SGSumExpression<T>;
|
|
if (!SGReadNaryOperands(output, inputRoot, expression)) {
|
|
delete output;
|
|
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
|
|
return 0;
|
|
}
|
|
return output;
|
|
}
|
|
if (name == "prod" || name == "product") {
|
|
if (expression->nChildren() < 1) {
|
|
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
|
|
return 0;
|
|
}
|
|
SGProductExpression<T>* output = new SGProductExpression<T>;
|
|
if (!SGReadNaryOperands(output, inputRoot, expression)) {
|
|
delete output;
|
|
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
|
|
return 0;
|
|
}
|
|
return output;
|
|
}
|
|
if (name == "min") {
|
|
if (expression->nChildren() < 1) {
|
|
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
|
|
return 0;
|
|
}
|
|
SGMinExpression<T>* output = new SGMinExpression<T>;
|
|
if (!SGReadNaryOperands(output, inputRoot, expression)) {
|
|
delete output;
|
|
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
|
|
return 0;
|
|
}
|
|
return output;
|
|
}
|
|
if (name == "max") {
|
|
if (expression->nChildren() < 1) {
|
|
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
|
|
return 0;
|
|
}
|
|
SGMaxExpression<T>* output = new SGMaxExpression<T>;
|
|
if (!SGReadNaryOperands(output, inputRoot, expression)) {
|
|
delete output;
|
|
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
|
|
return 0;
|
|
}
|
|
return output;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
template<typename T>
|
|
static SGExpression<T>*
|
|
SGReadFExpression(SGPropertyNode *inputRoot, const SGPropertyNode *expression)
|
|
{
|
|
SGExpression<T>* r = SGReadIExpression<T>(inputRoot, expression);
|
|
if (r)
|
|
return r;
|
|
|
|
if (!expression)
|
|
return 0;
|
|
|
|
std::string name = expression->getName();
|
|
if (name == "acos") {
|
|
if (expression->nChildren() != 1) {
|
|
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
|
|
return 0;
|
|
}
|
|
SGSharedPtr<SGExpression<T> > inputExpression;
|
|
inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
|
|
if (!inputExpression) {
|
|
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
|
|
return 0;
|
|
}
|
|
return new SGACosExpression<T>(inputExpression);
|
|
}
|
|
|
|
if (name == "asin") {
|
|
if (expression->nChildren() != 1) {
|
|
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
|
|
return 0;
|
|
}
|
|
SGSharedPtr<SGExpression<T> > inputExpression;
|
|
inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
|
|
if (!inputExpression) {
|
|
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
|
|
return 0;
|
|
}
|
|
return new SGASinExpression<T>(inputExpression);
|
|
}
|
|
|
|
if (name == "atan") {
|
|
if (expression->nChildren() != 1) {
|
|
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
|
|
return 0;
|
|
}
|
|
SGSharedPtr<SGExpression<T> > inputExpression;
|
|
inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
|
|
if (!inputExpression) {
|
|
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
|
|
return 0;
|
|
}
|
|
return new SGATanExpression<T>(inputExpression);
|
|
}
|
|
|
|
if (name == "ceil") {
|
|
if (expression->nChildren() != 1) {
|
|
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
|
|
return 0;
|
|
}
|
|
SGSharedPtr<SGExpression<T> > inputExpression;
|
|
inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
|
|
if (!inputExpression) {
|
|
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
|
|
return 0;
|
|
}
|
|
return new SGCeilExpression<T>(inputExpression);
|
|
}
|
|
|
|
if (name == "cos") {
|
|
if (expression->nChildren() != 1) {
|
|
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
|
|
return 0;
|
|
}
|
|
SGSharedPtr<SGExpression<T> > inputExpression;
|
|
inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
|
|
if (!inputExpression) {
|
|
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
|
|
return 0;
|
|
}
|
|
return new SGCosExpression<T>(inputExpression);
|
|
}
|
|
|
|
if (name == "cosh") {
|
|
if (expression->nChildren() != 1) {
|
|
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
|
|
return 0;
|
|
}
|
|
SGSharedPtr<SGExpression<T> > inputExpression;
|
|
inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
|
|
if (!inputExpression) {
|
|
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
|
|
return 0;
|
|
}
|
|
return new SGCoshExpression<T>(inputExpression);
|
|
}
|
|
|
|
if (name == "deg2rad") {
|
|
if (expression->nChildren() != 1) {
|
|
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
|
|
return 0;
|
|
}
|
|
SGSharedPtr<SGExpression<T> > inputExpression;
|
|
inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
|
|
if (!inputExpression) {
|
|
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
|
|
return 0;
|
|
}
|
|
return new SGScaleExpression<T>(inputExpression, SGMisc<T>::pi()/180);
|
|
}
|
|
|
|
if (name == "exp") {
|
|
if (expression->nChildren() != 1) {
|
|
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
|
|
return 0;
|
|
}
|
|
SGSharedPtr<SGExpression<T> > inputExpression;
|
|
inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
|
|
if (!inputExpression) {
|
|
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
|
|
return 0;
|
|
}
|
|
return new SGExpExpression<T>(inputExpression);
|
|
}
|
|
|
|
if (name == "floor") {
|
|
if (expression->nChildren() != 1) {
|
|
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
|
|
return 0;
|
|
}
|
|
SGSharedPtr<SGExpression<T> > inputExpression;
|
|
inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
|
|
if (!inputExpression) {
|
|
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
|
|
return 0;
|
|
}
|
|
return new SGFloorExpression<T>(inputExpression);
|
|
}
|
|
|
|
if (name == "log") {
|
|
if (expression->nChildren() != 1) {
|
|
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
|
|
return 0;
|
|
}
|
|
SGSharedPtr<SGExpression<T> > inputExpression;
|
|
inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
|
|
if (!inputExpression) {
|
|
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
|
|
return 0;
|
|
}
|
|
return new SGLogExpression<T>(inputExpression);
|
|
}
|
|
|
|
if (name == "log10") {
|
|
if (expression->nChildren() != 1) {
|
|
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
|
|
return 0;
|
|
}
|
|
SGSharedPtr<SGExpression<T> > inputExpression;
|
|
inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
|
|
if (!inputExpression) {
|
|
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
|
|
return 0;
|
|
}
|
|
return new SGLog10Expression<T>(inputExpression);
|
|
}
|
|
|
|
if (name == "rad2deg") {
|
|
if (expression->nChildren() != 1) {
|
|
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
|
|
return 0;
|
|
}
|
|
SGSharedPtr<SGExpression<T> > inputExpression;
|
|
inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
|
|
if (!inputExpression) {
|
|
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
|
|
return 0;
|
|
}
|
|
return new SGScaleExpression<T>(inputExpression, 180/SGMisc<T>::pi());
|
|
}
|
|
|
|
if (name == "sin") {
|
|
if (expression->nChildren() != 1) {
|
|
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
|
|
return 0;
|
|
}
|
|
SGSharedPtr<SGExpression<T> > inputExpression;
|
|
inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
|
|
if (!inputExpression) {
|
|
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
|
|
return 0;
|
|
}
|
|
return new SGSinExpression<T>(inputExpression);
|
|
}
|
|
|
|
if (name == "sinh") {
|
|
if (expression->nChildren() != 1) {
|
|
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
|
|
return 0;
|
|
}
|
|
SGSharedPtr<SGExpression<T> > inputExpression;
|
|
inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
|
|
if (!inputExpression) {
|
|
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
|
|
return 0;
|
|
}
|
|
return new SGSinhExpression<T>(inputExpression);
|
|
}
|
|
|
|
if (name == "sqrt") {
|
|
if (expression->nChildren() != 1) {
|
|
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
|
|
return 0;
|
|
}
|
|
SGSharedPtr<SGExpression<T> > inputExpression;
|
|
inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
|
|
if (!inputExpression) {
|
|
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
|
|
return 0;
|
|
}
|
|
return new SGSqrtExpression<T>(inputExpression);
|
|
}
|
|
|
|
if (name == "tan") {
|
|
if (expression->nChildren() != 1) {
|
|
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
|
|
return 0;
|
|
}
|
|
SGSharedPtr<SGExpression<T> > inputExpression;
|
|
inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
|
|
if (!inputExpression) {
|
|
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
|
|
return 0;
|
|
}
|
|
return new SGTanExpression<T>(inputExpression);
|
|
}
|
|
|
|
if (name == "tanh") {
|
|
if (expression->nChildren() != 1) {
|
|
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
|
|
return 0;
|
|
}
|
|
SGSharedPtr<SGExpression<T> > inputExpression;
|
|
inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
|
|
if (!inputExpression) {
|
|
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
|
|
return 0;
|
|
}
|
|
return new SGTanhExpression<T>(inputExpression);
|
|
}
|
|
|
|
// if (name == "table") {
|
|
// }
|
|
// if (name == "step") {
|
|
// }
|
|
// if (name == "condition") {
|
|
// }
|
|
|
|
if (name == "atan2") {
|
|
if (expression->nChildren() != 2) {
|
|
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
|
|
return 0;
|
|
}
|
|
SGSharedPtr<SGExpression<T> > inputExpressions[2] = {
|
|
SGReadFExpression<T>(inputRoot, expression->getChild(0)),
|
|
SGReadFExpression<T>(inputRoot, expression->getChild(1))
|
|
};
|
|
if (!inputExpressions[0] || !inputExpressions[1]) {
|
|
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
|
|
return 0;
|
|
}
|
|
return new SGAtan2Expression<T>(inputExpressions[0], inputExpressions[1]);
|
|
}
|
|
if (name == "div") {
|
|
if (expression->nChildren() != 2) {
|
|
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
|
|
return 0;
|
|
}
|
|
SGSharedPtr<SGExpression<T> > inputExpressions[2] = {
|
|
SGReadFExpression<T>(inputRoot, expression->getChild(0)),
|
|
SGReadFExpression<T>(inputRoot, expression->getChild(1))
|
|
};
|
|
if (!inputExpressions[0] || !inputExpressions[1]) {
|
|
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
|
|
return 0;
|
|
}
|
|
return new SGDivExpression<T>(inputExpressions[0], inputExpressions[1]);
|
|
}
|
|
if (name == "mod") {
|
|
if (expression->nChildren() != 2) {
|
|
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
|
|
return 0;
|
|
}
|
|
SGSharedPtr<SGExpression<T> > inputExpressions[2] = {
|
|
SGReadFExpression<T>(inputRoot, expression->getChild(0)),
|
|
SGReadFExpression<T>(inputRoot, expression->getChild(1))
|
|
};
|
|
if (!inputExpressions[0] || !inputExpressions[1]) {
|
|
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
|
|
return 0;
|
|
}
|
|
return new SGModExpression<T>(inputExpressions[0], inputExpressions[1]);
|
|
}
|
|
if (name == "pow") {
|
|
if (expression->nChildren() != 2) {
|
|
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
|
|
return 0;
|
|
}
|
|
SGSharedPtr<SGExpression<T> > inputExpressions[2] = {
|
|
SGReadIExpression<T>(inputRoot, expression->getChild(0)),
|
|
SGReadIExpression<T>(inputRoot, expression->getChild(1))
|
|
};
|
|
if (!inputExpressions[0] || !inputExpressions[1]) {
|
|
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
|
|
return 0;
|
|
}
|
|
return new SGPowExpression<T>(inputExpressions[0], inputExpressions[1]);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
SGExpression<int>*
|
|
SGReadIntExpression(SGPropertyNode *inputRoot,
|
|
const SGPropertyNode *configNode)
|
|
{ return SGReadIExpression<int>(inputRoot, configNode); }
|
|
|
|
SGExpression<float>*
|
|
SGReadFloatExpression(SGPropertyNode *inputRoot,
|
|
const SGPropertyNode *configNode)
|
|
{ return SGReadFExpression<float>(inputRoot, configNode); }
|
|
|
|
SGExpression<double>*
|
|
SGReadDoubleExpression(SGPropertyNode *inputRoot,
|
|
const SGPropertyNode *configNode)
|
|
{ return SGReadFExpression<double>(inputRoot, configNode); }
|
|
|
|
// SGExpression<bool>*
|
|
// SGReadBoolExpression(SGPropertyNode *inputRoot,
|
|
// const SGPropertyNode *configNode)
|
|
// { return SGReadBExpression<bool>(inputRoot, configNode); }
|