From 6260bd1ed1f3b974cdb75eef90b02f2ba8161052 Mon Sep 17 00:00:00 2001 From: BruebachL <44814898+BruebachL@users.noreply.github.com> Date: Tue, 28 Jul 2026 02:47:23 +0200 Subject: [PATCH] [GameScene] Arrow Graphics destruction safety (#7062) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Took 13 minutes Co-authored-by: Lukas BrĂ¼bach --- cockatrice/src/game_graphics/game_scene.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/cockatrice/src/game_graphics/game_scene.cpp b/cockatrice/src/game_graphics/game_scene.cpp index d0a4f6798..58e6888c6 100644 --- a/cockatrice/src/game_graphics/game_scene.cpp +++ b/cockatrice/src/game_graphics/game_scene.cpp @@ -47,6 +47,17 @@ GameScene::~GameScene() { delete animationTimer; + // Delete all ArrowItems before QGraphicsScene's base destructor runs. + // QGraphicsScene::~QGraphicsScene() destroys items in arbitrary order. + // If a PlayerTarget is destroyed before an ArrowItem pointing to it, + // ArrowItem::onTargetDestroyed fires and emits on the partially-destroyed + // GameScene, causing a segfault. + for (auto *item : items()) { + if (auto *arrow = qgraphicsitem_cast(item)) { + delete arrow; + } + } + // DO NOT call clearViews() here // clearViews calls close() on the zoneViews, which sends signals; sending signals in destructors leads to segfaults // deleteLater() deletes the zoneView without allowing it to send signals @@ -530,7 +541,9 @@ void GameScene::clearArrowsForPlayer(int playerId) void GameScene::clearArrowsForPlayerLocally(int playerId) { for (int arrowId : arrowRegistry.idsForPlayer(playerId)) { - arrowRegistry.take(playerId, arrowId)->delArrow(); + if (auto *arrow = arrowRegistry.take(playerId, arrowId)) { + arrow->delArrow(); + } } }