From 091a05e8fdf05afdfcc872bf5754d4657ae46653 Mon Sep 17 00:00:00 2001 From: Nomango Date: Wed, 3 Jun 2020 22:07:07 +0800 Subject: [PATCH] update frame ticker & fix window frozen when minimized --- src/kiwano/platform/Application.cpp | 47 +++++++++++------------- src/kiwano/platform/Application.h | 55 +++++++++++------------------ src/kiwano/platform/Runner.cpp | 31 +++++++++++----- src/kiwano/platform/Runner.h | 41 ++++++++++++++++----- 4 files changed, 97 insertions(+), 77 deletions(-) diff --git a/src/kiwano/platform/Application.cpp b/src/kiwano/platform/Application.cpp index 5a9edfc8..1a8ba46e 100644 --- a/src/kiwano/platform/Application.cpp +++ b/src/kiwano/platform/Application.cpp @@ -48,9 +48,10 @@ Application::~Application() void Application::Run(RunnerPtr runner) { KGE_ASSERT(runner); - runner_ = runner; - running_ = true; + running_ = true; is_paused_ = false; + runner_ = runner; + timer_ = Timer::Create(); // Initialize runner runner->InitSettings(); @@ -64,29 +65,17 @@ void Application::Run(RunnerPtr runner) // Everything is ready runner->OnReady(); + // Update everything + this->Update(0); + + // Start the loop while (running_) { - if (!frame_ticker_) - { - frame_ticker_ = Ticker::Create(0); - } + timer_->Tick(); - if (frame_ticker_->Tick()) - { - // Execute main loop - if (!runner->MainLoop(frame_ticker_->GetDeltaTime())) - running_ = false; - } - else - { - // Releases CPU - Duration total_dt = frame_ticker_->GetDeltaTime() + frame_ticker_->GetErrorTime(); - Duration sleep_dt = frame_ticker_->GetInterval() - total_dt; - if (sleep_dt.Milliseconds() > 1LL) - { - sleep_dt.Sleep(); - } - } + // Execute main loop + if (!runner->MainLoop(timer_->GetDeltaTime())) + running_ = false; } this->Destroy(); @@ -96,16 +85,16 @@ void Application::Pause() { is_paused_ = true; - if (frame_ticker_) - frame_ticker_->Pause(); + if (timer_) + timer_->Pause(); } void Application::Resume() { is_paused_ = false; - if (frame_ticker_) - frame_ticker_->Resume(); + if (timer_) + timer_->Resume(); } void Application::Quit() @@ -113,6 +102,12 @@ void Application::Quit() running_ = false; } +void Application::UpdateFrame(Duration dt) +{ + this->Render(); + this->Update(dt); +} + void Application::Destroy() { if (runner_) diff --git a/src/kiwano/platform/Application.h b/src/kiwano/platform/Application.h index 1107cde5..670440c3 100644 --- a/src/kiwano/platform/Application.h +++ b/src/kiwano/platform/Application.h @@ -27,7 +27,7 @@ #include #include #include -#include +#include namespace kiwano { @@ -103,18 +103,6 @@ public: */ WindowPtr GetWindow() const; - /** - * \~chinese - * @brief 获取帧报时器 - */ - TickerPtr GetFrameTicker() const; - - /** - * \~chinese - * @brief 设置帧报时器 - */ - void SetFrameTicker(TickerPtr ticker); - /** * \~chinese * @brief 设置时间缩放因子 @@ -150,16 +138,10 @@ public: /** * \~chinese - * @brief 更新所有模块 + * @brief 更新一帧 * @param dt 时间间隔 */ - void Update(Duration dt); - - /** - * \~chinese - * @brief 创建渲染上下文并渲染画面 - */ - void Render(); + void UpdateFrame(Duration dt); /** * \~chinese @@ -167,12 +149,26 @@ public: */ void Destroy(); +private: + /** + * \~chinese + * @brief 更新所有模块 + * @param dt 时间间隔 + */ + void Update(Duration dt); + + /** + * \~chinese + * @brief 渲染画面 + */ + void Render(); + private: bool running_; bool is_paused_; float time_scale_; RunnerPtr runner_; - TickerPtr frame_ticker_; + TimerPtr timer_; List modules_; std::mutex perform_mutex_; Queue> functions_to_perform_; @@ -185,18 +181,9 @@ inline RunnerPtr Application::GetRunner() const inline WindowPtr Application::GetWindow() const { - KGE_ASSERT(runner_); - return runner_->GetWindow(); -} - -inline TickerPtr Application::GetFrameTicker() const -{ - return frame_ticker_; -} - -inline void Application::SetFrameTicker(TickerPtr ticker) -{ - frame_ticker_ = ticker; + if (runner_) + return runner_->GetWindow(); + return nullptr; } inline bool Application::IsPaused() const diff --git a/src/kiwano/platform/Runner.cpp b/src/kiwano/platform/Runner.cpp index a289b6a5..175a0c07 100644 --- a/src/kiwano/platform/Runner.cpp +++ b/src/kiwano/platform/Runner.cpp @@ -101,6 +101,9 @@ void Runner::InitSettings() Director::GetInstance().ShowDebugInfo(true); Renderer::GetInstance().GetContext().SetCollectingStatus(true); } + + // Create frame ticker + frame_ticker_ = Ticker::Create(settings_.frame_interval, -1); } bool Runner::MainLoop(Duration dt) @@ -118,9 +121,6 @@ bool Runner::MainLoop(Duration dt) Application& app = Application::GetInstance(); - // Update modules before poll events - app.Update(dt); - // Poll events main_window_->PumpEvents(); while (EventPtr evt = main_window_->PollEvent()) @@ -128,12 +128,27 @@ bool Runner::MainLoop(Duration dt) app.DispatchEvent(evt.Get()); } - app.Render(); - - if (app.IsPaused()) + // Update frame ticker + if (frame_ticker_) { - // Slow down when the application is paused - Duration(5).Sleep(); + if (frame_ticker_->Tick(dt)) + { + app.UpdateFrame(frame_ticker_->GetDeltaTime()); + } + else + { + // Releases CPU + Duration total_dt = frame_ticker_->GetDeltaTime() + frame_ticker_->GetErrorTime(); + Duration sleep_dt = frame_ticker_->GetInterval() - total_dt; + if (sleep_dt.Milliseconds() > 1LL) + { + sleep_dt.Sleep(); + } + } + } + else + { + app.UpdateFrame(dt); } return true; } diff --git a/src/kiwano/platform/Runner.h b/src/kiwano/platform/Runner.h index db1a6d38..20c0c4b7 100644 --- a/src/kiwano/platform/Runner.h +++ b/src/kiwano/platform/Runner.h @@ -24,6 +24,8 @@ #include #include #include +#include + namespace kiwano { @@ -38,14 +40,15 @@ KGE_DECLARE_SMART_PTR(Runner); */ struct Settings { - uint32_t width; ///< 窗口宽度 - uint32_t height; ///< 窗口高度 - String title; ///< 窗口标题 - uint32_t icon; ///< 窗口图标 - bool resizable; ///< 窗口大小可调整 - Color bg_color; ///< 窗口背景色 - bool vsync_enabled; ///< 垂直同步 - bool debug_mode; ///< 调试模式 + uint32_t width; ///< 窗口宽度 + uint32_t height; ///< 窗口高度 + String title; ///< 窗口标题 + uint32_t icon; ///< 窗口图标 + bool resizable; ///< 窗口大小可调整 + Color bg_color; ///< 窗口背景色 + Duration frame_interval; ///< 帧间隔 + bool vsync_enabled; ///< 垂直同步 + bool debug_mode; ///< 调试模式 Settings() : width(800) @@ -54,7 +57,8 @@ struct Settings , icon() , resizable(false) , bg_color(Color::Black) - , vsync_enabled(true) + , frame_interval(16) + , vsync_enabled(false) , debug_mode(false) { } @@ -118,6 +122,14 @@ public: /// @brief 获取设置 Settings GetSettings() const; + /// \~chinese + /// @brief 获取帧报时器 + TickerPtr GetFrameTicker() const; + + /// \~chinese + /// @brief 设置帧报时器 + void SetFrameTicker(TickerPtr ticker); + protected: /// \~chinese /// @brief 修改设置 @@ -131,6 +143,7 @@ private: private: Settings settings_; WindowPtr main_window_; + TickerPtr frame_ticker_; }; inline void Runner::OnReady() {} @@ -162,4 +175,14 @@ inline void Runner::SetSettings(Settings settings) settings_ = settings; } +inline TickerPtr Runner::GetFrameTicker() const +{ + return frame_ticker_; +} + +inline void Runner::SetFrameTicker(TickerPtr ticker) +{ + frame_ticker_ = ticker; +} + } // namespace kiwano