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; 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) void Scene::processMaterialDefinition(refptr<Node> node)
{ {
map< string, refptr<Material> >::iterator it = map< string, refptr<Material> >::iterator it =

View File

@ -3,6 +3,7 @@
#include <vector> #include <vector>
#include <iostream> #include <iostream>
#include <typeinfo>
#include "nodes.h" #include "nodes.h"
@ -25,48 +26,109 @@ Node::~Node()
{ {
} }
double BinOpNode::getNumber() NodeRef BinOpNode::evaluate()
{ {
double o = one->getNumber(); double o = one->evaluate()->getNumber();
double t = two->getNumber(); double t = two->evaluate()->getNumber();
double r = 0.0;
switch (m_op) switch (m_op)
{ {
case '*': case '*':
return o * t; r = o * t;
break;
case '/': case '/':
return o / t; r = o / t;
break;
case '+': case '+':
return o + t; r = o + t;
break;
case '-': case '-':
return o - t; r = o - t;
break;
default: default:
cerr << "Error: BinOpNode created with op '" << m_op << "'" << endl; cerr << "Error: BinOpNode created with op '" << m_op << "'" << endl;
exit(-3); exit(-3);
} }
return new NumberNode(r);
} }
int BoolExpressionNode::getInteger() NodeRef BoolExpressionNode::evaluate()
{ {
double o, t; double o, t;
double r = 0;
if (m_op != '!') if (m_op != '!')
{ {
o = one->getNumber(); o = one->evaluate()->getNumber();
t = two->getNumber(); t = two->evaluate()->getNumber();
} }
switch (m_op) switch (m_op)
{ {
case '<': case '<':
return o < t; r = o < t ? 0 : 1;
break;
case '>': case '>':
return o > t; r = o > t ? 0 : 1;
break;
case '=': case '=':
return o == t; r = o == t ? 0 : 1;
break;
case 'n': case 'n':
return o != t; r = o != t ? 0 : 1;
break;
case '!': case '!':
return ! one->getInteger(); r = ! one->evaluate()->getInteger();
break;
case 'T': 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; std::cerr << "Warning: Node::getString() called!" << std::endl;
return ""; return "";
} }
virtual refptr<Node> getNode(int idx)
{
std::cerr << "Warning: Node::getNode() called!" << std::endl;
return NULL;
}
virtual refptr<Node> evaluate() virtual refptr<Node> evaluate()
{ {
std::cerr << "Warning: Node::evaluate() called!" << std::endl; std::cerr << "Warning: Node::evaluate() called!" << std::endl;
@ -631,7 +626,7 @@ class ExpressionNode : public Node
{ {
public: public:
bool isExpression() { return true; } bool isExpression() { return true; }
virtual double getNumber() = 0; virtual NodeRef evaluate() = 0;
}; };
class AssignmentNode : public ExpressionNode class AssignmentNode : public ExpressionNode
@ -642,11 +637,11 @@ class AssignmentNode : public ExpressionNode
{ {
} }
std::string getString() { return m_varref->getString(); } 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); parser_scope->putGlobal(getString(), n);
return n; return new NumberNode(n);
} }
protected: protected:
NodeRef m_varref; NodeRef m_varref;
@ -661,11 +656,11 @@ class LocalAssignmentNode : public ExpressionNode
{ {
} }
std::string getString() { return m_varref->getString(); } 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); parser_scope->putLocal(getString(), n);
return n; return new NumberNode(n);
} }
protected: protected:
NodeRef m_varref; NodeRef m_varref;
@ -676,10 +671,10 @@ class LocalDeclNode : public ExpressionNode
{ {
public: public:
LocalDeclNode(NodeRef varref) : m_varref(varref) { } LocalDeclNode(NodeRef varref) : m_varref(varref) { }
double getNumber() virtual NodeRef evaluate()
{ {
parser_scope->putLocal(m_varref->getString(), 0.0); parser_scope->putLocal(m_varref->getString(), 0.0);
return 0.0; return NULL;
} }
protected: protected:
NodeRef m_varref; NodeRef m_varref;
@ -692,7 +687,7 @@ class BinOpNode : public ExpressionNode
: m_op(op), one(one), two(two) : m_op(op), one(one), two(two)
{ {
} }
virtual double getNumber(); virtual NodeRef evaluate();
protected: protected:
char m_op; char m_op;
NodeRef one; NodeRef one;
@ -706,7 +701,7 @@ class BoolExpressionNode : public Node
: m_op(op), one(one), two(two) : m_op(op), one(one), two(two)
{ {
} }
int getInteger(); virtual NodeRef evaluate();
protected: protected:
char m_op; char m_op;
NodeRef one; NodeRef one;
@ -718,11 +713,11 @@ class VarRefNode : public Node
public: public:
VarRefNode(const std::string & str) { m_string = str; } VarRefNode(const std::string & str) { m_string = str; }
std::string getString() { return m_string; } std::string getString() { return m_string; }
double getNumber() virtual NodeRef evaluate()
{ {
if (parser_scope->contains(m_string)) 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::cerr << "Error: No identifier '" << m_string << "' in scope"
<< std::endl; << std::endl;
@ -741,17 +736,17 @@ class ForNode : public Node
m_nodes[1] = e2; m_nodes[1] = e2;
m_nodes[2] = e3; m_nodes[2] = e3;
} }
NodeRef getNode(int idx) virtual NodeRef evaluate();
{
if (0 <= idx && idx <= 2)
{
return m_nodes[idx];
}
return NULL;
}
protected: protected:
NodeRef m_nodes[3]; 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 #endif