update Application frame ticker

This commit is contained in:
Nomango 2020-05-27 16:38:58 +08:00
parent aba322a3c6
commit de4b480dc2
6 changed files with 75 additions and 31 deletions

View File

@ -263,17 +263,17 @@ inline void Duration::SetMilliseconds(int64_t ms)
inline void Duration::SetSeconds(float seconds) inline void Duration::SetSeconds(float seconds)
{ {
milliseconds_ = static_cast<long>(seconds * 1000.f); milliseconds_ = static_cast<int64_t>(seconds * 1000.f);
} }
inline void Duration::SetMinutes(float minutes) inline void Duration::SetMinutes(float minutes)
{ {
milliseconds_ = static_cast<long>(minutes * 60 * 1000.f); milliseconds_ = static_cast<int64_t>(minutes * 60 * 1000.f);
} }
inline void Duration::SetHours(float hours) inline void Duration::SetHours(float hours)
{ {
milliseconds_ = static_cast<long>(hours * 60 * 60 * 1000.f); milliseconds_ = static_cast<int64_t>(hours * 60 * 60 * 1000.f);
} }
inline bool Time::IsZero() const inline bool Time::IsZero() const

View File

@ -42,9 +42,6 @@ Application::Application()
Use(Renderer::GetInstance()); Use(Renderer::GetInstance());
Use(Input::GetInstance()); Use(Input::GetInstance());
Use(Director::GetInstance()); Use(Director::GetInstance());
ticker_ = Ticker::Create(0);
ticker_->Tick();
} }
Application::~Application() Application::~Application()
@ -76,11 +73,27 @@ void Application::Run(RunnerPtr runner, bool debug)
while (running_) 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; 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();
@ -89,19 +102,17 @@ void Application::Run(RunnerPtr runner, bool debug)
void Application::Pause() void Application::Pause()
{ {
is_paused_ = true; is_paused_ = true;
if (ticker_)
{ if (frame_ticker_)
ticker_->Pause(); frame_ticker_->Pause();
}
} }
void Application::Resume() void Application::Resume()
{ {
is_paused_ = false; is_paused_ = false;
if (ticker_)
{ if (frame_ticker_)
ticker_->Resume(); frame_ticker_->Resume();
}
} }
void Application::Quit() void Application::Quit()

View File

@ -78,6 +78,19 @@ public:
*/ */
void Quit(); void Quit();
/**
* \~chinese
* @brief
*/
bool IsPaused() const;
/**
* \~chinese
* @brief
* @param[in] module
*/
void Use(Module& module);
/** /**
* \~chinese * \~chinese
* @brief * @brief
@ -92,22 +105,15 @@ public:
/** /**
* \~chinese * \~chinese
* @brief * @brief
*/ */
TickerPtr GetTicker() const; TickerPtr GetFrameTicker() const;
/** /**
* \~chinese * \~chinese
* @brief * @brief
*/ */
bool IsPaused() const; void SetFrameTicker(TickerPtr ticker);
/**
* \~chinese
* @brief
* @param[in] module
*/
void Use(Module& module);
/** /**
* \~chinese * \~chinese
@ -166,7 +172,7 @@ private:
bool is_paused_; bool is_paused_;
float time_scale_; float time_scale_;
RunnerPtr runner_; RunnerPtr runner_;
TickerPtr ticker_; TickerPtr frame_ticker_;
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_;
@ -183,9 +189,14 @@ inline WindowPtr Application::GetMainWindow() const
return runner_->GetMainWindow(); 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 inline bool Application::IsPaused() const

View File

@ -34,6 +34,8 @@
#include <Windowsx.h> // GET_X_LPARAM, GET_Y_LPARAM #include <Windowsx.h> // GET_X_LPARAM, GET_Y_LPARAM
#include <imm.h> // ImmAssociateContext #include <imm.h> // ImmAssociateContext
#pragma comment(lib, "imm32.lib") #pragma comment(lib, "imm32.lib")
#include <timeapi.h> // timeBeginPeriod, timeEndPeriod
#pragma comment(lib, "winmm.lib")
namespace kiwano namespace kiwano
{ {
@ -185,6 +187,8 @@ WindowWin32Impl::WindowWin32Impl()
// F1 - F12 // F1 - F12
for (size_t i = 0; i < 12; ++i) for (size_t i = 0; i < 12; ++i)
key_map_[VK_F1 + i] = KeyCode(size_t(KeyCode::F1) + i); key_map_[VK_F1 + i] = KeyCode(size_t(KeyCode::F1) + i);
::timeBeginPeriod(0);
} }
WindowWin32Impl::~WindowWin32Impl() WindowWin32Impl::~WindowWin32Impl()
@ -194,6 +198,8 @@ WindowWin32Impl::~WindowWin32Impl()
::DestroyWindow(handle_); ::DestroyWindow(handle_);
handle_ = nullptr; handle_ = nullptr;
} }
::timeEndPeriod(0);
} }
void WindowWin32Impl::Init(const String& title, uint32_t width, uint32_t height, uint32_t icon, bool resizable) void WindowWin32Impl::Init(const String& title, uint32_t width, uint32_t height, uint32_t icon, bool resizable)

View File

@ -65,9 +65,16 @@ bool Ticker::Tick(Duration dt)
if (ticked_count_ == total_tick_count_) if (ticked_count_ == total_tick_count_)
return false; return false;
if (interval_.IsZero())
{
delta_time_ = dt;
++ticked_count_;
return true;
}
elapsed_time_ += dt; elapsed_time_ += dt;
if (elapsed_time_ + error_time_ > interval_) if (elapsed_time_ + error_time_ >= interval_)
{ {
delta_time_ = elapsed_time_; delta_time_ = elapsed_time_;
error_time_ = (elapsed_time_ + error_time_) - interval_; error_time_ = (elapsed_time_ + error_time_) - interval_;

View File

@ -87,6 +87,10 @@ public:
/// @brief 设置报时间隔 /// @brief 设置报时间隔
void SetInterval(Duration interval); void SetInterval(Duration interval);
/// \~chinese
/// @brief 获取时间误差
Duration GetErrorTime() const;
/// \~chinese /// \~chinese
/// @brief 获取计时器 /// @brief 获取计时器
TimerPtr GetTimer(); TimerPtr GetTimer();
@ -140,4 +144,9 @@ inline void Ticker::SetInterval(Duration interval)
interval_ = interval; interval_ = interval;
} }
inline Duration Ticker::GetErrorTime() const
{
return error_time_;
}
} // namespace kiwano } // namespace kiwano