From ce69c84f8a8a0dfefdb88529ed92d9ef01758f02 Mon Sep 17 00:00:00 2001 From: brige Date: Wed, 12 Nov 2025 23:22:27 +0800 Subject: [PATCH] fix crash of closing --- src/app/Application.cpp | 4 ++++ src/entities/EntitiesManager.cpp | 3 ++- src/scene/OEScene.cpp | 17 +++++++++++++++++ src/viewer/OsgWidget.cpp | 17 ++++++++++++----- src/workspace/WorkSpaceManager.cpp | 10 ++++++++++ 5 files changed, 45 insertions(+), 6 deletions(-) diff --git a/src/app/Application.cpp b/src/app/Application.cpp index 887fe11d..12b026e3 100644 --- a/src/app/Application.cpp +++ b/src/app/Application.cpp @@ -48,6 +48,10 @@ void Application::OnTimeout() { } void Application::Uninit() { + // Stop the app-level frame timer to prevent callbacks during teardown + if (timer_.isActive()) { + timer_.stop(); + } //Singleton::Destory(); Singleton::Destory(); Singleton::Destory(); diff --git a/src/entities/EntitiesManager.cpp b/src/entities/EntitiesManager.cpp index 8e3d08fe..58ca9916 100644 --- a/src/entities/EntitiesManager.cpp +++ b/src/entities/EntitiesManager.cpp @@ -32,7 +32,8 @@ void EntitiesManager::OnDestory() { ); for (auto* entity : entities) { RemoveEntity(entity); - entity->deleteLater(); + // Delete entities immediately to release scene graph resources before exit + delete entity; } } diff --git a/src/scene/OEScene.cpp b/src/scene/OEScene.cpp index 2c595a4e..6b04f3fc 100644 --- a/src/scene/OEScene.cpp +++ b/src/scene/OEScene.cpp @@ -55,7 +55,24 @@ void OEScene::AttachView(osgViewer::View* view) { } void OEScene::DetachView(osgViewer::View* view) { + if (!view) return; + + // Remove sky dome from this group if present; SkyNode has no detach in osgEarth 2.8 + if (skyDome_.valid()) { + removeChild(skyDome_.get()); + skyDome_ = nullptr; + } + + // Clear scene data view->setSceneData(nullptr); + + // Clear manipulator association + if (earthManipulator_.valid()) { + view->setCameraManipulator(nullptr); + } + + // Clear internal view pointer + curentView_ = nullptr; } bool OEScene::AddToScene(osg::Node* node) const { diff --git a/src/viewer/OsgWidget.cpp b/src/viewer/OsgWidget.cpp index 201efaa9..1200f786 100644 --- a/src/viewer/OsgWidget.cpp +++ b/src/viewer/OsgWidget.cpp @@ -1,4 +1,4 @@ -#include "viewer/OsgWidget.h" +#include "viewer/OsgWidget.h" #include @@ -69,13 +69,20 @@ OsgWidget::OsgWidget(QWidget* parent, Qt::WindowFlags f) OsgWidget::~OsgWidget() { LOG_INFO("OsgWidget::~OsgWidget"); + // Stop periodic updates to prevent callbacks during teardown + if (timer_.isActive()) { + timer_.stop(); + } + + // First unload the workspace while scene/view are still valid, + // so entities can detach cleanly from the scene graph if (nullptr != workspace_) { workspace_->Unlaod(); + workspace_ = nullptr; } - if (nullptr != viewUI_) { - viewUI_->RemoveUI(activeScene_->GetOrCreateSceneUI()); - viewUI_ = nullptr; - } + + // Then perform the viewer teardown (detach UI, view, and scene) + Uninitialize(); } void OsgWidget::Initialize() { diff --git a/src/workspace/WorkSpaceManager.cpp b/src/workspace/WorkSpaceManager.cpp index 4191ffa2..4362aae4 100644 --- a/src/workspace/WorkSpaceManager.cpp +++ b/src/workspace/WorkSpaceManager.cpp @@ -21,6 +21,16 @@ WorkSpaceManager::~WorkSpaceManager() { void WorkSpaceManager::OnDestory() { SaveDefaultWorkspace(); + for (auto& kv : workSpaces_) { + WorkSpace* ws = kv.second; + if (ws) { + ws->Unlaod(); + ws->deleteLater(); + } + } + workSpaces_.clear(); + + scene_ = nullptr; } WorkSpace* WorkSpaceManager::LoadDefaultWorkspace(class OEScene* secen) {