diff options
-rw-r--r-- | doc/classes/RichTextLabel.xml | 2 | ||||
-rw-r--r-- | editor/plugins/sprite_frames_editor_plugin.cpp | 16 | ||||
-rw-r--r-- | methods.py | 3 | ||||
-rw-r--r-- | modules/gdscript/editor/gdscript_highlighter.cpp | 96 | ||||
-rw-r--r-- | modules/gdscript/editor/gdscript_highlighter.h | 1 | ||||
-rw-r--r-- | modules/visual_script/editor/visual_script_editor.cpp | 2 | ||||
-rw-r--r-- | scene/resources/syntax_highlighter.cpp | 48 | ||||
-rw-r--r-- | scene/resources/texture.cpp | 6 | ||||
-rw-r--r-- | servers/rendering/shader_language.cpp | 445 | ||||
-rw-r--r-- | servers/rendering/shader_language.h | 5 |
10 files changed, 232 insertions, 392 deletions
diff --git a/doc/classes/RichTextLabel.xml b/doc/classes/RichTextLabel.xml index c8ed373271..6f5135459f 100644 --- a/doc/classes/RichTextLabel.xml +++ b/doc/classes/RichTextLabel.xml @@ -420,7 +420,7 @@ </member> <member name="text" type="String" setter="set_text" getter="get_text" default=""""> The label's text in BBCode format. Is not representative of manual modifications to the internal tag stack. Erases changes made by other methods when edited. - [b]Note:[/b] If [member bbcode_enabled] is [code]true[/code], it is unadvised to use the [code]+=[/code] operator with [code]text[/code] (e.g. [code]text += "some string"[/code]) as it replaces the whole text and can cause slowdowns. Use [method append_text] for adding text instead, unless you absolutely need to close a tag that was opened in an earlier method call. + [b]Note:[/b] If [member bbcode_enabled] is [code]true[/code], it is unadvised to use the [code]+=[/code] operator with [code]text[/code] (e.g. [code]text += "some string"[/code]) as it replaces the whole text and can cause slowdowns. It will also erase all BBCode that was added to stack using [code]push_*[/code] methods. Use [method append_text] for adding text instead, unless you absolutely need to close a tag that was opened in an earlier method call. </member> <member name="text_direction" type="int" setter="set_text_direction" getter="get_text_direction" enum="Control.TextDirection" default="0"> Base text writing direction. diff --git a/editor/plugins/sprite_frames_editor_plugin.cpp b/editor/plugins/sprite_frames_editor_plugin.cpp index 2da4f80751..3350cec912 100644 --- a/editor/plugins/sprite_frames_editor_plugin.cpp +++ b/editor/plugins/sprite_frames_editor_plugin.cpp @@ -222,28 +222,14 @@ void SpriteFramesEditor::_sheet_add_frames() { int fc = frames->get_frame_count(edited_anim); - Point2 src_origin; - Rect2 src_region(Point2(), texture_size); - - AtlasTexture *src_atlas = Object::cast_to<AtlasTexture>(*split_sheet_preview->get_texture()); - if (src_atlas && src_atlas->get_atlas().is_valid()) { - src_origin = src_atlas->get_region().position - src_atlas->get_margin().position; - src_region = src_atlas->get_region(); - } - for (Set<int>::Element *E = frames_selected.front(); E; E = E->next()) { int idx = E->get(); Point2 frame_coords(idx % frame_count_x, idx / frame_count_x); - Rect2 frame(frame_coords * frame_size + src_origin, frame_size); - Rect2 region = frame.intersection(src_region); - Rect2 margin(region == Rect2() ? Point2() : region.position - frame.position, frame.size - region.size); - Ref<AtlasTexture> at; at.instantiate(); at->set_atlas(split_sheet_preview->get_texture()); - at->set_region(region); - at->set_margin(margin); + at->set_region(Rect2(frame_coords * frame_size, frame_size)); undo_redo->add_do_method(frames, "add_frame", edited_anim, at, -1); undo_redo->add_undo_method(frames, "remove_frame", edited_anim, fc); diff --git a/methods.py b/methods.py index 3331e159c7..86239e434c 100644 --- a/methods.py +++ b/methods.py @@ -780,9 +780,10 @@ def generate_vs_project(env, num_jobs): env.vs_incs.append(str(header)) module_configs = ModuleConfigs() - import modules.mono.build_scripts.mono_reg_utils as mono_reg if env.get("module_mono_enabled"): + import modules.mono.build_scripts.mono_reg_utils as mono_reg + mono_root = env.get("mono_prefix") or mono_reg.find_mono_root_dir(env["bits"]) if mono_root: module_configs.add_mode( diff --git a/modules/gdscript/editor/gdscript_highlighter.cpp b/modules/gdscript/editor/gdscript_highlighter.cpp index 6425123e63..5cc295bbab 100644 --- a/modules/gdscript/editor/gdscript_highlighter.cpp +++ b/modules/gdscript/editor/gdscript_highlighter.cpp @@ -60,7 +60,9 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l bool in_keyword = false; bool in_word = false; bool in_function_name = false; + bool in_lambda = false; bool in_variable_declaration = false; + bool in_signal_declaration = false; bool in_function_args = false; bool in_member_variable = false; bool in_node_path = false; @@ -105,12 +107,15 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l /* color regions */ if (is_a_symbol || in_region != -1) { int from = j; - for (; from < line_length; from++) { - if (str[from] == '\\') { - from++; - continue; + + if (in_region == -1) { + for (; from < line_length; from++) { + if (str[from] == '\\') { + from++; + continue; + } + break; } - break; } if (from != line_length) { @@ -142,6 +147,12 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l /* check if it's the whole line */ if (end_key_length == 0 || color_regions[c].line_only || from + end_key_length > line_length) { + if (from + end_key_length > line_length) { + // If it's key length and there is a '\', dont skip to highlight esc chars. + if (str.find("\\", from) >= 0) { + break; + } + } prev_color = color_regions[in_region].color; highlighter_info["color"] = color_regions[c].color; color_map[j] = highlighter_info; @@ -161,13 +172,25 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l /* if we are in one find the end key */ if (in_region != -1) { + Color region_color = color_regions[in_region].color; + if (in_node_path && (color_regions[in_region].start_key == "\"" || color_regions[in_region].start_key == "\'")) { + region_color = node_path_color; + } + + prev_color = region_color; + highlighter_info["color"] = region_color; + color_map[j] = highlighter_info; + /* search the line */ int region_end_index = -1; int end_key_length = color_regions[in_region].end_key.length(); const char32_t *end_key = color_regions[in_region].end_key.get_data(); for (; from < line_length; from++) { if (line_length - from < end_key_length) { - break; + // Don't break if '\' to highlight esc chars. + if (str.find("\\", from) < 0) { + break; + } } if (!is_symbol(str[from])) { @@ -175,7 +198,16 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l } if (str[from] == '\\') { + Dictionary escape_char_highlighter_info; + escape_char_highlighter_info["color"] = symbol_color; + color_map[from] = escape_char_highlighter_info; + from++; + + Dictionary region_continue_highlighter_info; + prev_color = region_color; + region_continue_highlighter_info["color"] = region_color; + color_map[from + 1] = region_continue_highlighter_info; continue; } @@ -192,10 +224,6 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l } } - prev_color = color_regions[in_region].color; - highlighter_info["color"] = color_regions[in_region].color; - color_map[j] = highlighter_info; - previous_type = REGION; previous_text = ""; previous_column = j; @@ -289,20 +317,36 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l } if (!in_function_name && in_word && !in_keyword) { - int k = j; - while (k < str.length() && !is_symbol(str[k]) && str[k] != '\t' && str[k] != ' ') { - k++; - } + if (previous_text == GDScriptTokenizer::get_token_name(GDScriptTokenizer::Token::SIGNAL)) { + in_signal_declaration = true; + } else { + int k = j; + while (k < str.length() && !is_symbol(str[k]) && str[k] != '\t' && str[k] != ' ') { + k++; + } - // check for space between name and bracket - while (k < str.length() && (str[k] == '\t' || str[k] == ' ')) { - k++; - } + // check for space between name and bracket + while (k < str.length() && (str[k] == '\t' || str[k] == ' ')) { + k++; + } - if (str[k] == '(') { - in_function_name = true; - } else if (previous_text == GDScriptTokenizer::get_token_name(GDScriptTokenizer::Token::VAR)) { - in_variable_declaration = true; + if (str[k] == '(') { + in_function_name = true; + } else if (previous_text == GDScriptTokenizer::get_token_name(GDScriptTokenizer::Token::VAR)) { + in_variable_declaration = true; + } + + // 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] == ' ')) { + k--; + } + + if (str[k] == ':') { + in_lambda = true; + } + } } } @@ -348,7 +392,9 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l } in_variable_declaration = false; + in_signal_declaration = false; in_function_name = false; + in_lambda = false; in_member_variable = false; } @@ -376,10 +422,14 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l } else if (in_member_variable) { next_type = MEMBER; color = member_color; + } else if (in_signal_declaration) { + next_type = SIGNAL; + + color = member_color; } else if (in_function_name) { next_type = FUNCTION; - if (previous_text == GDScriptTokenizer::get_token_name(GDScriptTokenizer::Token::FUNC)) { + if (!in_lambda && previous_text == GDScriptTokenizer::get_token_name(GDScriptTokenizer::Token::FUNC)) { color = function_definition_color; } else { color = function_color; diff --git a/modules/gdscript/editor/gdscript_highlighter.h b/modules/gdscript/editor/gdscript_highlighter.h index ac4995bee7..1ae0d72896 100644 --- a/modules/gdscript/editor/gdscript_highlighter.h +++ b/modules/gdscript/editor/gdscript_highlighter.h @@ -58,6 +58,7 @@ private: SYMBOL, NUMBER, FUNCTION, + SIGNAL, KEYWORD, MEMBER, IDENTIFIER, diff --git a/modules/visual_script/editor/visual_script_editor.cpp b/modules/visual_script/editor/visual_script_editor.cpp index 6676d08735..ec1a8a6b42 100644 --- a/modules/visual_script/editor/visual_script_editor.cpp +++ b/modules/visual_script/editor/visual_script_editor.cpp @@ -2661,7 +2661,7 @@ Ref<Texture2D> VisualScriptEditor::get_theme_icon() { } if (Control::has_theme_icon(icon_name, "EditorIcons")) { - return get_parent_control()->get_theme_icon(icon_name, "EditorIcons"); + return Control::get_theme_icon(icon_name, SNAME("EditorIcons")); } return Control::get_theme_icon(SNAME("VisualScript"), SNAME("EditorIcons")); diff --git a/scene/resources/syntax_highlighter.cpp b/scene/resources/syntax_highlighter.cpp index 2efda08e08..e0aa21ac37 100644 --- a/scene/resources/syntax_highlighter.cpp +++ b/scene/resources/syntax_highlighter.cpp @@ -171,12 +171,15 @@ Dictionary CodeHighlighter::_get_line_syntax_highlighting_impl(int p_line) { /* color regions */ if (is_a_symbol || in_region != -1) { int from = j; - for (; from < line_length; from++) { - if (str[from] == '\\') { - from++; - continue; + + if (in_region == -1) { + for (; from < line_length; from++) { + if (str[from] == '\\') { + from++; + continue; + } + break; } - break; } if (from != line_length) { @@ -208,6 +211,12 @@ Dictionary CodeHighlighter::_get_line_syntax_highlighting_impl(int p_line) { /* check if it's the whole line */ if (end_key_length == 0 || color_regions[c].line_only || from + end_key_length > line_length) { + if (from + end_key_length > line_length && (color_regions[in_region].start_key == "\"" || color_regions[in_region].start_key == "\'")) { + // If it's key length and there is a '\', dont skip to highlight esc chars. + if (str.find("\\", from) >= 0) { + break; + } + } prev_color = color_regions[in_region].color; highlighter_info["color"] = color_regions[c].color; color_map[j] = highlighter_info; @@ -227,13 +236,23 @@ Dictionary CodeHighlighter::_get_line_syntax_highlighting_impl(int p_line) { /* if we are in one find the end key */ if (in_region != -1) { + bool is_string = (color_regions[in_region].start_key == "\"" || color_regions[in_region].start_key == "\'"); + + Color region_color = color_regions[in_region].color; + prev_color = region_color; + highlighter_info["color"] = region_color; + color_map[j] = highlighter_info; + /* search the line */ int region_end_index = -1; int end_key_length = color_regions[in_region].end_key.length(); const char32_t *end_key = color_regions[in_region].end_key.get_data(); for (; from < line_length; from++) { if (line_length - from < end_key_length) { - break; + // Don't break if '\' to highlight esc chars. + if (!is_string || str.find("\\", from) < 0) { + break; + } } if (!is_symbol(str[from])) { @@ -241,7 +260,20 @@ Dictionary CodeHighlighter::_get_line_syntax_highlighting_impl(int p_line) { } if (str[from] == '\\') { + if (is_string) { + Dictionary escape_char_highlighter_info; + escape_char_highlighter_info["color"] = symbol_color; + color_map[from] = escape_char_highlighter_info; + } + from++; + + if (is_string) { + Dictionary region_continue_highlighter_info; + prev_color = region_color; + region_continue_highlighter_info["color"] = region_color; + color_map[from + 1] = region_continue_highlighter_info; + } continue; } @@ -258,10 +290,6 @@ Dictionary CodeHighlighter::_get_line_syntax_highlighting_impl(int p_line) { } } - prev_color = color_regions[in_region].color; - highlighter_info["color"] = color_regions[in_region].color; - color_map[j] = highlighter_info; - j = from + (end_key_length - 1); if (region_end_index == -1) { color_region_cache[p_line] = in_region; diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp index 28dc869c4f..331674d248 100644 --- a/scene/resources/texture.cpp +++ b/scene/resources/texture.cpp @@ -1156,7 +1156,7 @@ void AtlasTexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_m rc.size.height = atlas->get_height(); } - RS::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, Rect2(p_pos + margin.position, rc.size), atlas->get_rid(), rc, p_modulate, p_transpose, filter_clip); + atlas->draw_rect_region(p_canvas_item, Rect2(p_pos + margin.position, rc.size), rc, p_modulate, p_transpose, filter_clip); } void AtlasTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose) const { @@ -1177,7 +1177,7 @@ void AtlasTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile Vector2 scale = p_rect.size / (region.size + margin.size); Rect2 dr(p_rect.position + margin.position * scale, rc.size * scale); - RS::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, dr, atlas->get_rid(), rc, p_modulate, p_transpose, filter_clip); + atlas->draw_rect_region(p_canvas_item, dr, rc, p_modulate, p_transpose, filter_clip); } void AtlasTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, bool p_clip_uv) const { @@ -1190,7 +1190,7 @@ void AtlasTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, cons Rect2 src_c; get_rect_region(p_rect, p_src_rect, dr, src_c); - RS::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, dr, atlas->get_rid(), src_c, p_modulate, p_transpose, filter_clip); + atlas->draw_rect_region(p_canvas_item, dr, src_c, p_modulate, p_transpose, filter_clip); } bool AtlasTexture::get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, Rect2 &r_rect, Rect2 &r_src_rect) const { diff --git a/servers/rendering/shader_language.cpp b/servers/rendering/shader_language.cpp index a03ba9a02a..7641943fe9 100644 --- a/servers/rendering/shader_language.cpp +++ b/servers/rendering/shader_language.cpp @@ -4309,101 +4309,73 @@ bool ShaderLanguage::_propagate_function_call_sampler_builtin_reference(StringNa ERR_FAIL_V(false); //bug? function not found } -ShaderLanguage::Node *ShaderLanguage::_parse_array_size(BlockNode *p_block, const FunctionInfo &p_function_info, int &r_array_size) { - int array_size = 0; - - Node *n = _parse_and_reduce_expression(p_block, p_function_info); - if (n) { - if (n->type == Node::TYPE_VARIABLE) { - VariableNode *vn = static_cast<VariableNode *>(n); - if (vn) { - ConstantNode::Value v; - DataType data_type; - bool is_const = false; - - _find_identifier(p_block, false, p_function_info, vn->name, &data_type, nullptr, &is_const, nullptr, nullptr, &v); - - if (is_const) { - if (data_type == TYPE_INT) { - int32_t value = v.sint; - if (value > 0) { - array_size = value; - } - } else if (data_type == TYPE_UINT) { - uint32_t value = v.uint; - if (value > 0U) { - array_size = value; - } - } - } - } - } else if (n->type == Node::TYPE_OPERATOR) { - _set_error("Array size expressions are not yet implemented."); - return nullptr; - } - } - - r_array_size = array_size; - return n; -} - -Error ShaderLanguage::_parse_global_array_size(int &r_array_size, const FunctionInfo &p_function_info) { - if (r_array_size > 0) { - _set_error("Array size is already defined!"); - return ERR_PARSE_ERROR; +Error ShaderLanguage::_parse_array_size(BlockNode *p_block, const FunctionInfo &p_function_info, bool p_forbid_unknown_size, Node **r_size_expression, int *r_array_size, bool *r_unknown_size) { + bool error = false; + if (r_array_size != nullptr && *r_array_size > 0) { + error = true; } - TkPos pos = _get_tkpos(); - Token tk = _get_token(); - - int array_size = 0; - - if (!tk.is_integer_constant() || ((int)tk.constant) <= 0) { - _set_tkpos(pos); - Node *n = _parse_array_size(nullptr, p_function_info, array_size); - if (!n) { - return ERR_PARSE_ERROR; - } - } else if (((int)tk.constant) > 0) { - array_size = (uint32_t)tk.constant; + if (r_unknown_size != nullptr && *r_unknown_size) { + error = true; } - - if (array_size <= 0) { - _set_error("Expected single integer constant > 0"); - return ERR_PARSE_ERROR; - } - - tk = _get_token(); - if (tk.type != TK_BRACKET_CLOSE) { - _set_error("Expected ']'"); + if (error) { + _set_error("Array size is already defined!"); return ERR_PARSE_ERROR; } - r_array_size = array_size; - return OK; -} - -Error ShaderLanguage::_parse_local_array_size(BlockNode *p_block, const FunctionInfo &p_function_info, Node *&r_size_expression, int &r_array_size, bool &r_is_unknown_size) { TkPos pos = _get_tkpos(); Token tk = _get_token(); if (tk.type == TK_BRACKET_CLOSE) { - r_is_unknown_size = true; + if (p_forbid_unknown_size) { + _set_error("Unknown array size is forbidden in that context!"); + return ERR_PARSE_ERROR; + } + if (r_unknown_size != nullptr) { + *r_unknown_size = true; + } } else { - int size = 0; + int array_size = 0; + if (!tk.is_integer_constant() || ((int)tk.constant) <= 0) { _set_tkpos(pos); - int array_size = 0; - Node *n = _parse_array_size(p_block, p_function_info, array_size); - if (!n) { - return ERR_PARSE_ERROR; + Node *n = _parse_and_reduce_expression(p_block, p_function_info); + if (n) { + if (n->type == Node::TYPE_VARIABLE) { + VariableNode *vn = static_cast<VariableNode *>(n); + if (vn) { + ConstantNode::Value v; + DataType data_type; + bool is_const = false; + + _find_identifier(p_block, false, p_function_info, vn->name, &data_type, nullptr, &is_const, nullptr, nullptr, &v); + + if (is_const) { + if (data_type == TYPE_INT) { + int32_t value = v.sint; + if (value > 0) { + array_size = value; + } + } else if (data_type == TYPE_UINT) { + uint32_t value = v.uint; + if (value > 0U) { + array_size = value; + } + } + } + } + } else if (n->type == Node::TYPE_OPERATOR) { + _set_error("Array size expressions are not yet implemented."); + return ERR_PARSE_ERROR; + } + if (r_size_expression != nullptr) { + *r_size_expression = n; + } } - size = array_size; - r_size_expression = n; } else if (((int)tk.constant) > 0) { - size = (uint32_t)tk.constant; + array_size = (uint32_t)tk.constant; } - if (size <= 0) { + if (array_size <= 0) { _set_error("Expected single integer constant > 0"); return ERR_PARSE_ERROR; } @@ -4414,9 +4386,10 @@ Error ShaderLanguage::_parse_local_array_size(BlockNode *p_block, const Function return ERR_PARSE_ERROR; } - r_array_size = size; + if (r_array_size != nullptr) { + *r_array_size = array_size; + } } - return OK; } @@ -4443,40 +4416,11 @@ ShaderLanguage::Node *ShaderLanguage::_parse_array_constructor(BlockNode *p_bloc } tk = _get_token(); if (tk.type == TK_BRACKET_OPEN) { - TkPos pos = _get_tkpos(); - tk = _get_token(); - if (tk.type == TK_BRACKET_CLOSE) { - undefined_size = true; - tk = _get_token(); - } else { - _set_tkpos(pos); - - Node *n = _parse_and_reduce_expression(p_block, p_function_info); - if (!n || n->type != Node::TYPE_CONSTANT || n->get_datatype() != TYPE_INT) { - _set_error("Expected single integer constant > 0"); - return nullptr; - } - - ConstantNode *cnode = (ConstantNode *)n; - if (cnode->values.size() == 1) { - array_size = cnode->values[0].sint; - if (array_size <= 0) { - _set_error("Expected single integer constant > 0"); - return nullptr; - } - } else { - _set_error("Expected single integer constant > 0"); - return nullptr; - } - - tk = _get_token(); - if (tk.type != TK_BRACKET_CLOSE) { - _set_error("Expected ']'"); - return nullptr; - } else { - tk = _get_token(); - } + Error error = _parse_array_size(p_block, p_function_info, false, nullptr, &array_size, &undefined_size); + if (error != OK) { + return nullptr; } + tk = _get_token(); } else { _set_error("Expected '['"); return nullptr; @@ -4572,40 +4516,15 @@ ShaderLanguage::Node *ShaderLanguage::_parse_array_constructor(BlockNode *p_bloc } tk = _get_token(); if (tk.type == TK_BRACKET_OPEN) { - TkPos pos = _get_tkpos(); - tk = _get_token(); - if (tk.type == TK_BRACKET_CLOSE) { + bool is_unknown_size = false; + Error error = _parse_array_size(p_block, p_function_info, false, nullptr, &array_size, &is_unknown_size); + if (error != OK) { + return nullptr; + } + if (is_unknown_size) { array_size = p_array_size; - tk = _get_token(); - } else { - _set_tkpos(pos); - - Node *n = _parse_and_reduce_expression(p_block, p_function_info); - if (!n || n->type != Node::TYPE_CONSTANT || n->get_datatype() != TYPE_INT) { - _set_error("Expected single integer constant > 0"); - return nullptr; - } - - ConstantNode *cnode = (ConstantNode *)n; - if (cnode->values.size() == 1) { - array_size = cnode->values[0].sint; - if (array_size <= 0) { - _set_error("Expected single integer constant > 0"); - return nullptr; - } - } else { - _set_error("Expected single integer constant > 0"); - return nullptr; - } - - tk = _get_token(); - if (tk.type != TK_BRACKET_CLOSE) { - _set_error("Expected ']'"); - return nullptr; - } else { - tk = _get_token(); - } } + tk = _get_token(); } else { _set_error("Expected '['"); return nullptr; @@ -6532,7 +6451,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun } if (tk.type == TK_BRACKET_OPEN) { - Error error = _parse_local_array_size(p_block, p_function_info, size_expr, array_size, unknown_size); + Error error = _parse_array_size(p_block, p_function_info, false, &size_expr, &array_size, &unknown_size); if (error != OK) { return error; } @@ -6587,17 +6506,12 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun bool is_array_decl = var.array_size > 0 || unknown_size; if (tk.type == TK_BRACKET_OPEN) { - if (is_array_decl) { - _set_error("Array size is already defined!"); - return ERR_PARSE_ERROR; - } - if (RenderingServer::get_singleton()->is_low_end() && is_const) { _set_error("Local const arrays are supported only on high-end platform!"); return ERR_PARSE_ERROR; } - Error error = _parse_local_array_size(p_block, p_function_info, size_expr, var.array_size, unknown_size); + Error error = _parse_array_size(p_block, p_function_info, false, &size_expr, &var.array_size, &unknown_size); if (error != OK) { return error; } @@ -6702,40 +6616,15 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun tk = _get_token(); if (tk.type == TK_BRACKET_OPEN) { - TkPos pos2 = _get_tkpos(); - tk = _get_token(); - if (tk.type == TK_BRACKET_CLOSE) { + bool is_unknown_size = false; + Error error = _parse_array_size(p_block, p_function_info, false, nullptr, &array_size2, &is_unknown_size); + if (error != OK) { + return error; + } + if (is_unknown_size) { array_size2 = var.array_size; - tk = _get_token(); - } else { - _set_tkpos(pos2); - - Node *n = _parse_and_reduce_expression(p_block, p_function_info); - if (!n || n->type != Node::TYPE_CONSTANT || n->get_datatype() != TYPE_INT) { - _set_error("Expected single integer constant > 0"); - return ERR_PARSE_ERROR; - } - - ConstantNode *cnode = (ConstantNode *)n; - if (cnode->values.size() == 1) { - array_size2 = cnode->values[0].sint; - if (array_size2 <= 0) { - _set_error("Expected single integer constant > 0"); - return ERR_PARSE_ERROR; - } - } else { - _set_error("Expected single integer constant > 0"); - return ERR_PARSE_ERROR; - } - - tk = _get_token(); - if (tk.type != TK_BRACKET_CLOSE) { - _set_error("Expected ']'"); - return ERR_PARSE_ERROR; - } else { - tk = _get_token(); - } } + tk = _get_token(); } else { _set_error("Expected '['"); return ERR_PARSE_ERROR; @@ -7764,7 +7653,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct } if (tk.type == TK_BRACKET_OPEN) { - Error error = _parse_global_array_size(array_size, constants); + Error error = _parse_array_size(nullptr, constants, true, nullptr, &array_size, nullptr); if (error != OK) { return error; } @@ -7793,7 +7682,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct tk = _get_token(); if (tk.type == TK_BRACKET_OPEN) { - Error error = _parse_global_array_size(member->array_size, constants); + Error error = _parse_array_size(nullptr, constants, true, nullptr, &member->array_size, nullptr); if (error != OK) { return error; } @@ -7925,7 +7814,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct } if (tk.type == TK_BRACKET_OPEN) { - Error error = _parse_global_array_size(array_size, constants); + Error error = _parse_array_size(nullptr, constants, true, nullptr, &array_size, nullptr); if (error != OK) { return error; } @@ -7973,7 +7862,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct tk = _get_token(); if (tk.type == TK_BRACKET_OPEN) { - Error error = _parse_global_array_size(uniform2.array_size, constants); + Error error = _parse_array_size(nullptr, constants, true, nullptr, &uniform2.array_size, nullptr); if (error != OK) { return error; } @@ -8308,29 +8197,11 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct } if (tk.type == TK_BRACKET_OPEN) { - if (array_size > 0) { - _set_error("Array size is already defined!"); - return ERR_PARSE_ERROR; + Error error = _parse_array_size(nullptr, constants, true, nullptr, &varying.array_size, nullptr); + if (error != OK) { + return error; } tk = _get_token(); - if (tk.is_integer_constant() && tk.constant > 0) { - varying.array_size = (int)tk.constant; - - tk = _get_token(); - if (tk.type == TK_BRACKET_CLOSE) { - tk = _get_token(); - if (tk.type != TK_SEMICOLON) { - _set_error("Expected ';'"); - return ERR_PARSE_ERROR; - } - } else { - _set_error("Expected ']'"); - return ERR_PARSE_ERROR; - } - } else { - _set_error("Expected integer constant > 0"); - return ERR_PARSE_ERROR; - } } shader->varyings[name] = varying; @@ -8395,36 +8266,18 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct tk = _get_token(); bool unknown_size = false; + bool fixed_array_size = false; if (tk.type == TK_BRACKET_OPEN) { if (is_constant && RenderingServer::get_singleton()->is_low_end()) { _set_error("Global const arrays are only supported on high-end platform!"); return ERR_PARSE_ERROR; } - bool error = false; - tk = _get_token(); - - if (tk.is_integer_constant()) { - array_size = (int)tk.constant; - if (array_size > 0) { - tk = _get_token(); - if (tk.type != TK_BRACKET_CLOSE) { - _set_error("Expected ']'"); - return ERR_PARSE_ERROR; - } - } else { - error = true; - } - } else if (tk.type == TK_BRACKET_CLOSE) { - unknown_size = true; - } else { - error = true; - } - if (error) { - _set_error("Expected integer constant > 0 or ']'"); - return ERR_PARSE_ERROR; + Error error = _parse_array_size(nullptr, constants, !is_constant, nullptr, &array_size, &unknown_size); + if (error != OK) { + return error; } - + fixed_array_size = true; prev_pos = _get_tkpos(); } @@ -8454,7 +8307,6 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct } //variable - bool first = true; while (true) { ShaderNode::Constant constant; constant.name = name; @@ -8462,34 +8314,18 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct constant.type_str = struct_name; constant.precision = precision; constant.initializer = nullptr; - constant.array_size = (first ? array_size : 0); - first = false; + constant.array_size = array_size; if (tk.type == TK_BRACKET_OPEN) { if (RenderingServer::get_singleton()->is_low_end()) { _set_error("Global const arrays are only supported on high-end platform!"); return ERR_PARSE_ERROR; } - if (constant.array_size > 0 || unknown_size) { - _set_error("Array size is already defined!"); - return ERR_PARSE_ERROR; + Error error = _parse_array_size(nullptr, constants, false, nullptr, &constant.array_size, &unknown_size); + if (error != OK) { + return error; } tk = _get_token(); - if (tk.type == TK_BRACKET_CLOSE) { - unknown_size = true; - tk = _get_token(); - } else if (tk.is_integer_constant() && ((int)tk.constant) > 0) { - constant.array_size = (int)tk.constant; - tk = _get_token(); - if (tk.type != TK_BRACKET_CLOSE) { - _set_error("Expected ']'"); - return ERR_PARSE_ERROR; - } - tk = _get_token(); - } else { - _set_error("Expected integer constant > 0 or ']'"); - return ERR_PARSE_ERROR; - } } if (tk.type == TK_OP_ASSIGN) { @@ -8540,43 +8376,18 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct } int array_size2 = 0; - tk = _get_token(); + if (tk.type == TK_BRACKET_OPEN) { - prev_pos = _get_tkpos(); - tk = _get_token(); - if (tk.type == TK_BRACKET_CLOSE) { + bool is_unknown_size = false; + Error error = _parse_array_size(nullptr, constants, false, nullptr, &array_size2, &is_unknown_size); + if (error != OK) { + return error; + } + if (is_unknown_size) { array_size2 = constant.array_size; - tk = _get_token(); - } else { - _set_tkpos(prev_pos); - - Node *n = _parse_and_reduce_expression(nullptr, constants); - if (!n || n->type != Node::TYPE_CONSTANT || n->get_datatype() != TYPE_INT) { - _set_error("Expected single integer constant > 0"); - return ERR_PARSE_ERROR; - } - - ConstantNode *cnode = (ConstantNode *)n; - if (cnode->values.size() == 1) { - array_size2 = cnode->values[0].sint; - if (array_size2 <= 0) { - _set_error("Expected single integer constant > 0"); - return ERR_PARSE_ERROR; - } - } else { - _set_error("Expected single integer constant > 0"); - return ERR_PARSE_ERROR; - } - - tk = _get_token(); - if (tk.type != TK_BRACKET_CLOSE) { - _set_error("Expected ']"); - return ERR_PARSE_ERROR; - } else { - tk = _get_token(); - } } + tk = _get_token(); } else { _set_error("Expected '["); return ERR_PARSE_ERROR; @@ -8674,6 +8485,8 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct } } + array_size = constant.array_size; + ConstantNode *expr = memnew(ConstantNode); expr->datatype = constant.type; @@ -8746,6 +8559,11 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct tk = _get_token(); + if (!fixed_array_size) { + array_size = 0; + } + unknown_size = false; + } else if (tk.type == TK_SEMICOLON) { break; } else { @@ -8902,27 +8720,9 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct tk = _get_token(); if (tk.type == TK_BRACKET_OPEN) { - bool error = false; - tk = _get_token(); - - if (tk.is_integer_constant()) { - arg_array_size = (int)tk.constant; - - if (arg_array_size > 0) { - tk = _get_token(); - if (tk.type != TK_BRACKET_CLOSE) { - _set_error("Expected ']'"); - return ERR_PARSE_ERROR; - } - } else { - error = true; - } - } else { - error = true; - } - if (error) { - _set_error("Expected integer constant > 0"); - return ERR_PARSE_ERROR; + Error error = _parse_array_size(nullptr, constants, true, nullptr, &arg_array_size, nullptr); + if (error != OK) { + return error; } tk = _get_token(); } @@ -8960,32 +8760,9 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct tk = _get_token(); if (tk.type == TK_BRACKET_OPEN) { - if (arg_array_size > 0) { - _set_error("Array size is already defined!"); - return ERR_PARSE_ERROR; - } - bool error = false; - tk = _get_token(); - - if (tk.is_integer_constant()) { - arg_array_size = (int)tk.constant; - - if (arg_array_size > 0) { - tk = _get_token(); - if (tk.type != TK_BRACKET_CLOSE) { - _set_error("Expected ']'"); - return ERR_PARSE_ERROR; - } - } else { - error = true; - } - } else { - error = true; - } - - if (error) { - _set_error("Expected integer constant > 0"); - return ERR_PARSE_ERROR; + Error error = _parse_array_size(nullptr, constants, true, nullptr, &arg_array_size, nullptr); + if (error != OK) { + return error; } tk = _get_token(); } diff --git a/servers/rendering/shader_language.h b/servers/rendering/shader_language.h index bc6dae7fa2..74f97319fe 100644 --- a/servers/rendering/shader_language.h +++ b/servers/rendering/shader_language.h @@ -1045,11 +1045,8 @@ private: bool _validate_varying_assign(ShaderNode::Varying &p_varying, String *r_message); bool _check_node_constness(const Node *p_node) const; - Node *_parse_array_size(BlockNode *p_block, const FunctionInfo &p_function_info, int &r_array_size); - Error _parse_global_array_size(int &r_array_size, const FunctionInfo &p_function_info); - Error _parse_local_array_size(BlockNode *p_block, const FunctionInfo &p_function_info, Node *&r_size_expression, int &r_array_size, bool &r_is_unknown_size); - Node *_parse_expression(BlockNode *p_block, const FunctionInfo &p_function_info); + Error _parse_array_size(BlockNode *p_block, const FunctionInfo &p_function_info, bool p_forbid_unknown_size, Node **r_size_expression, int *r_array_size, bool *r_unknown_size); Node *_parse_array_constructor(BlockNode *p_block, const FunctionInfo &p_function_info); Node *_parse_array_constructor(BlockNode *p_block, const FunctionInfo &p_function_info, DataType p_type, const StringName &p_struct_name, int p_array_size); ShaderLanguage::Node *_reduce_expression(BlockNode *p_block, ShaderLanguage::Node *p_node); |