Merge pull request #88916 from AThousandShips/tile_thread_fix_4_2
[4.2] Prevent threading problems in `TileMap`
This commit is contained in:
commit
2fdeeead5b
|
@ -5,7 +5,7 @@
|
|||
</brief_description>
|
||||
<description>
|
||||
Node for 2D tile-based maps. Tilemaps use a [TileSet] which contain a list of tiles which are used to create grid-based maps. A TileMap may have several layers, layouting tiles on top of each other.
|
||||
For performance reasons, all TileMap updates are batched at the end of a frame. Notably, this means that scene tiles from a [TileSetScenesCollectionSource] may be initialized after their parent.
|
||||
For performance reasons, all TileMap updates are batched at the end of a frame. Notably, this means that scene tiles from a [TileSetScenesCollectionSource] may be initialized after their parent. This is only queued when inside the scene tree.
|
||||
To force an update earlier on, call [method update_internals].
|
||||
</description>
|
||||
<tutorials>
|
||||
|
|
|
@ -68,9 +68,6 @@ void TilesEditorUtils::_thread_func(void *ud) {
|
|||
}
|
||||
|
||||
void TilesEditorUtils::_thread() {
|
||||
CallQueue queue;
|
||||
MessageQueue::set_thread_singleton_override(&queue);
|
||||
|
||||
pattern_thread_exited.clear();
|
||||
while (!pattern_thread_exit.is_set()) {
|
||||
pattern_preview_sem.wait();
|
||||
|
@ -130,8 +127,6 @@ void TilesEditorUtils::_thread() {
|
|||
// Add the viewport at the last moment to avoid rendering too early.
|
||||
EditorNode::get_singleton()->call_deferred("add_child", viewport);
|
||||
|
||||
MessageQueue::get_singleton()->flush();
|
||||
|
||||
RS::get_singleton()->connect(SNAME("frame_pre_draw"), callable_mp(const_cast<TilesEditorUtils *>(this), &TilesEditorUtils::_preview_frame_started), Object::CONNECT_ONE_SHOT);
|
||||
|
||||
pattern_preview_done.wait();
|
||||
|
@ -144,11 +139,7 @@ void TilesEditorUtils::_thread() {
|
|||
viewport->queue_free();
|
||||
}
|
||||
}
|
||||
|
||||
MessageQueue::get_singleton()->flush();
|
||||
}
|
||||
|
||||
MessageQueue::get_singleton()->flush();
|
||||
pattern_thread_exited.set();
|
||||
}
|
||||
|
||||
|
|
|
@ -3023,6 +3023,8 @@ void TileMap::_notification(int p_what) {
|
|||
for (Ref<TileMapLayer> &layer : layers) {
|
||||
layer->notify_tile_map_change(TileMapLayer::DIRTY_FLAGS_TILE_MAP_IN_TREE);
|
||||
}
|
||||
// Update on exit to prevent threading problems.
|
||||
_internal_update();
|
||||
} break;
|
||||
|
||||
case TileMap::NOTIFICATION_ENTER_CANVAS: {
|
||||
|
@ -3035,6 +3037,8 @@ void TileMap::_notification(int p_what) {
|
|||
for (Ref<TileMapLayer> &layer : layers) {
|
||||
layer->notify_tile_map_change(TileMapLayer::DIRTY_FLAGS_TILE_MAP_IN_CANVAS);
|
||||
}
|
||||
// Update on exit to prevent threading problems.
|
||||
_internal_update();
|
||||
} break;
|
||||
|
||||
case NOTIFICATION_DRAW: {
|
||||
|
@ -3109,9 +3113,12 @@ void TileMap::queue_internal_update() {
|
|||
if (pending_update) {
|
||||
return;
|
||||
}
|
||||
// Don't update when outside the tree, it doesn't do anything useful, and causes threading problems.
|
||||
if (is_inside_tree()) {
|
||||
pending_update = true;
|
||||
callable_mp(this, &TileMap::_internal_update).call_deferred();
|
||||
}
|
||||
}
|
||||
|
||||
void TileMap::_internal_update() {
|
||||
// Other updates.
|
||||
|
|
Loading…
Reference in New Issue