diff options
Diffstat (limited to 'modules/gdscript')
| -rw-r--r-- | modules/gdscript/gd_editor.cpp | 1 | ||||
| -rw-r--r-- | modules/gdscript/gd_functions.cpp | 83 | ||||
| -rw-r--r-- | modules/gdscript/gd_functions.h | 1 | ||||
| -rw-r--r-- | modules/gdscript/gd_parser.cpp | 16 | ||||
| -rw-r--r-- | modules/gdscript/gd_script.cpp | 5 |
5 files changed, 105 insertions, 1 deletions
diff --git a/modules/gdscript/gd_editor.cpp b/modules/gdscript/gd_editor.cpp index b4e5c04c9..ff19518ad 100644 --- a/modules/gdscript/gd_editor.cpp +++ b/modules/gdscript/gd_editor.cpp @@ -52,6 +52,7 @@ String GDScriptLanguage::get_template(const String& p_class_name, const String& "# var a=2\n"+ "# var b=\"textvar\"\n\n"+ "func _ready():\n"+ + "\t# Called every time the node is added to the scene.\n"+ "\t# Initialization here\n"+ "\tpass\n"+ "\n"+ diff --git a/modules/gdscript/gd_functions.cpp b/modules/gdscript/gd_functions.cpp index 9b7d8eeac..e5689d886 100644 --- a/modules/gdscript/gd_functions.cpp +++ b/modules/gdscript/gd_functions.cpp @@ -32,6 +32,7 @@ #include "reference.h" #include "gd_script.h" #include "func_ref.h" +#include "range_iterator.h" #include "os/os.h" #include "variant_parser.h" #include "io/marshalls.h" @@ -98,6 +99,7 @@ const char *GDFunctions::get_func_name(Function p_func) { "var2bytes", "bytes2var", "range", + "xrange", "load", "inst2dict", "dict2inst", @@ -816,6 +818,81 @@ void GDFunctions::call(Function p_func,const Variant **p_args,int p_arg_count,Va } } break; + case GEN_XRANGE: { + + switch(p_arg_count) { + case 0: { + r_error.error=Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; + r_error.argument=1; + } break; + case 1: { + + VALIDATE_ARG_NUM(0); + + int count=*p_args[0]; + + Ref<RangeIterator> itr = Ref<RangeIterator>( memnew(RangeIterator) ); + if (!*itr) { + ERR_EXPLAIN("Couldn't allocate iterator!"); + r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD; + ERR_FAIL(); + } + (*itr)->set_range(count); + r_ret=Variant(itr); + return; + } break; + case 2: { + + VALIDATE_ARG_NUM(0); + VALIDATE_ARG_NUM(1); + + int from=*p_args[0]; + int to=*p_args[1]; + + Ref<RangeIterator> itr = Ref<RangeIterator>( memnew(RangeIterator) ); + if (!*itr) { + ERR_EXPLAIN("Couldn't allocate iterator!"); + r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD; + ERR_FAIL(); + } + (*itr)->set_range(from, to); + r_ret=Variant(itr); + return; + } break; + case 3: { + + VALIDATE_ARG_NUM(0); + VALIDATE_ARG_NUM(1); + VALIDATE_ARG_NUM(2); + + int from=*p_args[0]; + int to=*p_args[1]; + int incr=*p_args[2]; + + if (incr==0) { + ERR_EXPLAIN("step argument is zero!"); + r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD; + ERR_FAIL(); + } + + Ref<RangeIterator> itr = Ref<RangeIterator>( memnew(RangeIterator) ); + if (!*itr) { + ERR_EXPLAIN("Couldn't allocate iterator!"); + r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD; + ERR_FAIL(); + } + (*itr)->set_range(from, to, incr); + r_ret=Variant(itr); + return; + } break; + default: { + + r_error.error=Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS; + r_error.argument=3; + } break; + } + + } break; case RESOURCE_LOAD: { VALIDATE_ARG_COUNT(1); if (p_args[0]->get_type()!=Variant::STRING) { @@ -1433,6 +1510,12 @@ MethodInfo GDFunctions::get_info(Function p_func) { mi.return_val.type=Variant::ARRAY; return mi; } break; + case GEN_XRANGE: { + + MethodInfo mi("xrange",PropertyInfo(Variant::NIL,"...")); + mi.return_val.type=Variant::OBJECT; + return mi; + } break; case RESOURCE_LOAD: { MethodInfo mi("load",PropertyInfo(Variant::STRING,"path")); diff --git a/modules/gdscript/gd_functions.h b/modules/gdscript/gd_functions.h index 8c8847256..3a993cc03 100644 --- a/modules/gdscript/gd_functions.h +++ b/modules/gdscript/gd_functions.h @@ -92,6 +92,7 @@ public: VAR_TO_BYTES, BYTES_TO_VAR, GEN_RANGE, + GEN_XRANGE, RESOURCE_LOAD, INST2DICT, DICT2INST, diff --git a/modules/gdscript/gd_parser.cpp b/modules/gdscript/gd_parser.cpp index b6e847884..4b0164d8a 100644 --- a/modules/gdscript/gd_parser.cpp +++ b/modules/gdscript/gd_parser.cpp @@ -1779,6 +1779,20 @@ void GDParser::_parse_block(BlockNode *p_block,bool p_static) { return; } + // Little optimisation for common usage "for i in range(...):": + // don't create and initialize a possibly huge array as range() + // would do, but instead create an iterator using xrange() + if (container->type == Node::TYPE_OPERATOR) { + OperatorNode *op = static_cast<OperatorNode *>(container); + if (op->arguments.size() > 0 && + op->arguments[0]->type == Node::TYPE_BUILT_IN_FUNCTION) { + BuiltInFunctionNode *c = static_cast<BuiltInFunctionNode *>(op->arguments[0]); + if (c->function == GDFunctions::GEN_RANGE) { + c->function = GDFunctions::GEN_XRANGE; + } + } + } + ControlFlowNode *cf_for = alloc_node<ControlFlowNode>(); cf_for->cf_type=ControlFlowNode::CF_FOR; @@ -1790,7 +1804,7 @@ void GDParser::_parse_block(BlockNode *p_block,bool p_static) { p_block->sub_blocks.push_back(cf_for->body); if (!_enter_indent_block(cf_for->body)) { - _set_error("Expected indented block after 'while'"); + _set_error("Expected indented block after 'for'"); p_block->end_line=tokenizer->get_token_line(); return; } diff --git a/modules/gdscript/gd_script.cpp b/modules/gdscript/gd_script.cpp index 1b2ed670a..c1ee148ef 100644 --- a/modules/gdscript/gd_script.cpp +++ b/modules/gdscript/gd_script.cpp @@ -1481,6 +1481,11 @@ Variant GDScript::_new(const Variant** p_args,int p_argcount,Variant::CallError& /* STEP 1, CREATE */ + if (!valid) { + r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD; + return Variant(); + } + r_error.error=Variant::CallError::CALL_OK; REF ref; Object *owner=NULL; |
