update frame ticker & fix window frozen when minimized
This commit is contained in:
		
							parent
							
								
									7f902e3343
								
							
						
					
					
						commit
						091a05e8fd
					
				|  | @ -48,9 +48,10 @@ Application::~Application() | ||||||
| void Application::Run(RunnerPtr runner) | void Application::Run(RunnerPtr runner) | ||||||
| { | { | ||||||
|     KGE_ASSERT(runner); |     KGE_ASSERT(runner); | ||||||
|     runner_ = runner; |  | ||||||
|     running_   = true; |     running_   = true; | ||||||
|     is_paused_ = false; |     is_paused_ = false; | ||||||
|  |     runner_    = runner; | ||||||
|  |     timer_     = Timer::Create(); | ||||||
| 
 | 
 | ||||||
|     // Initialize runner
 |     // Initialize runner
 | ||||||
|     runner->InitSettings(); |     runner->InitSettings(); | ||||||
|  | @ -64,30 +65,18 @@ void Application::Run(RunnerPtr runner) | ||||||
|     // Everything is ready
 |     // Everything is ready
 | ||||||
|     runner->OnReady(); |     runner->OnReady(); | ||||||
| 
 | 
 | ||||||
|  |     // Update everything
 | ||||||
|  |     this->Update(0); | ||||||
|  | 
 | ||||||
|  |     // Start the loop
 | ||||||
|     while (running_) |     while (running_) | ||||||
|     { |     { | ||||||
|         if (!frame_ticker_) |         timer_->Tick(); | ||||||
|         { |  | ||||||
|             frame_ticker_ = Ticker::Create(0); |  | ||||||
|         } |  | ||||||
| 
 | 
 | ||||||
|         if (frame_ticker_->Tick()) |  | ||||||
|         { |  | ||||||
|         // Execute main loop
 |         // Execute main loop
 | ||||||
|             if (!runner->MainLoop(frame_ticker_->GetDeltaTime())) |         if (!runner->MainLoop(timer_->GetDeltaTime())) | ||||||
|             running_ = false; |             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(); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|     this->Destroy(); |     this->Destroy(); | ||||||
| } | } | ||||||
|  | @ -96,16 +85,16 @@ void Application::Pause() | ||||||
| { | { | ||||||
|     is_paused_ = true; |     is_paused_ = true; | ||||||
| 
 | 
 | ||||||
|     if (frame_ticker_) |     if (timer_) | ||||||
|         frame_ticker_->Pause(); |         timer_->Pause(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Application::Resume() | void Application::Resume() | ||||||
| { | { | ||||||
|     is_paused_ = false; |     is_paused_ = false; | ||||||
| 
 | 
 | ||||||
|     if (frame_ticker_) |     if (timer_) | ||||||
|         frame_ticker_->Resume(); |         timer_->Resume(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Application::Quit() | void Application::Quit() | ||||||
|  | @ -113,6 +102,12 @@ void Application::Quit() | ||||||
|     running_ = false; |     running_ = false; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void Application::UpdateFrame(Duration dt) | ||||||
|  | { | ||||||
|  |     this->Render(); | ||||||
|  |     this->Update(dt); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void Application::Destroy() | void Application::Destroy() | ||||||
| { | { | ||||||
|     if (runner_) |     if (runner_) | ||||||
|  |  | ||||||
|  | @ -27,7 +27,7 @@ | ||||||
| #include <kiwano/event/Event.h> | #include <kiwano/event/Event.h> | ||||||
| #include <kiwano/platform/Runner.h> | #include <kiwano/platform/Runner.h> | ||||||
| #include <kiwano/platform/Window.h> | #include <kiwano/platform/Window.h> | ||||||
| #include <kiwano/utils/Ticker.h> | #include <kiwano/utils/Timer.h> | ||||||
| 
 | 
 | ||||||
| namespace kiwano | namespace kiwano | ||||||
| { | { | ||||||
|  | @ -103,18 +103,6 @@ public: | ||||||
|      */ |      */ | ||||||
|     WindowPtr GetWindow() const; |     WindowPtr GetWindow() const; | ||||||
| 
 | 
 | ||||||
|     /**
 |  | ||||||
|      * \~chinese |  | ||||||
|      * @brief 获取帧报时器 |  | ||||||
|      */ |  | ||||||
|     TickerPtr GetFrameTicker() const; |  | ||||||
| 
 |  | ||||||
|     /**
 |  | ||||||
|      * \~chinese |  | ||||||
|      * @brief 设置帧报时器 |  | ||||||
|      */ |  | ||||||
|     void SetFrameTicker(TickerPtr ticker); |  | ||||||
| 
 |  | ||||||
|     /**
 |     /**
 | ||||||
|      * \~chinese |      * \~chinese | ||||||
|      * @brief 设置时间缩放因子 |      * @brief 设置时间缩放因子 | ||||||
|  | @ -150,16 +138,10 @@ public: | ||||||
| 
 | 
 | ||||||
|     /**
 |     /**
 | ||||||
|      * \~chinese |      * \~chinese | ||||||
|      * @brief 更新所有模块 |      * @brief 更新一帧 | ||||||
|      * @param dt 时间间隔 |      * @param dt 时间间隔 | ||||||
|      */ |      */ | ||||||
|     void Update(Duration dt); |     void UpdateFrame(Duration dt); | ||||||
| 
 |  | ||||||
|     /**
 |  | ||||||
|      * \~chinese |  | ||||||
|      * @brief 创建渲染上下文并渲染画面 |  | ||||||
|      */ |  | ||||||
|     void Render(); |  | ||||||
| 
 | 
 | ||||||
|     /**
 |     /**
 | ||||||
|      * \~chinese |      * \~chinese | ||||||
|  | @ -167,12 +149,26 @@ public: | ||||||
|      */ |      */ | ||||||
|     void Destroy(); |     void Destroy(); | ||||||
| 
 | 
 | ||||||
|  | private: | ||||||
|  |     /**
 | ||||||
|  |      * \~chinese | ||||||
|  |      * @brief 更新所有模块 | ||||||
|  |      * @param dt 时间间隔 | ||||||
|  |      */ | ||||||
|  |     void Update(Duration dt); | ||||||
|  | 
 | ||||||
|  |     /**
 | ||||||
|  |      * \~chinese | ||||||
|  |      * @brief 渲染画面 | ||||||
|  |      */ | ||||||
|  |     void Render(); | ||||||
|  | 
 | ||||||
| private: | private: | ||||||
|     bool                    running_; |     bool                    running_; | ||||||
|     bool                    is_paused_; |     bool                    is_paused_; | ||||||
|     float                   time_scale_; |     float                   time_scale_; | ||||||
|     RunnerPtr               runner_; |     RunnerPtr               runner_; | ||||||
|     TickerPtr               frame_ticker_; |     TimerPtr                timer_; | ||||||
|     List<Module*>           modules_; |     List<Module*>           modules_; | ||||||
|     std::mutex              perform_mutex_; |     std::mutex              perform_mutex_; | ||||||
|     Queue<Function<void()>> functions_to_perform_; |     Queue<Function<void()>> functions_to_perform_; | ||||||
|  | @ -185,18 +181,9 @@ inline RunnerPtr Application::GetRunner() const | ||||||
| 
 | 
 | ||||||
| inline WindowPtr Application::GetWindow() const | inline WindowPtr Application::GetWindow() const | ||||||
| { | { | ||||||
|     KGE_ASSERT(runner_); |     if (runner_) | ||||||
|         return runner_->GetWindow(); |         return runner_->GetWindow(); | ||||||
| } |     return nullptr; | ||||||
| 
 |  | ||||||
| inline TickerPtr Application::GetFrameTicker() const |  | ||||||
| { |  | ||||||
|     return frame_ticker_; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| inline void Application::SetFrameTicker(TickerPtr ticker) |  | ||||||
| { |  | ||||||
|     frame_ticker_ = ticker; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| inline bool Application::IsPaused() const | inline bool Application::IsPaused() const | ||||||
|  |  | ||||||
|  | @ -101,6 +101,9 @@ void Runner::InitSettings() | ||||||
|         Director::GetInstance().ShowDebugInfo(true); |         Director::GetInstance().ShowDebugInfo(true); | ||||||
|         Renderer::GetInstance().GetContext().SetCollectingStatus(true); |         Renderer::GetInstance().GetContext().SetCollectingStatus(true); | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     // Create frame ticker
 | ||||||
|  |     frame_ticker_ = Ticker::Create(settings_.frame_interval, -1); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool Runner::MainLoop(Duration dt) | bool Runner::MainLoop(Duration dt) | ||||||
|  | @ -118,9 +121,6 @@ bool Runner::MainLoop(Duration dt) | ||||||
| 
 | 
 | ||||||
|     Application& app = Application::GetInstance(); |     Application& app = Application::GetInstance(); | ||||||
| 
 | 
 | ||||||
|     // Update modules before poll events
 |  | ||||||
|     app.Update(dt); |  | ||||||
| 
 |  | ||||||
|     // Poll events
 |     // Poll events
 | ||||||
|     main_window_->PumpEvents(); |     main_window_->PumpEvents(); | ||||||
|     while (EventPtr evt = main_window_->PollEvent()) |     while (EventPtr evt = main_window_->PollEvent()) | ||||||
|  | @ -128,12 +128,27 @@ bool Runner::MainLoop(Duration dt) | ||||||
|         app.DispatchEvent(evt.Get()); |         app.DispatchEvent(evt.Get()); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     app.Render(); |     // Update frame ticker
 | ||||||
| 
 |     if (frame_ticker_) | ||||||
|     if (app.IsPaused()) |  | ||||||
|     { |     { | ||||||
|         // Slow down when the application is paused
 |         if (frame_ticker_->Tick(dt)) | ||||||
|         Duration(5).Sleep(); |         { | ||||||
|  |             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; |     return true; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -24,6 +24,8 @@ | ||||||
| #include <kiwano/platform/Window.h> | #include <kiwano/platform/Window.h> | ||||||
| #include <kiwano/render/Color.h> | #include <kiwano/render/Color.h> | ||||||
| #include <kiwano/render/Texture.h> | #include <kiwano/render/Texture.h> | ||||||
|  | #include <kiwano/utils/Ticker.h> | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| namespace kiwano | namespace kiwano | ||||||
| { | { | ||||||
|  | @ -44,6 +46,7 @@ struct Settings | ||||||
|     uint32_t icon;            ///< 窗口图标
 |     uint32_t icon;            ///< 窗口图标
 | ||||||
|     bool     resizable;       ///< 窗口大小可调整
 |     bool     resizable;       ///< 窗口大小可调整
 | ||||||
|     Color    bg_color;        ///< 窗口背景色
 |     Color    bg_color;        ///< 窗口背景色
 | ||||||
|  |     Duration frame_interval;  ///< 帧间隔
 | ||||||
|     bool     vsync_enabled;   ///< 垂直同步
 |     bool     vsync_enabled;   ///< 垂直同步
 | ||||||
|     bool     debug_mode;      ///< 调试模式
 |     bool     debug_mode;      ///< 调试模式
 | ||||||
| 
 | 
 | ||||||
|  | @ -54,7 +57,8 @@ struct Settings | ||||||
|         , icon() |         , icon() | ||||||
|         , resizable(false) |         , resizable(false) | ||||||
|         , bg_color(Color::Black) |         , bg_color(Color::Black) | ||||||
|         , vsync_enabled(true) |         , frame_interval(16) | ||||||
|  |         , vsync_enabled(false) | ||||||
|         , debug_mode(false) |         , debug_mode(false) | ||||||
|     { |     { | ||||||
|     } |     } | ||||||
|  | @ -118,6 +122,14 @@ public: | ||||||
|     /// @brief 获取设置
 |     /// @brief 获取设置
 | ||||||
|     Settings GetSettings() const; |     Settings GetSettings() const; | ||||||
| 
 | 
 | ||||||
|  |     /// \~chinese
 | ||||||
|  |     /// @brief 获取帧报时器
 | ||||||
|  |     TickerPtr GetFrameTicker() const; | ||||||
|  | 
 | ||||||
|  |     /// \~chinese
 | ||||||
|  |     /// @brief 设置帧报时器
 | ||||||
|  |     void SetFrameTicker(TickerPtr ticker); | ||||||
|  | 
 | ||||||
| protected: | protected: | ||||||
|     /// \~chinese
 |     /// \~chinese
 | ||||||
|     /// @brief 修改设置
 |     /// @brief 修改设置
 | ||||||
|  | @ -131,6 +143,7 @@ private: | ||||||
| private: | private: | ||||||
|     Settings  settings_; |     Settings  settings_; | ||||||
|     WindowPtr main_window_; |     WindowPtr main_window_; | ||||||
|  |     TickerPtr frame_ticker_; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| inline void Runner::OnReady() {} | inline void Runner::OnReady() {} | ||||||
|  | @ -162,4 +175,14 @@ inline void Runner::SetSettings(Settings settings) | ||||||
|     settings_ = settings; |     settings_ = settings; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | inline TickerPtr Runner::GetFrameTicker() const | ||||||
|  | { | ||||||
|  |     return frame_ticker_; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | inline void Runner::SetFrameTicker(TickerPtr ticker) | ||||||
|  | { | ||||||
|  |     frame_ticker_ = ticker; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| }  // namespace kiwano
 | }  // namespace kiwano
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue