refactor(application): 将SquirrelVM执行逻辑改为启动回调

修改Application::run方法,接收一个启动回调函数参数,将原本直接执行的SquirrelVM::run逻辑改为由调用方通过回调控制。同时更新相关文档说明这一变更。
This commit is contained in:
2026-04-01 05:27:55 +08:00
parent 8cb688cf27
commit 648b94e741
4 changed files with 22 additions and 14 deletions

View File

@@ -57,6 +57,8 @@ struct AppConfig {
*/
class Application {
public:
using StartCallback = Function<void()>;
/**
* @brief 获取单例实例
* @return 应用程序实例引用
@@ -86,8 +88,9 @@ public:
/**
* @brief 运行主循环
* @param callback 主循环开始前执行一次的启动回调
*/
void run();
void run(StartCallback callback);
/**
* @brief 请求退出
@@ -200,4 +203,4 @@ private:
};
}
}

View File

@@ -18,7 +18,6 @@
#include <frostbite2D/platform/windows.h>
#include <frostbite2D/resource/asset.h>
#include <frostbite2D/resource/npk_archive.h>
#include <frostbite2D/script/squirrel_vm.h>
#include <frostbite2D/resource/pvf_archive.h>
#include <frostbite2D/resource/sound_pack_archive.h>
#include <frostbite2D/scene/scene.h>
@@ -181,7 +180,7 @@ bool Application::initCoreModules() {
return true;
}
void Application::run() {
void Application::run(StartCallback callback) {
if (!initialized_) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Application not initialized!");
return;
@@ -204,8 +203,8 @@ void Application::run() {
fpsTimer_ = 0.0f;
currentFps_ = 0;
if (SquirrelVM::get().isInitialized()) {
SquirrelVM::get().run();
if (callback) {
callback();
}
mainLoop();

View File

@@ -230,7 +230,11 @@ int main(int argc, char **argv) {
// SDL_Log("File: %s", path.c_str());
// }
app.run();
app.run([]() {
if (SquirrelVM::get().isInitialized()) {
SquirrelVM::get().run();
}
});
SDL_Log("Application exited normally");
app.shutdown();

View File

@@ -133,7 +133,7 @@ Nintendo Switch 平台使用 devkitPro/libnx/portlibs 工具链与库。
3. 初始化脚本系统和资源归档
4. 创建场景并压入 `SceneManager`
5. 创建文本、动画、精灵、测试 Actor
6. 调用 `Application::run()`
6. 调用 `Application::run(callback)`
7. 退出时调用 `Application::shutdown()`
一个简化后的运行主线如下:
@@ -151,8 +151,8 @@ main
-> 初始化 SquirrelVM / PvfArchive / NpkArchive / FontManager
-> SceneManager::PushScene
-> 创建 Sprite / TextSprite / Animation / Actor
-> Application::run
-> 可选执行 SquirrelVM::run
-> Application::run(callback)
-> 调用方提供的启动回调
-> 主循环
-> SDL_PollEvent
-> SDL 事件转换为引擎事件
@@ -191,7 +191,7 @@ main
需要注意的实现细节:
- `initCoreModules()` 内部会先设置 `Asset` 工作目录,再做 SDL/窗口/渲染器初始化。
- `run()` 会在主循环前检查 `SquirrelVM` 是否已初始化,如果已初始化则先执行 `SquirrelVM::run()`
- `run(callback)` 会在主循环前执行一次调用方传入的启动回调;`Application` 本身不再直接依赖 Squirrel
- `shutdown()` 中会清空场景栈、关闭渲染器、关闭音频系统、关闭归档系统,然后销毁窗口。
## 5.2 Window
@@ -485,9 +485,9 @@ SquirrelVM::get().setScriptDirectory("assets/scripts");
SquirrelVM::get().init();
```
随后在 `Application::run()` 中,如果 VM 已初始化,会先执行 `SquirrelVM::run()`
随后由调用方`Application::run(callback)` 的启动回调中决定是否执行 `SquirrelVM::run()`
这意味着脚本系统目前是“可选启动模块”,而不是 `Application::init()` 的强制步骤。
这意味着脚本系统目前是“由上层控制的可选启动模块”,而不是 `Application::init()``Application::run()` 的强制步骤。
## 10. 音频系统
@@ -624,7 +624,9 @@ if (!app.init(config)) {
auto scene = MakePtr<Scene>();
SceneManager::get().PushScene(scene);
app.run();
app.run([]() {
// optional startup logic
});
app.shutdown();
```