From 30c12297dc6df7d35df140475c0cec7308aea77a Mon Sep 17 00:00:00 2001 From: reduz Date: Mon, 28 Dec 2015 19:31:52 -0300 Subject: - added 'onready' keyword to gdscript. Defers initialization of member variables until _ready() is run. --- modules/gdscript/gd_parser.cpp | 45 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 43 insertions(+), 2 deletions(-) (limited to 'modules/gdscript/gd_parser.cpp') diff --git a/modules/gdscript/gd_parser.cpp b/modules/gdscript/gd_parser.cpp index 4339a13ed..95e172e26 100644 --- a/modules/gdscript/gd_parser.cpp +++ b/modules/gdscript/gd_parser.cpp @@ -2767,6 +2767,21 @@ void GDParser::_parse_class(ClassNode *p_class) { } }; //fallthrough to var + case GDTokenizer::TK_PR_ONREADY: { + + if (tokenizer->get_token(-1)==GDTokenizer::TK_PR_EXPORT) { + current_export=PropertyInfo(); + _set_error("Expected 'var' (can't combine with 'onready')."); + return; + } else { + + tokenizer->advance(); + if (tokenizer->get_token()!=GDTokenizer::TK_PR_VAR) { + _set_error("Expected 'var'."); + return; + } + } + }; //fallthrough to var case GDTokenizer::TK_PR_VAR: { //variale declaration and (eventual) initialization @@ -2777,6 +2792,8 @@ void GDParser::_parse_class(ClassNode *p_class) { current_export=PropertyInfo(); } + bool onready = tokenizer->get_token(-1)==GDTokenizer::TK_PR_ONREADY; + tokenizer->advance(); if (tokenizer->get_token()!=GDTokenizer::TK_IDENTIFIER) { @@ -2807,6 +2824,21 @@ void GDParser::_parse_class(ClassNode *p_class) { return; } + //discourage common error + if (!onready && subexpr->type==Node::TYPE_OPERATOR) { + + OperatorNode *op=static_cast(subexpr); + if (op->op==OperatorNode::OP_CALL && op->arguments[0]->type==Node::TYPE_SELF && op->arguments[1]->type==Node::TYPE_IDENTIFIER) { + IdentifierNode *id=static_cast(op->arguments[1]); + if (id->name=="get_node") { + + _set_error("Use 'onready var "+String(member.identifier)+" = get_node(..)' instead"); + return; + + } + } + } + member.expression=subexpr; if (autoexport) { @@ -2853,12 +2885,19 @@ void GDParser::_parse_class(ClassNode *p_class) { op->arguments.push_back(id); op->arguments.push_back(subexpr); + #ifdef DEBUG_ENABLED NewLineNode *nl = alloc_node(); nl->line=line; - p_class->initializer->statements.push_back(nl); + if (onready) + p_class->ready->statements.push_back(nl); + else + p_class->initializer->statements.push_back(nl); #endif - p_class->initializer->statements.push_back(op); + if (onready) + p_class->ready->statements.push_back(op); + else + p_class->initializer->statements.push_back(op); @@ -3009,6 +3048,8 @@ Error GDParser::_parse(const String& p_base_path) { ClassNode *main_class = alloc_node(); main_class->initializer = alloc_node(); main_class->initializer->parent_class=main_class; + main_class->ready = alloc_node(); + main_class->ready->parent_class=main_class; current_class=main_class; _parse_class(main_class); -- cgit v1.2.3-70-g09d2 From f7b64a62d115d4955a47ea6735960f535ed8133c Mon Sep 17 00:00:00 2001 From: reduz Date: Mon, 28 Dec 2015 21:05:57 -0300 Subject: -renamed function get_relative_transform() to get_relative_transform_to_parent(), makes more sense -fixed newly introduced bug in onready keyword, fixes #3155 --- modules/gdscript/gd_parser.cpp | 8 ++------ scene/2d/navigation_polygon.cpp | 8 ++++---- scene/2d/node_2d.cpp | 7 ++++--- scene/2d/node_2d.h | 2 +- scene/2d/tile_map.cpp | 4 ++-- 5 files changed, 13 insertions(+), 16 deletions(-) (limited to 'modules/gdscript/gd_parser.cpp') diff --git a/modules/gdscript/gd_parser.cpp b/modules/gdscript/gd_parser.cpp index 95e172e26..3da12fc38 100644 --- a/modules/gdscript/gd_parser.cpp +++ b/modules/gdscript/gd_parser.cpp @@ -2769,12 +2769,8 @@ void GDParser::_parse_class(ClassNode *p_class) { }; //fallthrough to var case GDTokenizer::TK_PR_ONREADY: { - if (tokenizer->get_token(-1)==GDTokenizer::TK_PR_EXPORT) { - current_export=PropertyInfo(); - _set_error("Expected 'var' (can't combine with 'onready')."); - return; - } else { - + if (token==GDTokenizer::TK_PR_ONREADY) { + //may be fallthrough from export, ignore if so tokenizer->advance(); if (tokenizer->get_token()!=GDTokenizer::TK_PR_VAR) { _set_error("Expected 'var'."); diff --git a/scene/2d/navigation_polygon.cpp b/scene/2d/navigation_polygon.cpp index 792f079ab..4c00d8cec 100644 --- a/scene/2d/navigation_polygon.cpp +++ b/scene/2d/navigation_polygon.cpp @@ -273,7 +273,7 @@ void NavigationPolygonInstance::set_enabled(bool p_enabled) { if (navpoly.is_valid()) { - nav_id = navigation->navpoly_create(navpoly,get_relative_transform(navigation),this); + nav_id = navigation->navpoly_create(navpoly,get_relative_transform_to_parent(navigation),this); } } @@ -309,7 +309,7 @@ void NavigationPolygonInstance::_notification(int p_what) { if (enabled && navpoly.is_valid()) { - nav_id = navigation->navpoly_create(navpoly,get_relative_transform(navigation),this); + nav_id = navigation->navpoly_create(navpoly,get_relative_transform_to_parent(navigation),this); } break; } @@ -321,7 +321,7 @@ void NavigationPolygonInstance::_notification(int p_what) { case NOTIFICATION_TRANSFORM_CHANGED: { if (navigation && nav_id!=-1) { - navigation->navpoly_set_transform(nav_id,get_relative_transform(navigation)); + navigation->navpoly_set_transform(nav_id,get_relative_transform_to_parent(navigation)); } } break; @@ -409,7 +409,7 @@ void NavigationPolygonInstance::set_navigation_polygon(const Refnavpoly_create(navpoly,get_relative_transform(navigation),this); + nav_id = navigation->navpoly_create(navpoly,get_relative_transform_to_parent(navigation),this); } //update_gizmo(); _change_notify("navpoly"); diff --git a/scene/2d/node_2d.cpp b/scene/2d/node_2d.cpp index 975827bc7..0683d31fc 100644 --- a/scene/2d/node_2d.cpp +++ b/scene/2d/node_2d.cpp @@ -333,17 +333,18 @@ int Node2D::get_z() const{ return z; } -Matrix32 Node2D::get_relative_transform(const Node *p_parent) const { +Matrix32 Node2D::get_relative_transform_to_parent(const Node *p_parent) const { if (p_parent==this) return Matrix32(); Node2D *parent_2d = get_parent()->cast_to(); + ERR_FAIL_COND_V(!parent_2d,Matrix32()); if (p_parent==parent_2d) return get_transform(); else - return parent_2d->get_relative_transform(p_parent) * get_transform(); + return parent_2d->get_relative_transform_to_parent(p_parent) * get_transform(); } @@ -396,7 +397,7 @@ void Node2D::_bind_methods() { ObjectTypeDB::bind_method(_MD("edit_set_pivot","pivot"),&Node2D::edit_set_pivot); - ObjectTypeDB::bind_method(_MD("get_relative_transform","parent"),&Node2D::get_relative_transform); + ObjectTypeDB::bind_method(_MD("get_relative_transform_to_parent","parent"),&Node2D::get_relative_transform_to_parent); ADD_PROPERTYNZ(PropertyInfo(Variant::VECTOR2,"transform/pos"),_SCS("set_pos"),_SCS("get_pos")); ADD_PROPERTYNZ(PropertyInfo(Variant::REAL,"transform/rot",PROPERTY_HINT_RANGE,"-1440,1440,0.1"),_SCS("_set_rotd"),_SCS("_get_rotd")); diff --git a/scene/2d/node_2d.h b/scene/2d/node_2d.h index 8efce33cd..a964a6ae3 100644 --- a/scene/2d/node_2d.h +++ b/scene/2d/node_2d.h @@ -99,7 +99,7 @@ public: void set_z_as_relative(bool p_enabled); bool is_z_relative() const; - Matrix32 get_relative_transform(const Node *p_parent) const; + Matrix32 get_relative_transform_to_parent(const Node *p_parent) const; diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index 1d48a9c8a..679ff719c 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -118,7 +118,7 @@ void TileMap::_update_quadrant_transform() { Matrix32 nav_rel; if (navigation) - nav_rel = get_relative_transform(navigation); + nav_rel = get_relative_transform_to_parent(navigation); for (Map::Element *E=quadrant_map.front();E;E=E->next()) { @@ -261,7 +261,7 @@ void TileMap::_update_dirty_quadrants() { Vector2 tcenter = cell_size/2; Matrix32 nav_rel; if (navigation) - nav_rel = get_relative_transform(navigation); + nav_rel = get_relative_transform_to_parent(navigation); Vector2 qofs; -- cgit v1.2.3-70-g09d2 From 99736e63e45b323d06411926bd92210a08c717c2 Mon Sep 17 00:00:00 2001 From: reduz Date: Tue, 29 Dec 2015 11:41:37 -0300 Subject: -fixed bug with some indent blocks not properly checked, fixes #2570 -added ability to do one-line blocks, such as: if something: print("hello") , to be more python-like --- modules/gdscript/gd_parser.cpp | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) (limited to 'modules/gdscript/gd_parser.cpp') diff --git a/modules/gdscript/gd_parser.cpp b/modules/gdscript/gd_parser.cpp index 3da12fc38..f924f1de3 100644 --- a/modules/gdscript/gd_parser.cpp +++ b/modules/gdscript/gd_parser.cpp @@ -75,20 +75,28 @@ bool GDParser::_enter_indent_block(BlockNode* p_block) { if (tokenizer->get_token()!=GDTokenizer::TK_NEWLINE) { - _set_error("newline expected after ':'."); - return false; + // be more python-like + int current = tab_level.back()->get(); + tab_level.push_back(current+1); + return true; + //_set_error("newline expected after ':'."); + //return false; } while(true) { if (tokenizer->get_token()!=GDTokenizer::TK_NEWLINE) { + print_line("no newline"); return false; //wtf } else if (tokenizer->get_token(1)!=GDTokenizer::TK_NEWLINE) { int indent = tokenizer->get_token_line_indent(); int current = tab_level.back()->get(); - if (indent<=current) + if (indent<=current) { + print_line("current: "+itos(current)+" indent: "+itos(indent)); + print_line("less than current"); return false; + } tab_level.push_back(indent); tokenizer->advance(); @@ -1588,6 +1596,7 @@ void GDParser::_parse_block(BlockNode *p_block,bool p_static) { p_block->sub_blocks.push_back(cf_if->body); if (!_enter_indent_block(cf_if->body)) { + _set_error("Expected intended block after 'if'"); p_block->end_line=tokenizer->get_token_line(); return; } @@ -1647,6 +1656,7 @@ void GDParser::_parse_block(BlockNode *p_block,bool p_static) { if (!_enter_indent_block(cf_if->body)) { + _set_error("Expected indented block after 'elif'"); p_block->end_line=tokenizer->get_token_line(); return; } @@ -1661,7 +1671,6 @@ void GDParser::_parse_block(BlockNode *p_block,bool p_static) { } else if (tokenizer->get_token()==GDTokenizer::TK_CF_ELSE) { if (tab_level.back()->get() > indent_level) { - _set_error("Invalid indent"); return; } @@ -1673,6 +1682,7 @@ void GDParser::_parse_block(BlockNode *p_block,bool p_static) { p_block->sub_blocks.push_back(cf_if->body_else); if (!_enter_indent_block(cf_if->body_else)) { + _set_error("Expected indented block after 'else'"); p_block->end_line=tokenizer->get_token_line(); return; } @@ -1713,6 +1723,7 @@ void GDParser::_parse_block(BlockNode *p_block,bool p_static) { p_block->sub_blocks.push_back(cf_while->body); if (!_enter_indent_block(cf_while->body)) { + _set_error("Expected indented block after 'while'"); p_block->end_line=tokenizer->get_token_line(); return; } @@ -1764,6 +1775,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'"); p_block->end_line=tokenizer->get_token_line(); return; } -- cgit v1.2.3-70-g09d2 From 7d2d1442f83e6a7a57a1823a6cf5af53e5419d5f Mon Sep 17 00:00:00 2001 From: reduz Date: Tue, 29 Dec 2015 12:11:21 -0300 Subject: -add breakpoint statement to ease with debugging, closes #3165 --- modules/gdscript/gd_compiler.cpp | 4 ++++ modules/gdscript/gd_parser.cpp | 11 +++++++++++ modules/gdscript/gd_parser.h | 5 +++++ modules/gdscript/gd_script.cpp | 9 +++++++++ modules/gdscript/gd_script.h | 1 + modules/gdscript/gd_tokenizer.cpp | 4 +++- modules/gdscript/gd_tokenizer.h | 1 + 7 files changed, 34 insertions(+), 1 deletion(-) (limited to 'modules/gdscript/gd_parser.cpp') diff --git a/modules/gdscript/gd_compiler.cpp b/modules/gdscript/gd_compiler.cpp index a45c79aca..add6235f3 100644 --- a/modules/gdscript/gd_compiler.cpp +++ b/modules/gdscript/gd_compiler.cpp @@ -1156,6 +1156,10 @@ Error GDCompiler::_parse_block(CodeGen& codegen,const GDParser::BlockNode *p_blo codegen.opcodes.push_back(GDFunction::OPCODE_ASSERT); codegen.opcodes.push_back(ret); } break; + case GDParser::Node::TYPE_BREAKPOINT: { + // try subblocks + codegen.opcodes.push_back(GDFunction::OPCODE_BREAKPOINT); + } break; case GDParser::Node::TYPE_LOCAL_VAR: { diff --git a/modules/gdscript/gd_parser.cpp b/modules/gdscript/gd_parser.cpp index f924f1de3..912170d2b 100644 --- a/modules/gdscript/gd_parser.cpp +++ b/modules/gdscript/gd_parser.cpp @@ -1862,6 +1862,17 @@ void GDParser::_parse_block(BlockNode *p_block,bool p_static) { return; } } break; + case GDTokenizer::TK_PR_BREAKPOINT: { + + tokenizer->advance(); + BreakpointNode *bn = alloc_node(); + p_block->statements.push_back(bn); + + if (!_end_statement()) { + _set_error("Expected end of statement after breakpoint."); + return; + } + } break; default: { Node *expression = _parse_and_reduce_expression(p_block,p_static,false,true); diff --git a/modules/gdscript/gd_parser.h b/modules/gdscript/gd_parser.h index 4aa5c8cfe..143c5f20e 100644 --- a/modules/gdscript/gd_parser.h +++ b/modules/gdscript/gd_parser.h @@ -54,6 +54,7 @@ public: TYPE_CONTROL_FLOW, TYPE_LOCAL_VAR, TYPE_ASSERT, + TYPE_BREAKPOINT, TYPE_NEWLINE, }; @@ -276,6 +277,10 @@ public: AssertNode() { type=TYPE_ASSERT; } }; + struct BreakpointNode : public Node { + BreakpointNode() { type=TYPE_BREAKPOINT; } + }; + struct NewLineNode : public Node { NewLineNode() { type=TYPE_NEWLINE; } }; diff --git a/modules/gdscript/gd_script.cpp b/modules/gdscript/gd_script.cpp index 70c788776..1c19328fe 100644 --- a/modules/gdscript/gd_script.cpp +++ b/modules/gdscript/gd_script.cpp @@ -1077,6 +1077,14 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a ip+=2; } continue; + case OPCODE_BREAKPOINT: { +#ifdef DEBUG_ENABLED + if (ScriptDebugger::get_singleton()) { + GDScriptLanguage::get_singleton()->debug_break("Breakpoint Statement",true); + } +#endif + ip+=1; + } continue; case OPCODE_LINE: { CHECK_SPACE(2); @@ -2672,6 +2680,7 @@ void GDScriptLanguage::get_reserved_words(List *p_words) const { "or", "export", "assert", + "breakpoint", "yield", "static", "float", diff --git a/modules/gdscript/gd_script.h b/modules/gdscript/gd_script.h index 952a28bdb..6fea20470 100644 --- a/modules/gdscript/gd_script.h +++ b/modules/gdscript/gd_script.h @@ -71,6 +71,7 @@ public: OPCODE_ITERATE_BEGIN, OPCODE_ITERATE, OPCODE_ASSERT, + OPCODE_BREAKPOINT, OPCODE_LINE, OPCODE_END }; diff --git a/modules/gdscript/gd_tokenizer.cpp b/modules/gdscript/gd_tokenizer.cpp index c732c00b8..39c7f3cfc 100644 --- a/modules/gdscript/gd_tokenizer.cpp +++ b/modules/gdscript/gd_tokenizer.cpp @@ -98,6 +98,7 @@ const char* GDTokenizer::token_names[TK_MAX]={ "assert", "yield", "signal", +"breakpoint", "'['", "']'", "'{'", @@ -861,6 +862,7 @@ void GDTokenizerText::_advance() { {TK_PR_ASSERT,"assert"}, {TK_PR_YIELD,"yield"}, {TK_PR_SIGNAL,"signal"}, + {TK_PR_BREAKPOINT,"breakpoint"}, {TK_PR_CONST,"const"}, //controlflow {TK_CF_IF,"if"}, @@ -1041,7 +1043,7 @@ void GDTokenizerText::advance(int p_amount) { ////////////////////////////////////////////////////////////////////////////////////////////////////// -#define BYTECODE_VERSION 6 +#define BYTECODE_VERSION 7 Error GDTokenizerBuffer::set_code_buffer(const Vector & p_buffer) { diff --git a/modules/gdscript/gd_tokenizer.h b/modules/gdscript/gd_tokenizer.h index 3c0107cea..96dd7ed20 100644 --- a/modules/gdscript/gd_tokenizer.h +++ b/modules/gdscript/gd_tokenizer.h @@ -106,6 +106,7 @@ public: TK_PR_ASSERT, TK_PR_YIELD, TK_PR_SIGNAL, + TK_PR_BREAKPOINT, TK_BRACKET_OPEN, TK_BRACKET_CLOSE, TK_CURLY_BRACKET_OPEN, -- cgit v1.2.3-70-g09d2 From 821351be0420c4b3def6b83c287ee7463e6e3506 Mon Sep 17 00:00:00 2001 From: Zher Huei Lee Date: Wed, 30 Dec 2015 00:23:26 +0000 Subject: added missing onready allocation for subclasses Fixes #3158 --- modules/gdscript/gd_parser.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'modules/gdscript/gd_parser.cpp') diff --git a/modules/gdscript/gd_parser.cpp b/modules/gdscript/gd_parser.cpp index 912170d2b..64b7f26e9 100644 --- a/modules/gdscript/gd_parser.cpp +++ b/modules/gdscript/gd_parser.cpp @@ -2081,6 +2081,8 @@ void GDParser::_parse_class(ClassNode *p_class) { ClassNode *newclass = alloc_node(); newclass->initializer = alloc_node(); newclass->initializer->parent_class=newclass; + newclass->ready = alloc_node(); + newclass->ready->parent_class=newclass; newclass->name=name; newclass->owner=p_class; -- cgit v1.2.3-70-g09d2