diff options
author | Juan Linietsky <reduzio@gmail.com> | 2017-01-11 20:09:45 -0300 |
---|---|---|
committer | Juan Linietsky <reduzio@gmail.com> | 2017-01-11 20:10:23 -0300 |
commit | bfef8de1bc4f7a7b9617a7b181881129033a0b0e (patch) | |
tree | 929ea1b48bc8d3cc1cfbd4146bdc7a5237e79404 /modules/gdscript | |
parent | 41821ba11ddd843d737ba5d40fabaabf1e393b9c (diff) |
More efficient iteration syntax, and range() is converted behind the scenes to it.
Diffstat (limited to 'modules/gdscript')
-rw-r--r-- | modules/gdscript/gd_parser.cpp | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/modules/gdscript/gd_parser.cpp b/modules/gdscript/gd_parser.cpp index aab6946364..6aed7c9491 100644 --- a/modules/gdscript/gd_parser.cpp +++ b/modules/gdscript/gd_parser.cpp @@ -2004,6 +2004,64 @@ void GDParser::_parse_block(BlockNode *p_block,bool p_static) { return; } + if (container->type==Node::TYPE_OPERATOR) { + + OperatorNode* op = static_cast<OperatorNode*>(container); + if (op->op==OperatorNode::OP_CALL && op->arguments[0]->type==Node::TYPE_BUILT_IN_FUNCTION && static_cast<BuiltInFunctionNode*>(op->arguments[0])->function==GDFunctions::GEN_RANGE) { + //iterating a range, so see if range() can be optimized without allocating memory, by replacing it by vectors (which can work as iterable too!) + + Vector<Node*> args; + Vector<double> constants; + + bool constant=true; + + for(int i=1;i<op->arguments.size();i++) { + args.push_back(op->arguments[i]); + if (constant && op->arguments[i]->type==Node::TYPE_CONSTANT) { + ConstantNode *c = static_cast<ConstantNode*>(op->arguments[i]); + if (c->value.get_type()==Variant::REAL || c->value.get_type()==Variant::INT) { + constants.push_back(c->value); + } else { + constant=false; + } + } + } + + if (args.size()>0 || args.size()<4) { + + if (constant) { + + ConstantNode *cn = alloc_node<ConstantNode>(); + switch(args.size()) { + case 1: cn->value=constants[0]; break; + case 2: cn->value=Vector2(constants[0],constants[1]); break; + case 3: cn->value=Vector3(constants[0],constants[1],constants[2]); break; + } + container=cn; + } else { + OperatorNode *on = alloc_node<OperatorNode>(); + on->op=OperatorNode::OP_CALL; + + TypeNode *tn = alloc_node<TypeNode>(); + on->arguments.push_back(tn); + + switch(args.size()) { + case 1: tn->vtype=Variant::REAL; break; + case 2: tn->vtype=Variant::VECTOR2; break; + case 3: tn->vtype=Variant::VECTOR3; break; + } + + for(int i=0;i<args.size();i++) { + on->arguments.push_back(args[i]); + } + + container=on; + } + } + } + + } + ControlFlowNode *cf_for = alloc_node<ControlFlowNode>(); cf_for->cf_type=ControlFlowNode::CF_FOR; |