reworked ForNode evaluation()

git-svn-id: svn://anubis/fart/branches/scene-file-scripting@339 7f9b0f55-74a9-4bce-be96-3c2cd072584d
This commit is contained in:
Josh Holtrop 2010-10-06 17:42:37 +00:00
parent f36c1fa60f
commit 18886ef767
3 changed files with 100 additions and 69 deletions

View File

@ -248,32 +248,6 @@ vector<ShapeRef> Scene::processGeneralItems(refptr<Node> node)
return shapes;
}
vector<ShapeRef> Scene::processForNode(refptr<Node> node)
{
if (!node->getNode(0).isNull())
{
node->getNode(0)->getNumber();
}
vector<ShapeRef> shapes, incoming;
while (node->getNode(1)->getInteger() != 0)
{
incoming = processGeneralItems(node);
while (incoming.size() > 0)
{
shapes.push_back(incoming[0]);
incoming.erase(incoming.begin());
}
if (!node->getNode(2).isNull())
{
node->getNode(2)->getNumber();
}
}
return shapes;
}
void Scene::processMaterialDefinition(refptr<Node> node)
{
map< string, refptr<Material> >::iterator it =

View File

@ -3,6 +3,7 @@
#include <vector>
#include <iostream>
#include <typeinfo>
#include "nodes.h"
@ -25,48 +26,109 @@ Node::~Node()
{
}
double BinOpNode::getNumber()
NodeRef BinOpNode::evaluate()
{
double o = one->getNumber();
double t = two->getNumber();
double o = one->evaluate()->getNumber();
double t = two->evaluate()->getNumber();
double r = 0.0;
switch (m_op)
{
case '*':
return o * t;
r = o * t;
break;
case '/':
return o / t;
r = o / t;
break;
case '+':
return o + t;
r = o + t;
break;
case '-':
return o - t;
r = o - t;
break;
default:
cerr << "Error: BinOpNode created with op '" << m_op << "'" << endl;
exit(-3);
}
return new NumberNode(r);
}
int BoolExpressionNode::getInteger()
NodeRef BoolExpressionNode::evaluate()
{
double o, t;
double r = 0;
if (m_op != '!')
{
o = one->getNumber();
t = two->getNumber();
o = one->evaluate()->getNumber();
t = two->evaluate()->getNumber();
}
switch (m_op)
{
case '<':
return o < t;
r = o < t ? 0 : 1;
break;
case '>':
return o > t;
r = o > t ? 0 : 1;
break;
case '=':
return o == t;
r = o == t ? 0 : 1;
break;
case 'n':
return o != t;
r = o != t ? 0 : 1;
break;
case '!':
return ! one->getInteger();
r = ! one->evaluate()->getInteger();
break;
case 'T':
return 1;
r = 1;
break;
}
return 0;
return new NumberNode(r);
}
NodeRef ForNode::evaluate()
{
NodeRef eval = new EvaluatePropagateNode();
if (!m_nodes[0].isNull())
{
m_nodes[0]->evaluate();
}
while (m_nodes[1]->evaluate()->getInteger() != 0)
{
for (vector<NodeRef>::iterator it = m_children.begin();
it != m_children.end();
it++)
{
NodeRef n = (*it)->evaluate();
if ( ! n.isNull() )
{
if (typeid(*n) == typeid(EvaluatePropagateNode))
{
for (vector<NodeRef>::iterator it2 = n->getChildren().begin();
it2 != n->getChildren().end();
it2++)
{
eval->addChild(*it2);
}
}
else
{
eval->addChild(n);
}
}
}
if (!m_nodes[2].isNull())
{
m_nodes[2]->evaluate();
}
}
/* clear out all child nodes so that evaluateChildren() doesn't
* attempt to evaluate them */
m_children.clear();
return eval;
}

View File

@ -39,11 +39,6 @@ class Node
std::cerr << "Warning: Node::getString() called!" << std::endl;
return "";
}
virtual refptr<Node> getNode(int idx)
{
std::cerr << "Warning: Node::getNode() called!" << std::endl;
return NULL;
}
virtual refptr<Node> evaluate()
{
std::cerr << "Warning: Node::evaluate() called!" << std::endl;
@ -631,7 +626,7 @@ class ExpressionNode : public Node
{
public:
bool isExpression() { return true; }
virtual double getNumber() = 0;
virtual NodeRef evaluate() = 0;
};
class AssignmentNode : public ExpressionNode
@ -642,11 +637,11 @@ class AssignmentNode : public ExpressionNode
{
}
std::string getString() { return m_varref->getString(); }
double getNumber()
virtual NodeRef evaluate()
{
double n = m_expr->getNumber();
double n = m_expr->evaluate()->getNumber();
parser_scope->putGlobal(getString(), n);
return n;
return new NumberNode(n);
}
protected:
NodeRef m_varref;
@ -661,11 +656,11 @@ class LocalAssignmentNode : public ExpressionNode
{
}
std::string getString() { return m_varref->getString(); }
double getNumber()
virtual NodeRef evaluate()
{
double n = m_expr->getNumber();
double n = m_expr->evaluate()->getNumber();
parser_scope->putLocal(getString(), n);
return n;
return new NumberNode(n);
}
protected:
NodeRef m_varref;
@ -676,10 +671,10 @@ class LocalDeclNode : public ExpressionNode
{
public:
LocalDeclNode(NodeRef varref) : m_varref(varref) { }
double getNumber()
virtual NodeRef evaluate()
{
parser_scope->putLocal(m_varref->getString(), 0.0);
return 0.0;
return NULL;
}
protected:
NodeRef m_varref;
@ -692,7 +687,7 @@ class BinOpNode : public ExpressionNode
: m_op(op), one(one), two(two)
{
}
virtual double getNumber();
virtual NodeRef evaluate();
protected:
char m_op;
NodeRef one;
@ -706,7 +701,7 @@ class BoolExpressionNode : public Node
: m_op(op), one(one), two(two)
{
}
int getInteger();
virtual NodeRef evaluate();
protected:
char m_op;
NodeRef one;
@ -718,11 +713,11 @@ class VarRefNode : public Node
public:
VarRefNode(const std::string & str) { m_string = str; }
std::string getString() { return m_string; }
double getNumber()
virtual NodeRef evaluate()
{
if (parser_scope->contains(m_string))
{
return parser_scope->get(m_string);
return new NumberNode(parser_scope->get(m_string));
}
std::cerr << "Error: No identifier '" << m_string << "' in scope"
<< std::endl;
@ -741,17 +736,17 @@ class ForNode : public Node
m_nodes[1] = e2;
m_nodes[2] = e3;
}
NodeRef getNode(int idx)
{
if (0 <= idx && idx <= 2)
{
return m_nodes[idx];
}
return NULL;
}
virtual NodeRef evaluate();
protected:
NodeRef m_nodes[3];
};
/* this class is only used to hold a set of items coming out of a class's
* evaluate() from above. the evaluateChildren() top-level method will
* propagate children of this class up to the level of their parent */
class EvaluatePropagateNode : public Node
{
};
#endif