diff options
-rw-r--r-- | editor/editor_inspector.cpp | 2 | ||||
-rw-r--r-- | editor/plugins/canvas_item_editor_plugin.cpp | 2 | ||||
-rw-r--r-- | editor/plugins/script_editor_plugin.cpp | 6 | ||||
-rw-r--r-- | modules/gdscript/gdscript_analyzer.cpp | 11 | ||||
-rw-r--r-- | modules/gdscript/gdscript_byte_codegen.cpp | 94 | ||||
-rw-r--r-- | modules/gdscript/gdscript_byte_codegen.h | 1 | ||||
-rw-r--r-- | modules/gdscript/gdscript_codegen.h | 1 | ||||
-rw-r--r-- | modules/gdscript/gdscript_compiler.cpp | 18 | ||||
-rw-r--r-- | modules/gdscript/gdscript_parser.h | 2 | ||||
-rw-r--r-- | modules/gdscript/tests/scripts/analyzer/features/call_self_get_name.gd | 9 | ||||
-rw-r--r-- | modules/gdscript/tests/scripts/analyzer/features/call_self_get_name.out | 3 | ||||
-rw-r--r-- | modules/visual_script/visual_script_builtin_funcs.cpp | 1 | ||||
-rw-r--r-- | thirdparty/README.md | 2 | ||||
-rw-r--r-- | thirdparty/meshoptimizer/simplifier.cpp | 16 |
14 files changed, 107 insertions, 61 deletions
diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp index 0616ab07bd..f869031446 100644 --- a/editor/editor_inspector.cpp +++ b/editor/editor_inspector.cpp @@ -1626,7 +1626,7 @@ void EditorInspector::update_tree() { bool draw_red = false; - { + if (is_inside_tree()) { Node *nod = Object::cast_to<Node>(object); Node *es = EditorNode::get_singleton()->get_edited_scene(); if (nod && es != nod && nod->get_owner() != es) { diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index 21bff41498..5811e2b9ba 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -4380,7 +4380,7 @@ void CanvasItemEditor::_update_scrollbars() { // Calculate scrollable area. Rect2 canvas_item_rect = Rect2(Point2(), screen_rect); - if (editor->get_edited_scene()) { + if (editor->is_inside_tree() && editor->get_edited_scene()) { Rect2 content_rect = _get_encompassing_rect(editor->get_edited_scene()); canvas_item_rect.expand_to(content_rect.position); canvas_item_rect.expand_to(content_rect.position + content_rect.size); diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp index 1147267ce0..623e4ea66e 100644 --- a/editor/plugins/script_editor_plugin.cpp +++ b/editor/plugins/script_editor_plugin.cpp @@ -1504,8 +1504,10 @@ void ScriptEditor::_notification(int p_what) { recent_scripts->set_as_minsize(); - _update_script_colors(); - _update_script_names(); + if (is_inside_tree()) { + _update_script_colors(); + _update_script_names(); + } } break; case NOTIFICATION_READY: { diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp index 7b04959227..d8d60b35c6 100644 --- a/modules/gdscript/gdscript_analyzer.cpp +++ b/modules/gdscript/gdscript_analyzer.cpp @@ -543,6 +543,7 @@ void GDScriptAnalyzer::resolve_class_interface(GDScriptParser::ClassNode *p_clas } else { // TODO: Add warning. mark_node_unsafe(member.variable->initializer); + member.variable->use_conversion_assign = true; } } else if (datatype.builtin_type == Variant::INT && member.variable->initializer->get_datatype().builtin_type == Variant::FLOAT) { #ifdef DEBUG_ENABLED @@ -552,6 +553,7 @@ void GDScriptAnalyzer::resolve_class_interface(GDScriptParser::ClassNode *p_clas if (member.variable->initializer->get_datatype().is_variant()) { // TODO: Warn unsafe assign. mark_node_unsafe(member.variable->initializer); + member.variable->use_conversion_assign = true; } } } else if (member.variable->infer_datatype) { @@ -1145,6 +1147,7 @@ void GDScriptAnalyzer::resolve_variable(GDScriptParser::VariableNode *p_variable } else { // TODO: Add warning. mark_node_unsafe(p_variable->initializer); + p_variable->use_conversion_assign = true; } #ifdef DEBUG_ENABLED } else if (type.builtin_type == Variant::INT && p_variable->initializer->get_datatype().builtin_type == Variant::FLOAT) { @@ -1154,6 +1157,7 @@ void GDScriptAnalyzer::resolve_variable(GDScriptParser::VariableNode *p_variable if (p_variable->initializer->get_datatype().is_variant()) { // TODO: Warn unsafe assign. mark_node_unsafe(p_variable->initializer); + p_variable->use_conversion_assign = true; } } } else if (p_variable->infer_datatype) { @@ -1608,10 +1612,12 @@ void GDScriptAnalyzer::reduce_assignment(GDScriptParser::AssignmentNode *p_assig } else { // TODO: Add warning. mark_node_unsafe(p_assignment); + p_assignment->use_conversion_assign = true; } } else { // TODO: Warning in this case. mark_node_unsafe(p_assignment); + p_assignment->use_conversion_assign = true; } } } else { @@ -1621,6 +1627,9 @@ void GDScriptAnalyzer::reduce_assignment(GDScriptParser::AssignmentNode *p_assig if (assignee_type.has_no_type() || assigned_value_type.is_variant()) { mark_node_unsafe(p_assignment); + if (assignee_type.is_hard_type()) { + p_assignment->use_conversion_assign = true; + } } if (p_assignment->assignee->type == GDScriptParser::Node::IDENTIFIER) { @@ -2059,9 +2068,11 @@ void GDScriptAnalyzer::reduce_call(GDScriptParser::CallNode *p_call, bool is_awa if (p_call->is_super) { base_type = parser->current_class->base_type; + base_type.is_meta_type = false; is_self = true; } else if (callee_type == GDScriptParser::Node::IDENTIFIER) { base_type = parser->current_class->get_datatype(); + base_type.is_meta_type = false; is_self = true; } else if (callee_type == GDScriptParser::Node::SUBSCRIPT) { GDScriptParser::SubscriptNode *subscript = static_cast<GDScriptParser::SubscriptNode *>(p_call->callee); diff --git a/modules/gdscript/gdscript_byte_codegen.cpp b/modules/gdscript/gdscript_byte_codegen.cpp index ea34a2ca2d..77a972ef12 100644 --- a/modules/gdscript/gdscript_byte_codegen.cpp +++ b/modules/gdscript/gdscript_byte_codegen.cpp @@ -779,63 +779,43 @@ void GDScriptByteCodeGenerator::write_get_member(const Address &p_target, const append(p_name); } -void GDScriptByteCodeGenerator::write_assign(const Address &p_target, const Address &p_source) { - if (p_target.type.has_type && !p_source.type.has_type) { - // Typed assignment. - switch (p_target.type.kind) { - case GDScriptDataType::BUILTIN: { - if (p_target.type.builtin_type == Variant::ARRAY && p_target.type.has_container_element_type()) { - append(GDScriptFunction::OPCODE_ASSIGN_TYPED_ARRAY, 2); - append(p_target); - append(p_source); - } else { - append(GDScriptFunction::OPCODE_ASSIGN_TYPED_BUILTIN, 2); - append(p_target); - append(p_source); - append(p_target.type.builtin_type); - } - } break; - case GDScriptDataType::NATIVE: { - int class_idx = GDScriptLanguage::get_singleton()->get_global_map()[p_target.type.native_type]; - Variant nc = GDScriptLanguage::get_singleton()->get_global_array()[class_idx]; - class_idx = get_constant_pos(nc) | (GDScriptFunction::ADDR_TYPE_CONSTANT << GDScriptFunction::ADDR_BITS); - append(GDScriptFunction::OPCODE_ASSIGN_TYPED_NATIVE, 3); - append(p_target); - append(p_source); - append(class_idx); - } break; - case GDScriptDataType::SCRIPT: - case GDScriptDataType::GDSCRIPT: { - Variant script = p_target.type.script_type; - int idx = get_constant_pos(script) | (GDScriptFunction::ADDR_TYPE_CONSTANT << GDScriptFunction::ADDR_BITS); - - append(GDScriptFunction::OPCODE_ASSIGN_TYPED_SCRIPT, 3); +void GDScriptByteCodeGenerator::write_assign_with_conversion(const Address &p_target, const Address &p_source) { + switch (p_target.type.kind) { + case GDScriptDataType::BUILTIN: { + if (p_target.type.builtin_type == Variant::ARRAY && p_target.type.has_container_element_type()) { + append(GDScriptFunction::OPCODE_ASSIGN_TYPED_ARRAY, 2); append(p_target); append(p_source); - append(idx); - } break; - default: { - ERR_PRINT("Compiler bug: unresolved assign."); - - // Shouldn't get here, but fail-safe to a regular assignment - append(GDScriptFunction::OPCODE_ASSIGN, 2); + } else { + append(GDScriptFunction::OPCODE_ASSIGN_TYPED_BUILTIN, 2); append(p_target); append(p_source); + append(p_target.type.builtin_type); } - } - } else { - if (p_target.type.kind == GDScriptDataType::BUILTIN && p_target.type.builtin_type == Variant::ARRAY && p_target.type.has_container_element_type()) { - append(GDScriptFunction::OPCODE_ASSIGN_TYPED_ARRAY, 2); + } break; + case GDScriptDataType::NATIVE: { + int class_idx = GDScriptLanguage::get_singleton()->get_global_map()[p_target.type.native_type]; + Variant nc = GDScriptLanguage::get_singleton()->get_global_array()[class_idx]; + class_idx = get_constant_pos(nc) | (GDScriptFunction::ADDR_TYPE_CONSTANT << GDScriptFunction::ADDR_BITS); + append(GDScriptFunction::OPCODE_ASSIGN_TYPED_NATIVE, 3); append(p_target); append(p_source); - } else if (p_target.type.kind == GDScriptDataType::BUILTIN && p_source.type.kind == GDScriptDataType::BUILTIN && p_target.type.builtin_type != p_source.type.builtin_type) { - // Need conversion.. - append(GDScriptFunction::OPCODE_ASSIGN_TYPED_BUILTIN, 2); + append(class_idx); + } break; + case GDScriptDataType::SCRIPT: + case GDScriptDataType::GDSCRIPT: { + Variant script = p_target.type.script_type; + int idx = get_constant_pos(script) | (GDScriptFunction::ADDR_TYPE_CONSTANT << GDScriptFunction::ADDR_BITS); + + append(GDScriptFunction::OPCODE_ASSIGN_TYPED_SCRIPT, 3); append(p_target); append(p_source); - append(p_target.type.builtin_type); - } else { - // Either untyped assignment or already type-checked by the parser + append(idx); + } break; + default: { + ERR_PRINT("Compiler bug: unresolved assign."); + + // Shouldn't get here, but fail-safe to a regular assignment append(GDScriptFunction::OPCODE_ASSIGN, 2); append(p_target); append(p_source); @@ -843,6 +823,24 @@ void GDScriptByteCodeGenerator::write_assign(const Address &p_target, const Addr } } +void GDScriptByteCodeGenerator::write_assign(const Address &p_target, const Address &p_source) { + if (p_target.type.kind == GDScriptDataType::BUILTIN && p_target.type.builtin_type == Variant::ARRAY && p_target.type.has_container_element_type()) { + append(GDScriptFunction::OPCODE_ASSIGN_TYPED_ARRAY, 2); + append(p_target); + append(p_source); + } else if (p_target.type.kind == GDScriptDataType::BUILTIN && p_source.type.kind == GDScriptDataType::BUILTIN && p_target.type.builtin_type != p_source.type.builtin_type) { + // Need conversion. + append(GDScriptFunction::OPCODE_ASSIGN_TYPED_BUILTIN, 2); + append(p_target); + append(p_source); + append(p_target.type.builtin_type); + } else { + append(GDScriptFunction::OPCODE_ASSIGN, 2); + append(p_target); + append(p_source); + } +} + void GDScriptByteCodeGenerator::write_assign_true(const Address &p_target) { append(GDScriptFunction::OPCODE_ASSIGN_TRUE, 1); append(p_target); diff --git a/modules/gdscript/gdscript_byte_codegen.h b/modules/gdscript/gdscript_byte_codegen.h index f8c05fea83..b1f3cd5fb3 100644 --- a/modules/gdscript/gdscript_byte_codegen.h +++ b/modules/gdscript/gdscript_byte_codegen.h @@ -450,6 +450,7 @@ public: virtual void write_set_member(const Address &p_value, const StringName &p_name) override; virtual void write_get_member(const Address &p_target, const StringName &p_name) override; virtual void write_assign(const Address &p_target, const Address &p_source) override; + virtual void write_assign_with_conversion(const Address &p_target, const Address &p_source) override; virtual void write_assign_true(const Address &p_target) override; virtual void write_assign_false(const Address &p_target) override; virtual void write_assign_default_parameter(const Address &p_dst, const Address &p_src) override; diff --git a/modules/gdscript/gdscript_codegen.h b/modules/gdscript/gdscript_codegen.h index 399c9d6de7..cac6544f03 100644 --- a/modules/gdscript/gdscript_codegen.h +++ b/modules/gdscript/gdscript_codegen.h @@ -111,6 +111,7 @@ public: virtual void write_set_member(const Address &p_value, const StringName &p_name) = 0; virtual void write_get_member(const Address &p_target, const StringName &p_name) = 0; virtual void write_assign(const Address &p_target, const Address &p_source) = 0; + virtual void write_assign_with_conversion(const Address &p_target, const Address &p_source) = 0; virtual void write_assign_true(const Address &p_target) = 0; virtual void write_assign_false(const Address &p_target) = 0; virtual void write_assign_default_parameter(const Address &dst, const Address &src) = 0; diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp index 4ac9864d4f..179316b97e 100644 --- a/modules/gdscript/gdscript_compiler.cpp +++ b/modules/gdscript/gdscript_compiler.cpp @@ -1084,7 +1084,11 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code gen->write_call(GDScriptCodeGenerator::Address(), GDScriptCodeGenerator::Address(GDScriptCodeGenerator::Address::SELF), setter_function, args); } else { // Just assign. - gen->write_assign(target, op_result); + if (assignment->use_conversion_assign) { + gen->write_assign_with_conversion(target, op_result); + } else { + gen->write_assign(target, op_result); + } } if (op_result.mode == GDScriptCodeGenerator::Address::TEMPORARY) { @@ -1792,7 +1796,11 @@ Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::Sui if (error) { return error; } - gen->write_assign(local, src_address); + if (lv->use_conversion_assign) { + gen->write_assign_with_conversion(local, src_address); + } else { + gen->write_assign(local, src_address); + } if (src_address.mode == GDScriptCodeGenerator::Address::TEMPORARY) { codegen.generator->pop_temporary(); } @@ -1930,7 +1938,11 @@ GDScriptFunction *GDScriptCompiler::_parse_function(Error &r_error, GDScript *p_ return nullptr; } - codegen.generator->write_assign(dst_address, src_address); + if (field->use_conversion_assign) { + codegen.generator->write_assign_with_conversion(dst_address, src_address); + } else { + codegen.generator->write_assign(dst_address, src_address); + } if (src_address.mode == GDScriptCodeGenerator::Address::TEMPORARY) { codegen.generator->pop_temporary(); } diff --git a/modules/gdscript/gdscript_parser.h b/modules/gdscript/gdscript_parser.h index b1b29a7bd1..ee5e411cad 100644 --- a/modules/gdscript/gdscript_parser.h +++ b/modules/gdscript/gdscript_parser.h @@ -370,6 +370,7 @@ public: Variant::Operator variant_op = Variant::OP_MAX; ExpressionNode *assignee = nullptr; ExpressionNode *assigned_value = nullptr; + bool use_conversion_assign = false; AssignmentNode() { type = ASSIGNMENT; @@ -1119,6 +1120,7 @@ public: MultiplayerAPI::RPCMode rpc_mode = MultiplayerAPI::RPC_MODE_DISABLED; int assignments = 0; int usages = 0; + bool use_conversion_assign = false; #ifdef TOOLS_ENABLED String doc_description; #endif // TOOLS_ENABLED diff --git a/modules/gdscript/tests/scripts/analyzer/features/call_self_get_name.gd b/modules/gdscript/tests/scripts/analyzer/features/call_self_get_name.gd new file mode 100644 index 0000000000..d21d8bce96 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/features/call_self_get_name.gd @@ -0,0 +1,9 @@ +extends Node + +func test(): + set_name("TestNodeName") + if get_name() == &"TestNodeName": + print("Name is equal") + else: + print("Name is not equal") + print(get_name() is StringName) diff --git a/modules/gdscript/tests/scripts/analyzer/features/call_self_get_name.out b/modules/gdscript/tests/scripts/analyzer/features/call_self_get_name.out new file mode 100644 index 0000000000..dc4348d9c3 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/features/call_self_get_name.out @@ -0,0 +1,3 @@ +GDTEST_OK +Name is equal +True diff --git a/modules/visual_script/visual_script_builtin_funcs.cpp b/modules/visual_script/visual_script_builtin_funcs.cpp index 3b24de433c..df34ec22ce 100644 --- a/modules/visual_script/visual_script_builtin_funcs.cpp +++ b/modules/visual_script/visual_script_builtin_funcs.cpp @@ -132,6 +132,7 @@ bool VisualScriptBuiltinFunc::has_input_sequence_port() const { case TEXT_PRINT: case TEXT_PRINTERR: case TEXT_PRINTRAW: + case MATH_SEED: return true; default: return false; diff --git a/thirdparty/README.md b/thirdparty/README.md index d3599fd195..1500e8d656 100644 --- a/thirdparty/README.md +++ b/thirdparty/README.md @@ -367,7 +367,7 @@ File extracted from upstream release tarball: ## meshoptimizer - Upstream: https://github.com/zeux/meshoptimizer -- Version: 0.16 (95893c0566646434dd675b708d293fcb2d526d08, 2021) +- Version: git (f5d83e879c48f8664783a69b4f50711d27549b66, 2021) - License: MIT Files extracted from upstream repository: diff --git a/thirdparty/meshoptimizer/simplifier.cpp b/thirdparty/meshoptimizer/simplifier.cpp index 059cabb055..0f10ebef4b 100644 --- a/thirdparty/meshoptimizer/simplifier.cpp +++ b/thirdparty/meshoptimizer/simplifier.cpp @@ -120,8 +120,13 @@ struct PositionHasher { const unsigned int* key = reinterpret_cast<const unsigned int*>(vertex_positions + index * vertex_stride_float); + // scramble bits to make sure that integer coordinates have entropy in lower bits + unsigned int x = key[0] ^ (key[0] >> 17); + unsigned int y = key[1] ^ (key[1] >> 17); + unsigned int z = key[2] ^ (key[2] >> 17); + // Optimized Spatial Hashing for Collision Detection of Deformable Objects - return (key[0] * 73856093) ^ (key[1] * 19349663) ^ (key[2] * 83492791); + return (x * 73856093) ^ (y * 19349663) ^ (z * 83492791); } bool equal(unsigned int lhs, unsigned int rhs) const @@ -1160,7 +1165,7 @@ struct IdHasher struct TriangleHasher { - unsigned int* indices; + const unsigned int* indices; size_t hash(unsigned int i) const { @@ -1375,9 +1380,10 @@ static float interpolate(float y, float x0, float y0, float x1, float y1, float } // namespace meshopt #ifndef NDEBUG -unsigned char* meshopt_simplifyDebugKind = 0; -unsigned int* meshopt_simplifyDebugLoop = 0; -unsigned int* meshopt_simplifyDebugLoopBack = 0; +// Note: this is only exposed for debug visualization purposes; do *not* use these in debug builds +MESHOPTIMIZER_API unsigned char* meshopt_simplifyDebugKind = 0; +MESHOPTIMIZER_API unsigned int* meshopt_simplifyDebugLoop = 0; +MESHOPTIMIZER_API unsigned int* meshopt_simplifyDebugLoopBack = 0; #endif size_t meshopt_simplify(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions_data, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, float* out_result_error) |