add Application::Pause & Application::Resume
This commit is contained in:
		
							parent
							
								
									6d1cf35730
								
							
						
					
					
						commit
						1af108df90
					
				|  | @ -23,6 +23,7 @@ | ||||||
| 
 | 
 | ||||||
| namespace kiwano | namespace kiwano | ||||||
| { | { | ||||||
|  | 
 | ||||||
| /**
 | /**
 | ||||||
|  * \addtogroup Actions |  * \addtogroup Actions | ||||||
|  * @{ |  * @{ | ||||||
|  |  | ||||||
|  | @ -24,6 +24,7 @@ | ||||||
| #include <regex> | #include <regex> | ||||||
| #include <unordered_map> | #include <unordered_map> | ||||||
| #include <chrono> | #include <chrono> | ||||||
|  | #include <thread> | ||||||
| 
 | 
 | ||||||
| namespace kiwano | namespace kiwano | ||||||
| { | { | ||||||
|  | @ -231,6 +232,17 @@ float Duration::Hours() const | ||||||
|     return static_cast<float>(hour) + static_cast<float>(ms) / (60 * 60 * 1000.f); |     return static_cast<float>(hour) + static_cast<float>(ms) / (60 * 60 * 1000.f); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void Duration::Sleep() const | ||||||
|  | { | ||||||
|  |     using std::chrono::milliseconds; | ||||||
|  |     using std::this_thread::sleep_for; | ||||||
|  | 
 | ||||||
|  |     if (milliseconds_) | ||||||
|  |     { | ||||||
|  |         sleep_for(milliseconds(milliseconds_)); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| String Duration::ToString() const | String Duration::ToString() const | ||||||
| { | { | ||||||
|     if (IsZero()) |     if (IsZero()) | ||||||
|  |  | ||||||
|  | @ -96,6 +96,10 @@ struct KGE_API Duration | ||||||
|     /// @param hours 小时数
 |     /// @param hours 小时数
 | ||||||
|     void SetHours(float hours); |     void SetHours(float hours); | ||||||
| 
 | 
 | ||||||
|  |     /// \~chinese
 | ||||||
|  |     /// @brief ÐÝÃß
 | ||||||
|  |     void Sleep() const; | ||||||
|  | 
 | ||||||
|     /// \~chinese
 |     /// \~chinese
 | ||||||
|     /// @brief 转为字符串
 |     /// @brief 转为字符串
 | ||||||
|     String ToString() const; |     String ToString() const; | ||||||
|  |  | ||||||
|  | @ -30,7 +30,7 @@ typedef IntrusiveList<EventListenerPtr> ListenerList; | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * \~chinese |  * \~chinese | ||||||
|  * @brief 事件分发系统 |  * @brief 事件分发器 | ||||||
|  */ |  */ | ||||||
| class KGE_API EventDispatcher | class KGE_API EventDispatcher | ||||||
| { | { | ||||||
|  |  | ||||||
|  | @ -36,11 +36,15 @@ int GetVersion() | ||||||
| 
 | 
 | ||||||
| Application::Application() | Application::Application() | ||||||
|     : running_(false) |     : running_(false) | ||||||
|  |     , is_paused_(false) | ||||||
|     , time_scale_(1.f) |     , time_scale_(1.f) | ||||||
| { | { | ||||||
|     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() | ||||||
|  | @ -52,8 +56,8 @@ void Application::Run(RunnerPtr runner, bool debug) | ||||||
| { | { | ||||||
|     KGE_ASSERT(runner); |     KGE_ASSERT(runner); | ||||||
|     runner_ = runner; |     runner_ = runner; | ||||||
|     timer_   = Timer::Create(); |  | ||||||
|     running_ = true; |     running_ = true; | ||||||
|  |     is_paused_ = false; | ||||||
| 
 | 
 | ||||||
|     // Setup all modules
 |     // Setup all modules
 | ||||||
|     for (auto c : modules_) |     for (auto c : modules_) | ||||||
|  | @ -72,15 +76,34 @@ void Application::Run(RunnerPtr runner, bool debug) | ||||||
| 
 | 
 | ||||||
|     while (running_) |     while (running_) | ||||||
|     { |     { | ||||||
|         timer_->Tick(); |         if (ticker_->Tick()) | ||||||
| 
 |         { | ||||||
|         if (!runner->MainLoop(timer_->GetDeltaTime())) |             if (!runner->MainLoop(ticker_->GetDeltaTime())) | ||||||
|                 running_ = false; |                 running_ = false; | ||||||
|         } |         } | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     this->Destroy(); |     this->Destroy(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void Application::Pause() | ||||||
|  | { | ||||||
|  |     is_paused_ = true; | ||||||
|  |     if (ticker_) | ||||||
|  |     { | ||||||
|  |         ticker_->Pause(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void Application::Resume() | ||||||
|  | { | ||||||
|  |     is_paused_ = false; | ||||||
|  |     if (ticker_) | ||||||
|  |     { | ||||||
|  |         ticker_->Resume(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void Application::Quit() | void Application::Quit() | ||||||
| { | { | ||||||
|     running_ = false; |     running_ = false; | ||||||
|  | @ -130,7 +153,7 @@ void Application::DispatchEvent(EventPtr evt) | ||||||
| 
 | 
 | ||||||
| void Application::DispatchEvent(Event* evt) | void Application::DispatchEvent(Event* evt) | ||||||
| { | { | ||||||
|     if (!running_) |     if (!running_ /* Dispatch events even if application is paused */) | ||||||
|         return; |         return; | ||||||
| 
 | 
 | ||||||
|     for (auto comp : modules_) |     for (auto comp : modules_) | ||||||
|  | @ -144,7 +167,7 @@ void Application::DispatchEvent(Event* evt) | ||||||
| 
 | 
 | ||||||
| void Application::Update(Duration dt) | void Application::Update(Duration dt) | ||||||
| { | { | ||||||
|     if (!running_) |     if (!running_ || is_paused_) | ||||||
|         return; |         return; | ||||||
| 
 | 
 | ||||||
|     // Before update
 |     // Before update
 | ||||||
|  | @ -198,7 +221,7 @@ void Application::Update(Duration dt) | ||||||
| 
 | 
 | ||||||
| void Application::Render() | void Application::Render() | ||||||
| { | { | ||||||
|     if (!running_) |     if (!running_ /* Render even if application is paused */) | ||||||
|         return; |         return; | ||||||
| 
 | 
 | ||||||
|     Renderer& renderer = Renderer::GetInstance(); |     Renderer& renderer = Renderer::GetInstance(); | ||||||
|  |  | ||||||
|  | @ -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/Timer.h> | #include <kiwano/utils/Ticker.h> | ||||||
| 
 | 
 | ||||||
| namespace kiwano | namespace kiwano | ||||||
| { | { | ||||||
|  | @ -60,6 +60,18 @@ public: | ||||||
|      */ |      */ | ||||||
|     void Run(RunnerPtr runner, bool debug = false); |     void Run(RunnerPtr runner, bool debug = false); | ||||||
| 
 | 
 | ||||||
|  |     /**
 | ||||||
|  |      * \~chinese | ||||||
|  |      * @brief 暂停应用程序 | ||||||
|  |      */ | ||||||
|  |     void Pause(); | ||||||
|  | 
 | ||||||
|  |     /**
 | ||||||
|  |      * \~chinese | ||||||
|  |      * @brief 继续应用程序 | ||||||
|  |      */ | ||||||
|  |     void Resume(); | ||||||
|  | 
 | ||||||
|     /**
 |     /**
 | ||||||
|      * \~chinese |      * \~chinese | ||||||
|      * @brief ÖÕÖ¹Ó¦ÓóÌÐò |      * @brief ÖÕÖ¹Ó¦ÓóÌÐò | ||||||
|  | @ -80,15 +92,15 @@ public: | ||||||
| 
 | 
 | ||||||
|     /**
 |     /**
 | ||||||
|      * \~chinese |      * \~chinese | ||||||
|      * @brief 获取计时器 |      * @brief 获取报时器 | ||||||
|      */ |      */ | ||||||
|     TimerPtr GetTimer() const; |     TickerPtr GetTicker() const; | ||||||
| 
 | 
 | ||||||
|     /**
 |     /**
 | ||||||
|      * \~chinese |      * \~chinese | ||||||
|      * @brief 是否正在运行 |      * @brief 获取暂停状态 | ||||||
|      */ |      */ | ||||||
|     bool IsRunning() const; |     bool IsPaused() const; | ||||||
| 
 | 
 | ||||||
|     /**
 |     /**
 | ||||||
|      * \~chinese |      * \~chinese | ||||||
|  | @ -151,9 +163,10 @@ public: | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|     bool                    running_; |     bool                    running_; | ||||||
|  |     bool                    is_paused_; | ||||||
|     float                   time_scale_; |     float                   time_scale_; | ||||||
|     RunnerPtr               runner_; |     RunnerPtr               runner_; | ||||||
|     TimerPtr                timer_; |     TickerPtr               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_; | ||||||
|  | @ -170,14 +183,14 @@ inline WindowPtr Application::GetMainWindow() const | ||||||
|     return runner_->GetMainWindow(); |     return runner_->GetMainWindow(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| inline TimerPtr Application::GetTimer() const | inline TickerPtr Application::GetTicker() const | ||||||
| { | { | ||||||
|     return timer_; |     return ticker_; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| inline bool Application::IsRunning() const | inline bool Application::IsPaused() const | ||||||
| { | { | ||||||
|     return running_; |     return is_paused_; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| }  // namespace kiwano
 | }  // namespace kiwano
 | ||||||
|  |  | ||||||
|  | @ -21,6 +21,8 @@ | ||||||
| #include <kiwano/platform/Runner.h> | #include <kiwano/platform/Runner.h> | ||||||
| #include <kiwano/platform/Application.h> | #include <kiwano/platform/Application.h> | ||||||
| 
 | 
 | ||||||
|  | #define KGE_MAX_SKIP_FRAMES 10 | ||||||
|  | 
 | ||||||
| namespace kiwano | namespace kiwano | ||||||
| { | { | ||||||
| 
 | 
 | ||||||
|  | @ -95,6 +97,12 @@ bool Runner::MainLoop(Duration dt) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     app.Render(); |     app.Render(); | ||||||
|  | 
 | ||||||
|  |     if (app.IsPaused()) | ||||||
|  |     { | ||||||
|  |         // Slow down when the application is paused
 | ||||||
|  |         Duration(5).Sleep(); | ||||||
|  |     } | ||||||
|     return true; |     return true; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -573,11 +573,7 @@ LRESULT WindowWin32Impl::MessageProc(HWND hwnd, UINT32 msg, WPARAM wparam, LPARA | ||||||
| 
 | 
 | ||||||
|             is_minimized_ = true; |             is_minimized_ = true; | ||||||
|             // Pause game when window is minimized
 |             // Pause game when window is minimized
 | ||||||
|             if (Application::GetInstance().IsRunning()) |             Application::GetInstance().Pause(); | ||||||
|             { |  | ||||||
|                 TimerPtr timer = Application::GetInstance().GetTimer(); |  | ||||||
|                 timer->Pause(); |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|         else if (SIZE_MAXIMIZED == wparam) |         else if (SIZE_MAXIMIZED == wparam) | ||||||
|         { |         { | ||||||
|  | @ -586,11 +582,7 @@ LRESULT WindowWin32Impl::MessageProc(HWND hwnd, UINT32 msg, WPARAM wparam, LPARA | ||||||
|             if (is_minimized_) |             if (is_minimized_) | ||||||
|             { |             { | ||||||
|                 is_minimized_ = false; |                 is_minimized_ = false; | ||||||
|                 if (Application::GetInstance().IsRunning()) |                 Application::GetInstance().Resume(); | ||||||
|                 { |  | ||||||
|                     TimerPtr timer = Application::GetInstance().GetTimer(); |  | ||||||
|                     timer->Resume(); |  | ||||||
|                 } |  | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         else if (wparam == SIZE_RESTORED) |         else if (wparam == SIZE_RESTORED) | ||||||
|  | @ -601,11 +593,7 @@ LRESULT WindowWin32Impl::MessageProc(HWND hwnd, UINT32 msg, WPARAM wparam, LPARA | ||||||
| 
 | 
 | ||||||
|                 // the window was restored and was previously minimized
 |                 // the window was restored and was previously minimized
 | ||||||
|                 is_minimized_ = false; |                 is_minimized_ = false; | ||||||
|                 if (Application::GetInstance().IsRunning()) |                 Application::GetInstance().Resume(); | ||||||
|                 { |  | ||||||
|                     TimerPtr timer = Application::GetInstance().GetTimer(); |  | ||||||
|                     timer->Resume(); |  | ||||||
|                 } |  | ||||||
|             } |             } | ||||||
|             else if (is_resizing_) |             else if (is_resizing_) | ||||||
|             { |             { | ||||||
|  | @ -630,22 +618,14 @@ LRESULT WindowWin32Impl::MessageProc(HWND hwnd, UINT32 msg, WPARAM wparam, LPARA | ||||||
|     case WM_ENTERSIZEMOVE: |     case WM_ENTERSIZEMOVE: | ||||||
|     { |     { | ||||||
|         is_resizing_ = true; |         is_resizing_ = true; | ||||||
|         if (Application::GetInstance().IsRunning()) |         Application::GetInstance().Pause(); | ||||||
|         { |  | ||||||
|             TimerPtr timer = Application::GetInstance().GetTimer(); |  | ||||||
|             timer->Pause(); |  | ||||||
|         } |  | ||||||
|         return 0; |         return 0; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     case WM_EXITSIZEMOVE: |     case WM_EXITSIZEMOVE: | ||||||
|     { |     { | ||||||
|         is_resizing_ = false; |         is_resizing_ = false; | ||||||
|         if (Application::GetInstance().IsRunning()) |         Application::GetInstance().Resume(); | ||||||
|         { |  | ||||||
|             TimerPtr timer = Application::GetInstance().GetTimer(); |  | ||||||
|             timer->Resume(); |  | ||||||
|         } |  | ||||||
| 
 | 
 | ||||||
|         // Send window resized event when client size changed
 |         // Send window resized event when client size changed
 | ||||||
|         RECT client_rect = { 0 }; |         RECT client_rect = { 0 }; | ||||||
|  |  | ||||||
|  | @ -23,6 +23,7 @@ | ||||||
| 
 | 
 | ||||||
| namespace kiwano | namespace kiwano | ||||||
| { | { | ||||||
|  | 
 | ||||||
| void TaskScheduler::Update(Duration dt) | void TaskScheduler::Update(Duration dt) | ||||||
| { | { | ||||||
|     if (tasks_.IsEmpty()) |     if (tasks_.IsEmpty()) | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue