diff options
Diffstat (limited to 'modules')
-rw-r--r-- | modules/gdscript/editor/gdscript_highlighter.cpp | 69 | ||||
-rw-r--r-- | modules/gdscript/gdscript.cpp | 43 | ||||
-rw-r--r-- | modules/gdscript/gdscript.h | 5 | ||||
-rw-r--r-- | modules/mono/csharp_script.cpp | 70 | ||||
-rw-r--r-- | modules/mono/csharp_script.h | 5 | ||||
-rw-r--r-- | modules/text_server_adv/text_server_adv.cpp | 8 | ||||
-rw-r--r-- | modules/text_server_fb/text_server_fb.cpp | 8 | ||||
-rw-r--r-- | modules/visual_script/visual_script.h | 3 |
8 files changed, 183 insertions, 28 deletions
diff --git a/modules/gdscript/editor/gdscript_highlighter.cpp b/modules/gdscript/editor/gdscript_highlighter.cpp index a23f19de85..e7299b4d3a 100644 --- a/modules/gdscript/editor/gdscript_highlighter.cpp +++ b/modules/gdscript/editor/gdscript_highlighter.cpp @@ -46,6 +46,7 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l bool prev_is_char = false; bool prev_is_number = false; + bool prev_is_binary_op = false; bool in_keyword = false; bool in_word = false; bool in_function_name = false; @@ -84,16 +85,17 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l const int line_length = str.length(); Color prev_color; - if (in_region != -1 && str.length() == 0) { + if (in_region != -1 && line_length == 0) { color_region_cache[p_line] = in_region; } - for (int j = 0; j < str.length(); j++) { + for (int j = 0; j < line_length; j++) { Dictionary highlighter_info; color = font_color; bool is_char = !is_symbol(str[j]); bool is_a_symbol = is_symbol(str[j]); bool is_number = is_digit(str[j]); + bool is_binary_op = false; /* color regions */ if (is_a_symbol || in_region != -1) { @@ -244,7 +246,7 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l is_hex_notation = false; } - // disallow anything not a 0 or 1 + // disallow anything not a 0 or 1 in binary notation if (is_bin_notation && (is_binary_digit(str[j]))) { is_number = true; } else if (is_bin_notation) { @@ -285,7 +287,7 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l if (!in_keyword && is_char && !prev_is_char) { int to = j; - while (to < str.length() && !is_symbol(str[to])) { + while (to < line_length && !is_symbol(str[to])) { to++; } @@ -318,12 +320,12 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l in_signal_declaration = true; } else { int k = j; - while (k < str.length() && !is_symbol(str[k]) && str[k] != '\t' && str[k] != ' ') { + while (k < line_length && !is_symbol(str[k]) && !is_whitespace(str[k])) { k++; } // check for space between name and bracket - while (k < str.length() && (str[k] == '\t' || str[k] == ' ')) { + while (k < line_length && is_whitespace(str[k])) { k++; } @@ -336,7 +338,7 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l // Check for lambda. if (in_function_name && previous_text == GDScriptTokenizer::get_token_name(GDScriptTokenizer::Token::FUNC)) { k = j - 1; - while (k > 0 && (str[k] == '\t' || str[k] == ' ')) { + while (k > 0 && is_whitespace(str[k])) { k--; } @@ -349,7 +351,7 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l if (!in_function_name && !in_member_variable && !in_keyword && !is_number && in_word) { int k = j; - while (k > 0 && !is_symbol(str[k]) && str[k] != '\t' && str[k] != ' ') { + while (k > 0 && !is_symbol(str[k]) && !is_whitespace(str[k])) { k--; } @@ -378,7 +380,7 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l if (in_variable_declaration || in_function_args) { int k = j; // Skip space - while (k < str.length() && (str[k] == '\t' || str[k] == ' ')) { + while (k < line_length && is_whitespace(str[k])) { k++; } @@ -395,13 +397,41 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l in_member_variable = false; } - if (!in_node_path && in_region == -1 && (str[j] == '^')) { + if (j > 0 && (str[j] == '&' || str[j] == '^' || str[j] == '%' || str[j] == '+' || str[j] == '-' || str[j] == '~')) { + int k = j - 1; + while (k > 0 && is_whitespace(str[k])) { + k--; + } + if (!is_symbol(str[k]) || str[k] == '"' || str[k] == '\'' || str[k] == ')' || str[k] == ']' || str[k] == '}') { + is_binary_op = true; + } + } + + // Highlight '+' and '-' like numbers when unary + if ((str[j] == '+' || str[j] == '-' || str[j] == '~') && !is_binary_op) { + is_number = true; + is_a_symbol = false; + } + + // Keep symbol color for binary '&&'. In the case of '&&&' use StringName color for the last ampersand + if (!in_string_name && in_region == -1 && str[j] == '&' && !is_binary_op) { + if (j >= 2 && str[j - 1] == '&' && str[j - 2] != '&' && prev_is_binary_op) { + is_binary_op = true; + } else if (j == 0 || (j > 0 && str[j - 1] != '&') || prev_is_binary_op) { + in_string_name = true; + } + } else if (in_region != -1 || is_a_symbol) { + in_string_name = false; + } + + // '^^' has no special meaning, so unlike StringName, when binary, use NodePath color for the last caret + if (!in_node_path && in_region == -1 && str[j] == '^' && !is_binary_op && (j == 0 || (j > 0 && str[j - 1] != '^') || prev_is_binary_op)) { in_node_path = true; - } else if (in_region != -1 || (is_a_symbol && str[j] != '/' && str[j] != '%')) { + } else if (in_region != -1 || is_a_symbol) { in_node_path = false; } - if (!in_node_ref && in_region == -1 && (str[j] == '$' || str[j] == '%')) { + if (!in_node_ref && in_region == -1 && (str[j] == '$' || (str[j] == '%' && !is_binary_op))) { in_node_ref = true; } else if (in_region != -1 || (is_a_symbol && str[j] != '/' && str[j] != '%')) { in_node_ref = false; @@ -413,16 +443,7 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l in_annotation = false; } - if (!in_string_name && in_region == -1 && str[j] == '&') { - in_string_name = true; - } else if (in_region != -1 || is_a_symbol) { - in_string_name = false; - } - - if (in_node_path) { - next_type = NODE_PATH; - color = node_path_color; - } else if (in_node_ref) { + if (in_node_ref) { next_type = NODE_REF; color = node_ref_color; } else if (in_annotation) { @@ -431,6 +452,9 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l } else if (in_string_name) { next_type = STRING_NAME; color = string_name_color; + } else if (in_node_path) { + next_type = NODE_PATH; + color = node_path_color; } else if (in_keyword) { next_type = KEYWORD; color = keyword_color; @@ -487,6 +511,7 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l prev_is_char = is_char; prev_is_number = is_number; + prev_is_binary_op = is_binary_op; if (color != prev_color) { prev_color = color; diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp index 8a5e93eeff..cf2d6ae9f8 100644 --- a/modules/gdscript/gdscript.cpp +++ b/modules/gdscript/gdscript.cpp @@ -1538,6 +1538,47 @@ void GDScriptInstance::get_property_list(List<PropertyInfo> *p_properties) const } } +bool GDScriptInstance::property_can_revert(const StringName &p_name) const { + Variant name = p_name; + const Variant *args[1] = { &name }; + + const GDScript *sptr = script.ptr(); + while (sptr) { + HashMap<StringName, GDScriptFunction *>::ConstIterator E = sptr->member_functions.find(GDScriptLanguage::get_singleton()->strings._property_can_revert); + if (E) { + Callable::CallError err; + Variant ret = E->value->call(const_cast<GDScriptInstance *>(this), args, 1, err); + if (err.error == Callable::CallError::CALL_OK && ret.get_type() == Variant::BOOL && ret.operator bool()) { + return true; + } + } + sptr = sptr->_base; + } + + return false; +} + +bool GDScriptInstance::property_get_revert(const StringName &p_name, Variant &r_ret) const { + Variant name = p_name; + const Variant *args[1] = { &name }; + + const GDScript *sptr = script.ptr(); + while (sptr) { + HashMap<StringName, GDScriptFunction *>::ConstIterator E = sptr->member_functions.find(GDScriptLanguage::get_singleton()->strings._property_get_revert); + if (E) { + Callable::CallError err; + Variant ret = E->value->call(const_cast<GDScriptInstance *>(this), args, 1, err); + if (err.error == Callable::CallError::CALL_OK && ret.get_type() != Variant::NIL) { + r_ret = ret; + return true; + } + } + sptr = sptr->_base; + } + + return false; +} + void GDScriptInstance::get_method_list(List<MethodInfo> *p_list) const { const GDScript *sptr = script.ptr(); while (sptr) { @@ -2248,6 +2289,8 @@ GDScriptLanguage::GDScriptLanguage() { strings._set = StaticCString::create("_set"); strings._get = StaticCString::create("_get"); strings._get_property_list = StaticCString::create("_get_property_list"); + strings._property_can_revert = StaticCString::create("_property_can_revert"); + strings._property_get_revert = StaticCString::create("_property_get_revert"); strings._script_source = StaticCString::create("script/source"); _debug_parse_err_line = -1; _debug_parse_err_file = ""; diff --git a/modules/gdscript/gdscript.h b/modules/gdscript/gdscript.h index 5123cccddd..e4b12d4ddb 100644 --- a/modules/gdscript/gdscript.h +++ b/modules/gdscript/gdscript.h @@ -287,6 +287,9 @@ public: virtual void get_property_list(List<PropertyInfo> *p_properties) const; virtual Variant::Type get_property_type(const StringName &p_name, bool *r_is_valid = nullptr) const; + virtual bool property_can_revert(const StringName &p_name) const; + virtual bool property_get_revert(const StringName &p_name, Variant &r_ret) const; + virtual void get_method_list(List<MethodInfo> *p_list) const; virtual bool has_method(const StringName &p_method) const; virtual Variant callp(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error); @@ -423,6 +426,8 @@ public: StringName _set; StringName _get; StringName _get_property_list; + StringName _property_can_revert; + StringName _property_get_revert; StringName _script_source; } strings; diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp index 475b483d6c..b95b63cf1f 100644 --- a/modules/mono/csharp_script.cpp +++ b/modules/mono/csharp_script.cpp @@ -1853,6 +1853,74 @@ Variant::Type CSharpInstance::get_property_type(const StringName &p_name, bool * return Variant::NIL; } +bool CSharpInstance::property_can_revert(const StringName &p_name) const { + ERR_FAIL_COND_V(!script.is_valid(), false); + + GD_MONO_SCOPE_THREAD_ATTACH; + + MonoObject *mono_object = get_mono_object(); + ERR_FAIL_NULL_V(mono_object, false); + + GDMonoClass *top = script->script_class; + + while (top && top != script->native) { + GDMonoMethod *method = top->get_method(CACHED_STRING_NAME(_property_can_revert), 1); + + if (method) { + Variant name = p_name; + const Variant *args[1] = { &name }; + + MonoObject *ret = method->invoke(mono_object, args); + + if (ret) { + bool can_revert = GDMonoMarshal::mono_object_to_variant(ret); + if (can_revert) { + return true; + } + } + + break; + } + + top = top->get_parent_class(); + } + + return false; +} + +bool CSharpInstance::property_get_revert(const StringName &p_name, Variant &r_ret) const { + ERR_FAIL_COND_V(!script.is_valid(), false); + + GD_MONO_SCOPE_THREAD_ATTACH; + + MonoObject *mono_object = get_mono_object(); + ERR_FAIL_NULL_V(mono_object, false); + + GDMonoClass *top = script->script_class; + + while (top && top != script->native) { + GDMonoMethod *method = top->get_method(CACHED_STRING_NAME(_property_get_revert), 1); + + if (method) { + Variant name = p_name; + const Variant *args[1] = { &name }; + + MonoObject *ret = method->invoke(mono_object, args); + + if (ret) { + r_ret = GDMonoMarshal::mono_object_to_variant(ret); + return true; + } + + break; + } + + top = top->get_parent_class(); + } + + return false; +} + void CSharpInstance::get_method_list(List<MethodInfo> *p_list) const { if (!script->is_valid() || !script->script_class) { return; @@ -3705,6 +3773,8 @@ CSharpLanguage::StringNameCache::StringNameCache() { _set = StaticCString::create("_set"); _get = StaticCString::create("_get"); _get_property_list = StaticCString::create("_get_property_list"); + _property_can_revert = StaticCString::create("_property_can_revert"); + _property_get_revert = StaticCString::create("_property_get_revert"); _notification = StaticCString::create("_notification"); _script_source = StaticCString::create("script/source"); on_before_serialize = StaticCString::create("OnBeforeSerialize"); diff --git a/modules/mono/csharp_script.h b/modules/mono/csharp_script.h index 48129e69cb..823de91bf6 100644 --- a/modules/mono/csharp_script.h +++ b/modules/mono/csharp_script.h @@ -293,6 +293,9 @@ public: void get_property_list(List<PropertyInfo> *p_properties) const override; Variant::Type get_property_type(const StringName &p_name, bool *r_is_valid) const override; + bool property_can_revert(const StringName &p_name) const override; + bool property_get_revert(const StringName &p_name, Variant &r_ret) const override; + void get_method_list(List<MethodInfo> *p_list) const override; bool has_method(const StringName &p_method) const override; Variant callp(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) override; @@ -371,6 +374,8 @@ class CSharpLanguage : public ScriptLanguage { StringName _set; StringName _get; StringName _get_property_list; + StringName _property_can_revert; + StringName _property_get_revert; StringName _notification; StringName _script_source; StringName dotctor; // .ctor diff --git a/modules/text_server_adv/text_server_adv.cpp b/modules/text_server_adv/text_server_adv.cpp index 73dbf2f443..c0cff08f13 100644 --- a/modules/text_server_adv/text_server_adv.cpp +++ b/modules/text_server_adv/text_server_adv.cpp @@ -1313,12 +1313,14 @@ _FORCE_INLINE_ bool TextServerAdvanced::_ensure_cache_for_size(FontAdvanced *p_f fargs.stream = &fd->stream; int max_index = 0; - FT_Face tmp_face; + FT_Face tmp_face = nullptr; error = FT_Open_Face(ft_library, &fargs, -1, &tmp_face); - if (error == 0) { + if (tmp_face && error == 0) { max_index = tmp_face->num_faces - 1; } - FT_Done_Face(tmp_face); + if (tmp_face) { + FT_Done_Face(tmp_face); + } error = FT_Open_Face(ft_library, &fargs, CLAMP(p_font_data->face_index, 0, max_index), &fd->face); if (error) { diff --git a/modules/text_server_fb/text_server_fb.cpp b/modules/text_server_fb/text_server_fb.cpp index 55d912a10a..3b91c6981e 100644 --- a/modules/text_server_fb/text_server_fb.cpp +++ b/modules/text_server_fb/text_server_fb.cpp @@ -733,12 +733,14 @@ _FORCE_INLINE_ bool TextServerFallback::_ensure_cache_for_size(FontFallback *p_f fargs.stream = &fd->stream; int max_index = 0; - FT_Face tmp_face; + FT_Face tmp_face = nullptr; error = FT_Open_Face(ft_library, &fargs, -1, &tmp_face); - if (error == 0) { + if (tmp_face && error == 0) { max_index = tmp_face->num_faces - 1; } - FT_Done_Face(tmp_face); + if (tmp_face) { + FT_Done_Face(tmp_face); + } error = FT_Open_Face(ft_library, &fargs, CLAMP(p_font_data->face_index, 0, max_index), &fd->face); if (error) { diff --git a/modules/visual_script/visual_script.h b/modules/visual_script/visual_script.h index 14cb14e8d9..d3a90d53fb 100644 --- a/modules/visual_script/visual_script.h +++ b/modules/visual_script/visual_script.h @@ -409,6 +409,9 @@ public: virtual void get_property_list(List<PropertyInfo> *p_properties) const; virtual Variant::Type get_property_type(const StringName &p_name, bool *r_is_valid = nullptr) const; + virtual bool property_can_revert(const StringName &p_name) const { return false; }; + virtual bool property_get_revert(const StringName &p_name, Variant &r_ret) const { return false; }; + virtual void get_method_list(List<MethodInfo> *p_list) const; virtual bool has_method(const StringName &p_method) const; virtual Variant callp(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error); |