diff --git a/scene/gui/rich_text_effect.cpp b/scene/gui/rich_text_effect.cpp index 67fa85b8321..e0bb3ae219a 100644 --- a/scene/gui/rich_text_effect.cpp +++ b/scene/gui/rich_text_effect.cpp @@ -120,3 +120,7 @@ CharFXTransform::CharFXTransform() { color = Color(); character = 0; } + +CharFXTransform::~CharFXTransform() { + environment.clear(); +} diff --git a/scene/gui/rich_text_effect.h b/scene/gui/rich_text_effect.h index f9c3e153990..4330cebfe62 100644 --- a/scene/gui/rich_text_effect.h +++ b/scene/gui/rich_text_effect.h @@ -64,6 +64,8 @@ public: Dictionary environment; CharFXTransform(); + ~CharFXTransform(); + uint64_t get_relative_index() { return relative_index; } void set_relative_index(uint64_t p_index) { relative_index = p_index; } uint64_t get_absolute_index() { return absolute_index; } diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index d9ae42d6e63..c5330c78e19 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -348,6 +348,7 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int & int it_char_start = p_char_count; Vector fx_stack = Vector(); + _fetch_item_fx_stack(text, fx_stack); bool custom_fx_ok = true; if (p_mode == PROCESS_DRAW) { @@ -359,8 +360,14 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int & strikethrough = true; } - fade = _fetch_by_type(text, ITEM_FADE); - _fetch_item_stack(text, fx_stack); + Item *fade_item = it; + while (fade_item) { + if (fade_item->type == ITEM_FADE) { + fade = static_cast(fade_item); + break; + } + fade_item = fade_item->parent; + } } else if (p_mode == PROCESS_CACHE) { l.char_count += text->text.length(); @@ -467,18 +474,16 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int & faded_visibility > 0.0f); for (int j = 0; j < fx_stack.size(); j++) { - ItemCustomFX *item_custom = Object::cast_to(fx_stack[j]); - ItemShake *item_shake = Object::cast_to(fx_stack[j]); - ItemWave *item_wave = Object::cast_to(fx_stack[j]); - ItemTornado *item_tornado = Object::cast_to(fx_stack[j]); - ItemRainbow *item_rainbow = Object::cast_to(fx_stack[j]); + ItemFX *item_fx = fx_stack[j]; + + if (item_fx->type == ITEM_CUSTOMFX && custom_fx_ok) { + ItemCustomFX *item_custom = static_cast(item_fx); + + Ref charfx = item_custom->char_fx_transform; + Ref custom_effect = item_custom->custom_effect; - if (item_custom && custom_fx_ok) { - Ref charfx = Ref(memnew(CharFXTransform)); - Ref custom_effect = _get_custom_effect_by_code(item_custom->identifier); if (!custom_effect.is_null()) { charfx->elapsed_time = item_custom->elapsed_time; - charfx->environment = item_custom->environment; charfx->relative_index = c_item_offset; charfx->absolute_index = p_char_count; charfx->visibility = visible; @@ -494,7 +499,9 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int & visible &= charfx->visibility; fx_char = charfx->character; } - } else if (item_shake) { + } else if (item_fx->type == ITEM_SHAKE) { + ItemShake *item_shake = static_cast(item_fx); + uint64_t char_current_rand = item_shake->offset_random(c_item_offset); uint64_t char_previous_rand = item_shake->offset_previous_random(c_item_offset); uint64_t max_rand = 2147483647; @@ -509,14 +516,20 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int & Math::cos(current_offset), n_time)) * (float)item_shake->strength / 10.0f; - } else if (item_wave) { + } else if (item_fx->type == ITEM_WAVE) { + ItemWave *item_wave = static_cast(item_fx); + double value = Math::sin(item_wave->frequency * item_wave->elapsed_time + ((p_ofs.x + pofs) / 50)) * (item_wave->amplitude / 10.0f); fx_offset += Point2(0, 1) * value; - } else if (item_tornado) { + } else if (item_fx->type == ITEM_TORNADO) { + ItemTornado *item_tornado = static_cast(item_fx); + double torn_x = Math::sin(item_tornado->frequency * item_tornado->elapsed_time + ((p_ofs.x + pofs) / 50)) * (item_tornado->radius); double torn_y = Math::cos(item_tornado->frequency * item_tornado->elapsed_time + ((p_ofs.x + pofs) / 50)) * (item_tornado->radius); fx_offset += Point2(torn_x, torn_y); - } else if (item_rainbow) { + } else if (item_fx->type == ITEM_RAINBOW) { + ItemRainbow *item_rainbow = static_cast(item_fx); + fx_color = fx_color.from_hsv(item_rainbow->frequency * (item_rainbow->elapsed_time + ((p_ofs.x + pofs) / 50)), item_rainbow->saturation, item_rainbow->value, @@ -884,7 +897,11 @@ void RichTextLabel::_update_scroll() { void RichTextLabel::_update_fx(RichTextLabel::ItemFrame *p_frame, float p_delta_time) { Item *it = p_frame; while (it) { - ItemFX *ifx = Object::cast_to(it); + ItemFX *ifx = NULL; + + if (it->type == ITEM_CUSTOMFX || it->type == ITEM_SHAKE || it->type == ITEM_WAVE || it->type == ITEM_TORNADO || it->type == ITEM_RAINBOW) { + ifx = static_cast(it); + } if (!ifx) { it = _get_next_item(it, true); @@ -893,7 +910,12 @@ void RichTextLabel::_update_fx(RichTextLabel::ItemFrame *p_frame, float p_delta_ ifx->elapsed_time += p_delta_time; - ItemShake *shake = Object::cast_to(it); + ItemShake *shake = NULL; + + if (it->type == ITEM_SHAKE) { + shake = static_cast(it); + } + if (shake) { bool cycle = (shake->elapsed_time > (1.0f / shake->rate)); if (cycle) { @@ -983,9 +1005,6 @@ void RichTextLabel::_notification(int p_what) { case NOTIFICATION_INTERNAL_PROCESS: { float dt = get_process_delta_time(); - for (int i = 0; i < custom_effects.size(); i++) { - } - _update_fx(main, dt); update(); } @@ -1408,6 +1427,17 @@ bool RichTextLabel::_find_by_type(Item *p_item, ItemType p_type) { return false; } +void RichTextLabel::_fetch_item_fx_stack(Item *p_item, Vector &r_stack) { + Item *item = p_item; + while (item) { + if (item->type == ITEM_CUSTOMFX || item->type == ITEM_SHAKE || item->type == ITEM_WAVE || item->type == ITEM_TORNADO || item->type == ITEM_RAINBOW) { + r_stack.push_back(static_cast(item)); + } + + item = item->parent; + } +} + bool RichTextLabel::_find_meta(Item *p_item, Variant *r_meta, ItemMeta **r_item) { Item *item = p_item; @@ -1776,10 +1806,10 @@ void RichTextLabel::push_rainbow(float p_saturation, float p_value, float p_freq _add_item(item, true); } -void RichTextLabel::push_customfx(String p_identifier, Dictionary p_environment) { +void RichTextLabel::push_customfx(Ref p_custom_effect, Dictionary p_environment) { ItemCustomFX *item = memnew(ItemCustomFX); - item->identifier = p_identifier; - item->environment = p_environment; + item->custom_effect = p_custom_effect; + item->char_fx_transform->environment = p_environment; _add_item(item, true); } @@ -2287,7 +2317,7 @@ Error RichTextLabel::append_bbcode(const String &p_bbcode) { Ref effect = _get_custom_effect_by_code(identifier); if (!effect.is_null()) { - push_customfx(identifier, properties); + push_customfx(effect, properties); pos = brk_end + 1; tag_stack.push_front(identifier); set_process_internal(true); @@ -2700,17 +2730,16 @@ Size2 RichTextLabel::get_minimum_size() const { } Ref RichTextLabel::_get_custom_effect_by_code(String p_bbcode_identifier) { - Ref r; for (int i = 0; i < custom_effects.size(); i++) { if (!custom_effects[i].is_valid()) continue; if (custom_effects[i]->get_bbcode() == p_bbcode_identifier) { - r = custom_effects[i]; + return custom_effects[i]; } } - return r; + return Ref(); } Dictionary RichTextLabel::parse_expressions_for_values(Vector p_expressions) { diff --git a/scene/gui/rich_text_label.h b/scene/gui/rich_text_label.h index 481f8d9746c..1c90d974e4d 100644 --- a/scene/gui/rich_text_label.h +++ b/scene/gui/rich_text_label.h @@ -81,7 +81,7 @@ protected: static void _bind_methods(); private: - class Item; + struct Item; struct Line { @@ -103,10 +103,7 @@ private: } }; - class Item : public Object { - GDCLASS(Item, Object); - - public: + struct Item { int index; Item *parent; ItemType type; @@ -129,10 +126,7 @@ private: virtual ~Item() { _clear_children(); } }; - class ItemFrame : public Item { - GDCLASS(ItemFrame, Item); - - public: + struct ItemFrame : public Item { int parent_line; bool cell; Vector lines; @@ -147,95 +141,59 @@ private: } }; - class ItemText : public Item { - GDCLASS(ItemText, Item); - - public: + struct ItemText : public Item { String text; ItemText() { type = ITEM_TEXT; } }; - class ItemImage : public Item { - GDCLASS(ItemImage, Item); - - public: + struct ItemImage : public Item { Ref image; ItemImage() { type = ITEM_IMAGE; } }; - class ItemFont : public Item { - GDCLASS(ItemFont, Item); - - public: + struct ItemFont : public Item { Ref font; ItemFont() { type = ITEM_FONT; } }; - class ItemColor : public Item { - GDCLASS(ItemColor, Item); - - public: + struct ItemColor : public Item { Color color; ItemColor() { type = ITEM_COLOR; } }; - class ItemUnderline : public Item { - GDCLASS(ItemUnderline, Item); - - public: + struct ItemUnderline : public Item { ItemUnderline() { type = ITEM_UNDERLINE; } }; - class ItemStrikethrough : public Item { - GDCLASS(ItemStrikethrough, Item); - - public: + struct ItemStrikethrough : public Item { ItemStrikethrough() { type = ITEM_STRIKETHROUGH; } }; - class ItemMeta : public Item { - GDCLASS(ItemMeta, Item); - - public: + struct ItemMeta : public Item { Variant meta; ItemMeta() { type = ITEM_META; } }; - class ItemAlign : public Item { - GDCLASS(ItemAlign, Item); - - public: + struct ItemAlign : public Item { Align align; ItemAlign() { type = ITEM_ALIGN; } }; - class ItemIndent : public Item { - GDCLASS(ItemIndent, Item); - - public: + struct ItemIndent : public Item { int level; ItemIndent() { type = ITEM_INDENT; } }; - class ItemList : public Item { - GDCLASS(ItemList, Item); - - public: + struct ItemList : public Item { ListType list_type; ItemList() { type = ITEM_LIST; } }; - class ItemNewline : public Item { - GDCLASS(ItemNewline, Item); - - public: + struct ItemNewline : public Item { ItemNewline() { type = ITEM_NEWLINE; } }; - class ItemTable : public Item { - GDCLASS(ItemTable, Item); - - public: + struct ItemTable : public Item { struct Column { bool expand; int expand_ratio; @@ -249,20 +207,14 @@ private: ItemTable() { type = ITEM_TABLE; } }; - class ItemFade : public Item { - GDCLASS(ItemFade, Item); - - public: + struct ItemFade : public Item { int starting_index; int length; ItemFade() { type = ITEM_FADE; } }; - class ItemFX : public Item { - GDCLASS(ItemFX, Item); - - public: + struct ItemFX : public Item { float elapsed_time; ItemFX() { @@ -270,10 +222,7 @@ private: } }; - class ItemShake : public ItemFX { - GDCLASS(ItemShake, ItemFX); - - public: + struct ItemShake : public ItemFX { int strength; float rate; uint64_t _current_rng; @@ -302,10 +251,7 @@ private: } }; - class ItemWave : public ItemFX { - GDCLASS(ItemWave, ItemFX); - - public: + struct ItemWave : public ItemFX { float frequency; float amplitude; @@ -316,10 +262,7 @@ private: } }; - class ItemTornado : public ItemFX { - GDCLASS(ItemTornado, ItemFX); - - public: + struct ItemTornado : public ItemFX { float radius; float frequency; @@ -330,10 +273,7 @@ private: } }; - class ItemRainbow : public ItemFX { - GDCLASS(ItemRainbow, ItemFX); - - public: + struct ItemRainbow : public ItemFX { float saturation; float value; float frequency; @@ -346,22 +286,21 @@ private: } }; - class ItemCustomFX : public ItemFX { - GDCLASS(ItemCustomFX, ItemFX); - - public: - String identifier; - Dictionary environment; + struct ItemCustomFX : public ItemFX { + Ref char_fx_transform; + Ref custom_effect; ItemCustomFX() { - identifier = ""; - environment = Dictionary(); type = ITEM_CUSTOMFX; + + char_fx_transform.instance(); } virtual ~ItemCustomFX() { _clear_children(); - environment.clear(); + + char_fx_transform.unref(); + custom_effect.unref(); } }; @@ -440,32 +379,7 @@ private: bool _find_meta(Item *p_item, Variant *r_meta, ItemMeta **r_item = NULL); bool _find_layout_subitem(Item *from, Item *to); bool _find_by_type(Item *p_item, ItemType p_type); - template - T *_fetch_by_type(Item *p_item, ItemType p_type) { - Item *item = p_item; - T *result = NULL; - while (item) { - if (item->type == p_type) { - result = Object::cast_to(item); - if (result) - return result; - } - item = item->parent; - } - - return result; - }; - template - void _fetch_item_stack(Item *p_item, Vector &r_stack) { - Item *item = p_item; - while (item) { - T *found = Object::cast_to(item); - if (found) { - r_stack.push_back(found); - } - item = item->parent; - } - } + void _fetch_item_fx_stack(Item *p_item, Vector &r_stack); void _update_scroll(); void _update_fx(ItemFrame *p_frame, float p_delta_time); @@ -509,7 +423,7 @@ public: void push_wave(float p_frequency, float p_amplitude); void push_tornado(float p_frequency, float p_radius); void push_rainbow(float p_saturation, float p_value, float p_frequency); - void push_customfx(String p_identifier, Dictionary p_environment); + void push_customfx(Ref p_custom_effect, Dictionary p_environment); void set_table_column_expand(int p_column, bool p_expand, int p_ratio = 1); int get_current_table_column() const; void push_cell();