From de4b480dc2ff86e88edcf33edf13dd70741d91d0 Mon Sep 17 00:00:00 2001 From: Nomango Date: Wed, 27 May 2020 16:38:58 +0800 Subject: [PATCH] update Application frame ticker --- src/kiwano/core/Time.h | 6 ++-- src/kiwano/platform/Application.cpp | 37 ++++++++++++++-------- src/kiwano/platform/Application.h | 39 +++++++++++++++--------- src/kiwano/platform/win32/WindowImpl.cpp | 6 ++++ src/kiwano/utils/Ticker.cpp | 9 +++++- src/kiwano/utils/Ticker.h | 9 ++++++ 6 files changed, 75 insertions(+), 31 deletions(-) diff --git a/src/kiwano/core/Time.h b/src/kiwano/core/Time.h index 1cf09285..10b0ce37 100644 --- a/src/kiwano/core/Time.h +++ b/src/kiwano/core/Time.h @@ -263,17 +263,17 @@ inline void Duration::SetMilliseconds(int64_t ms) inline void Duration::SetSeconds(float seconds) { - milliseconds_ = static_cast(seconds * 1000.f); + milliseconds_ = static_cast(seconds * 1000.f); } inline void Duration::SetMinutes(float minutes) { - milliseconds_ = static_cast(minutes * 60 * 1000.f); + milliseconds_ = static_cast(minutes * 60 * 1000.f); } inline void Duration::SetHours(float hours) { - milliseconds_ = static_cast(hours * 60 * 60 * 1000.f); + milliseconds_ = static_cast(hours * 60 * 60 * 1000.f); } inline bool Time::IsZero() const diff --git a/src/kiwano/platform/Application.cpp b/src/kiwano/platform/Application.cpp index 52a1533f..3aeec82c 100644 --- a/src/kiwano/platform/Application.cpp +++ b/src/kiwano/platform/Application.cpp @@ -42,9 +42,6 @@ Application::Application() Use(Renderer::GetInstance()); Use(Input::GetInstance()); Use(Director::GetInstance()); - - ticker_ = Ticker::Create(0); - ticker_->Tick(); } Application::~Application() @@ -76,11 +73,27 @@ void Application::Run(RunnerPtr runner, bool debug) while (running_) { - if (ticker_->Tick()) + if (!frame_ticker_) { - if (!runner->MainLoop(ticker_->GetDeltaTime())) + frame_ticker_ = Ticker::Create(0); + } + + 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(); + } + } } this->Destroy(); @@ -89,19 +102,17 @@ void Application::Run(RunnerPtr runner, bool debug) void Application::Pause() { is_paused_ = true; - if (ticker_) - { - ticker_->Pause(); - } + + if (frame_ticker_) + frame_ticker_->Pause(); } void Application::Resume() { is_paused_ = false; - if (ticker_) - { - ticker_->Resume(); - } + + if (frame_ticker_) + frame_ticker_->Resume(); } void Application::Quit() diff --git a/src/kiwano/platform/Application.h b/src/kiwano/platform/Application.h index 10765c55..f893e2bb 100644 --- a/src/kiwano/platform/Application.h +++ b/src/kiwano/platform/Application.h @@ -78,6 +78,19 @@ public: */ void Quit(); + /** + * \~chinese + * @brief 获取暂停状态 + */ + bool IsPaused() const; + + /** + * \~chinese + * @brief 添加模块 + * @param[in] module 模块 + */ + void Use(Module& module); + /** * \~chinese * @brief 获取程序运行器 @@ -92,22 +105,15 @@ public: /** * \~chinese - * @brief 获取报时器 + * @brief 获取帧报时器 */ - TickerPtr GetTicker() const; + TickerPtr GetFrameTicker() const; /** * \~chinese - * @brief 获取暂停状态 + * @brief 设置帧报时器 */ - bool IsPaused() const; - - /** - * \~chinese - * @brief 添加模块 - * @param[in] module 模块 - */ - void Use(Module& module); + void SetFrameTicker(TickerPtr ticker); /** * \~chinese @@ -166,7 +172,7 @@ private: bool is_paused_; float time_scale_; RunnerPtr runner_; - TickerPtr ticker_; + TickerPtr frame_ticker_; List modules_; std::mutex perform_mutex_; Queue> functions_to_perform_; @@ -183,9 +189,14 @@ inline WindowPtr Application::GetMainWindow() const return runner_->GetMainWindow(); } -inline TickerPtr Application::GetTicker() const +inline TickerPtr Application::GetFrameTicker() const { - return ticker_; + return frame_ticker_; +} + +inline void Application::SetFrameTicker(TickerPtr ticker) +{ + frame_ticker_ = ticker; } inline bool Application::IsPaused() const diff --git a/src/kiwano/platform/win32/WindowImpl.cpp b/src/kiwano/platform/win32/WindowImpl.cpp index be5ae065..1aba29ef 100644 --- a/src/kiwano/platform/win32/WindowImpl.cpp +++ b/src/kiwano/platform/win32/WindowImpl.cpp @@ -34,6 +34,8 @@ #include // GET_X_LPARAM, GET_Y_LPARAM #include // ImmAssociateContext #pragma comment(lib, "imm32.lib") +#include // timeBeginPeriod, timeEndPeriod +#pragma comment(lib, "winmm.lib") namespace kiwano { @@ -185,6 +187,8 @@ WindowWin32Impl::WindowWin32Impl() // F1 - F12 for (size_t i = 0; i < 12; ++i) key_map_[VK_F1 + i] = KeyCode(size_t(KeyCode::F1) + i); + + ::timeBeginPeriod(0); } WindowWin32Impl::~WindowWin32Impl() @@ -194,6 +198,8 @@ WindowWin32Impl::~WindowWin32Impl() ::DestroyWindow(handle_); handle_ = nullptr; } + + ::timeEndPeriod(0); } void WindowWin32Impl::Init(const String& title, uint32_t width, uint32_t height, uint32_t icon, bool resizable) diff --git a/src/kiwano/utils/Ticker.cpp b/src/kiwano/utils/Ticker.cpp index d44dc5ac..bbb40fdd 100644 --- a/src/kiwano/utils/Ticker.cpp +++ b/src/kiwano/utils/Ticker.cpp @@ -65,9 +65,16 @@ bool Ticker::Tick(Duration dt) if (ticked_count_ == total_tick_count_) return false; + if (interval_.IsZero()) + { + delta_time_ = dt; + ++ticked_count_; + return true; + } + elapsed_time_ += dt; - if (elapsed_time_ + error_time_ > interval_) + if (elapsed_time_ + error_time_ >= interval_) { delta_time_ = elapsed_time_; error_time_ = (elapsed_time_ + error_time_) - interval_; diff --git a/src/kiwano/utils/Ticker.h b/src/kiwano/utils/Ticker.h index 815bfe8c..09d9df2b 100644 --- a/src/kiwano/utils/Ticker.h +++ b/src/kiwano/utils/Ticker.h @@ -87,6 +87,10 @@ public: /// @brief 设置报时间隔 void SetInterval(Duration interval); + /// \~chinese + /// @brief 获取时间误差 + Duration GetErrorTime() const; + /// \~chinese /// @brief 获取计时器 TimerPtr GetTimer(); @@ -140,4 +144,9 @@ inline void Ticker::SetInterval(Duration interval) interval_ = interval; } +inline Duration Ticker::GetErrorTime() const +{ + return error_time_; +} + } // namespace kiwano