mirror of
https://github.com/godotengine/godot.git
synced 2024-11-10 14:12:51 +00:00
[RichTextLabel] Fix thread unsafe set_physics_process_internal
usage. Use WorkerThreadPool
instead of creating new threads.
This commit is contained in:
parent
551f5191e5
commit
0cc1f4240a
@ -4068,7 +4068,6 @@ void TextServerAdvanced::_realign(ShapedTextDataAdvanced *p_sd) const {
|
||||
|
||||
RID TextServerAdvanced::_shaped_text_substr(const RID &p_shaped, int64_t p_start, int64_t p_length) const {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
const ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
|
||||
ERR_FAIL_COND_V(!sd, RID());
|
||||
|
||||
@ -5513,6 +5512,7 @@ void TextServerAdvanced::_shape_run(ShapedTextDataAdvanced *p_sd, int64_t p_star
|
||||
}
|
||||
|
||||
bool TextServerAdvanced::_shaped_text_shape(const RID &p_shaped) {
|
||||
_THREAD_SAFE_METHOD_
|
||||
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
|
||||
ERR_FAIL_COND_V(!sd, false);
|
||||
|
||||
@ -6569,6 +6569,7 @@ TextServerAdvanced::TextServerAdvanced() {
|
||||
}
|
||||
|
||||
void TextServerAdvanced::_cleanup() {
|
||||
_THREAD_SAFE_METHOD_
|
||||
for (const KeyValue<SystemFontKey, SystemFontCache> &E : system_fonts) {
|
||||
const Vector<SystemFontCacheRec> &sysf_cache = E.value.var;
|
||||
for (const SystemFontCacheRec &F : sysf_cache) {
|
||||
|
@ -1797,7 +1797,9 @@ void RichTextLabel::_notification(int p_what) {
|
||||
} break;
|
||||
|
||||
case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
|
||||
queue_redraw();
|
||||
if (is_visible_in_tree()) {
|
||||
queue_redraw();
|
||||
}
|
||||
} break;
|
||||
|
||||
case NOTIFICATION_DRAW: {
|
||||
@ -2665,19 +2667,26 @@ bool RichTextLabel::_find_layout_subitem(Item *from, Item *to) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void RichTextLabel::_thread_function(void *self) {
|
||||
RichTextLabel *rtl = reinterpret_cast<RichTextLabel *>(self);
|
||||
rtl->set_physics_process_internal(true);
|
||||
rtl->_process_line_caches();
|
||||
rtl->set_physics_process_internal(false);
|
||||
rtl->updating.store(false);
|
||||
rtl->call_deferred(SNAME("queue_redraw"));
|
||||
void RichTextLabel::_thread_function(void *p_userdata) {
|
||||
_process_line_caches();
|
||||
updating.store(false);
|
||||
call_deferred(SNAME("thread_end"));
|
||||
}
|
||||
|
||||
void RichTextLabel::_thread_end() {
|
||||
set_physics_process_internal(false);
|
||||
if (is_visible_in_tree()) {
|
||||
queue_redraw();
|
||||
}
|
||||
}
|
||||
|
||||
void RichTextLabel::_stop_thread() {
|
||||
if (threaded) {
|
||||
stop_thread.store(true);
|
||||
thread.wait_to_finish();
|
||||
if (task != WorkerThreadPool::INVALID_TASK_ID) {
|
||||
WorkerThreadPool::get_singleton()->wait_for_task_completion(task);
|
||||
task = WorkerThreadPool::INVALID_TASK_ID;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2787,7 +2796,8 @@ bool RichTextLabel::_validate_line_caches() {
|
||||
if (threaded) {
|
||||
updating.store(true);
|
||||
loaded.store(true);
|
||||
thread.start(RichTextLabel::_thread_function, reinterpret_cast<void *>(this));
|
||||
task = WorkerThreadPool::get_singleton()->add_template_task(this, &RichTextLabel::_thread_function, nullptr, true, vformat("RichTextLabelShape:%x", (int64_t)get_instance_id()));
|
||||
set_physics_process_internal(true);
|
||||
loading_started = OS::get_singleton()->get_ticks_msec();
|
||||
return false;
|
||||
} else {
|
||||
@ -5457,6 +5467,8 @@ void RichTextLabel::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("get_menu"), &RichTextLabel::get_menu);
|
||||
ClassDB::bind_method(D_METHOD("is_menu_visible"), &RichTextLabel::is_menu_visible);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("_thread_end"), &RichTextLabel::_thread_end);
|
||||
|
||||
// Note: set "bbcode_enabled" first, to avoid unnecessary "text" resets.
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "bbcode_enabled"), "set_use_bbcode", "is_using_bbcode");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::STRING, "text", PROPERTY_HINT_MULTILINE_TEXT), "set_text", "get_text");
|
||||
|
@ -31,6 +31,7 @@
|
||||
#ifndef RICH_TEXT_LABEL_H
|
||||
#define RICH_TEXT_LABEL_H
|
||||
|
||||
#include "core/object/worker_thread_pool.h"
|
||||
#include "rich_text_effect.h"
|
||||
#include "scene/gui/popup_menu.h"
|
||||
#include "scene/gui/scroll_bar.h"
|
||||
@ -369,7 +370,7 @@ private:
|
||||
Item *current = nullptr;
|
||||
ItemFrame *current_frame = nullptr;
|
||||
|
||||
Thread thread;
|
||||
WorkerThreadPool::TaskID task = WorkerThreadPool::INVALID_TASK_ID;
|
||||
Mutex data_mutex;
|
||||
bool threaded = false;
|
||||
std::atomic<bool> stop_thread;
|
||||
@ -409,7 +410,8 @@ private:
|
||||
|
||||
void _invalidate_current_line(ItemFrame *p_frame);
|
||||
|
||||
static void _thread_function(void *self);
|
||||
void _thread_function(void *p_userdata);
|
||||
void _thread_end();
|
||||
void _stop_thread();
|
||||
bool _validate_line_caches();
|
||||
void _process_line_caches();
|
||||
|
Loading…
Reference in New Issue
Block a user