mirror of
https://github.com/zhenyan121/SporeBG-Conid.git
synced 2026-04-10 06:14:08 +08:00
feat: add delayed scene destruction to prevent null references
This commit is contained in:
@@ -102,5 +102,10 @@ void GameApplication::run() {
|
|||||||
m_windowManager->endUI();
|
m_windowManager->endUI();
|
||||||
|
|
||||||
m_windowManager->Present();
|
m_windowManager->Present();
|
||||||
|
cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GameApplication::cleanup() {
|
||||||
|
m_sceneManager->destoryQuitedScene();
|
||||||
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ private:
|
|||||||
std::unique_ptr<UIRenderer> m_uiRenderer;
|
std::unique_ptr<UIRenderer> m_uiRenderer;
|
||||||
std::unique_ptr<DebugManager> m_debugManager;
|
std::unique_ptr<DebugManager> m_debugManager;
|
||||||
Config m_config;
|
Config m_config;
|
||||||
|
void cleanup();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GameApplication();
|
GameApplication();
|
||||||
|
|||||||
@@ -150,6 +150,7 @@ void SceneManager::changeScene(const std::string& sceneName) {
|
|||||||
// 退出当前场景
|
// 退出当前场景
|
||||||
if (m_scene) {
|
if (m_scene) {
|
||||||
m_scene->onExit();
|
m_scene->onExit();
|
||||||
|
m_quitedScene = m_scene;
|
||||||
}
|
}
|
||||||
// 切换到目标场景
|
// 切换到目标场景
|
||||||
m_scene = target;
|
m_scene = target;
|
||||||
@@ -205,4 +206,14 @@ void SceneManager::handleSceneEvent(const SceneEvent& event) {
|
|||||||
SDL_Log("SceneManager::handleSceneEvent: Unhandled event type!\n");
|
SDL_Log("SceneManager::handleSceneEvent: Unhandled event type!\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SceneManager::destoryQuitedScene() {
|
||||||
|
if (!m_quitedScene) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto info = typeid(*m_quitedScene.get()).name();
|
||||||
|
m_quitedScene.reset();
|
||||||
|
std::cout << "SceneManager: " << info << " destroyed\n";
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -79,7 +79,7 @@ public:
|
|||||||
void popScene();
|
void popScene();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 替换当前场景
|
* @brief 替换当前场景,在帧结束销毁退出的场景,如果要保留场景,应该用pushScene
|
||||||
* @param sceneName 场景名称,用于缓存查找或工厂创建
|
* @param sceneName 场景名称,用于缓存查找或工厂创建
|
||||||
* @details 当前场景将接收 onExit() 回调并被替换。若缓存中存在该名称的场景则复用,
|
* @details 当前场景将接收 onExit() 回调并被替换。若缓存中存在该名称的场景则复用,
|
||||||
* 否则通过工厂函数创建新场景。新场景成为当前场景并接收 onEnter() 回调
|
* 否则通过工厂函数创建新场景。新场景成为当前场景并接收 onEnter() 回调
|
||||||
@@ -117,6 +117,10 @@ public:
|
|||||||
* @param event 场景事件对象
|
* @param event 场景事件对象
|
||||||
*/
|
*/
|
||||||
void handleSceneEvent(const SceneEvent& event);
|
void handleSceneEvent(const SceneEvent& event);
|
||||||
|
/**
|
||||||
|
* @brief 在帧结束的时候销毁退出的场景
|
||||||
|
*/
|
||||||
|
void destoryQuitedScene();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SDL_Renderer* m_renderer; ///< SDL 渲染器指针
|
SDL_Renderer* m_renderer; ///< SDL 渲染器指针
|
||||||
@@ -126,7 +130,7 @@ private:
|
|||||||
std::stack<std::shared_ptr<Scene>> m_scenes; ///< 场景栈,存储场景层级关系(使用 shared_ptr)
|
std::stack<std::shared_ptr<Scene>> m_scenes; ///< 场景栈,存储场景层级关系(使用 shared_ptr)
|
||||||
std::unordered_map<std::string, std::shared_ptr<Scene>> m_sceneCache; ///< 场景缓存,按名字缓存场景以便切换时复用
|
std::unordered_map<std::string, std::shared_ptr<Scene>> m_sceneCache; ///< 场景缓存,按名字缓存场景以便切换时复用
|
||||||
std::unordered_map<std::string, std::function<std::shared_ptr<Scene>()>> m_sceneFactories; ///< 场景工厂映射,按名字动态创建场景实例
|
std::unordered_map<std::string, std::function<std::shared_ptr<Scene>()>> m_sceneFactories; ///< 场景工厂映射,按名字动态创建场景实例
|
||||||
|
std::shared_ptr<Scene> m_quitedScene; ///< 已经退出的场景,准备在最后销毁
|
||||||
/**
|
/**
|
||||||
* @brief 获取窗口尺寸的辅助方法
|
* @brief 获取窗口尺寸的辅助方法
|
||||||
* @return 返回 {宽度, 高度},如果获取失败则返回默认值 {1600, 900}
|
* @return 返回 {宽度, 高度},如果获取失败则返回默认值 {1600, 900}
|
||||||
|
|||||||
Reference in New Issue
Block a user