Add Runner

This commit is contained in:
Nomango 2020-02-14 17:12:13 +08:00
parent a34184dd18
commit 93e97c60c2
11 changed files with 193 additions and 88 deletions

View File

@ -22,6 +22,7 @@
<ClInclude Include="..\..\src\kiwano\core\Exception.h" />
<ClInclude Include="..\..\src\kiwano\core\Keys.h" />
<ClInclude Include="..\..\src\kiwano\core\Library.h" />
<ClInclude Include="..\..\src\kiwano\core\Runner.h" />
<ClInclude Include="..\..\src\kiwano\core\Singleton.h" />
<ClInclude Include="..\..\src\kiwano\core\Time.h" />
<ClInclude Include="..\..\src\kiwano\kiwano.h" />

View File

@ -300,6 +300,9 @@
<ClInclude Include="..\..\src\kiwano\render\Layer.h">
<Filter>render</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\core\Runner.h">
<Filter>core</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\src\kiwano\2d\Canvas.cpp">

View File

@ -235,7 +235,7 @@ void HttpClient::NetworkThread()
response_queue_.push(response);
response_mutex_.unlock();
Application::PreformInMainThread(Closure(this, &HttpClient::DispatchResponseCallback));
Application::GetInstance().PreformInMainThread(Closure(this, &HttpClient::DispatchResponseCallback));
}
}

View File

@ -77,7 +77,7 @@ void AsyncTask::TaskThread()
func_mutex_.unlock();
}
Application::PreformInMainThread(Closure(this, &AsyncTask::Complete));
Application::GetInstance().PreformInMainThread(Closure(this, &AsyncTask::Complete));
}
void AsyncTask::Complete()

94
src/kiwano/core/Runner.h Normal file
View File

@ -0,0 +1,94 @@
// Copyright (c) 2016-2018 Kiwano - Nomango
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#pragma once
#include <kiwano/core/Common.h>
namespace kiwano
{
/**
* \~chinese
* @brief
*/
class KGE_API Runner
{
public:
typedef Function<void()> Callback;
Runner();
/// \~chinese
/// @brief 构造程序运行器
/// @param on_ready 应用程序初始化完成后执行的回调函数
/// @param on_destroy 应用程序销毁时执行的回调函数
Runner(const Callback& on_ready, const Callback& on_destroy = nullptr);
/// \~chinese
/// @brief 初始化完成处理
/// @details 重载该函数以在应用程序初始化完成后自动执行
virtual void OnReady();
/// \~chinese
/// @brief 应用程序销毁处理
/// @details 重载该函数以处理应用程序销毁时的行为,如完成资源回收等
virtual void OnDestroy();
/// \~chinese
/// @brief 窗口关闭处理
/// @details 重载该函数以处理用户关闭窗口时的行为,如保存用户数据等
/// @return 返回true允许用户关闭窗口否则阻止窗口关闭
virtual bool OnClosing();
private:
Callback on_ready_;
Callback on_destroy_;
};
inline Runner::Runner() {}
inline Runner::Runner(const Callback& on_ready, const Callback& on_destroy)
: on_ready_(on_ready)
, on_destroy_(on_destroy)
{
}
inline void Runner::OnReady()
{
if (on_ready_)
{
on_ready_();
}
}
inline void Runner::OnDestroy()
{
if (on_destroy_)
{
on_destroy_();
}
}
inline bool Runner::OnClosing()
{
return true;
}
} // namespace kiwano

View File

@ -18,40 +18,28 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#include <kiwano/core/Director.h>
#include <kiwano/core/Logger.h>
#include <kiwano/platform/Application.h>
#include <kiwano/platform/Input.h>
#include <kiwano/core/Director.h>
#include <kiwano/core/Logger.h>
#include <kiwano/render/TextureCache.h>
#include <kiwano/utils/ResourceCache.h>
#include <mutex>
namespace kiwano
{
namespace
{
using FunctionToPerform = Function<void()>;
std::mutex perform_mutex_;
Queue<FunctionToPerform> functions_to_perform_;
} // namespace
Application::Application()
: time_scale_(1.f)
: quiting_(false)
, time_scale_(1.f)
{
Use(&Renderer::GetInstance());
Use(&Input::GetInstance());
Use(&Director::GetInstance());
}
Application::~Application()
{
Destroy();
}
Application::~Application() {}
void Application::Run(bool debug)
void Application::Run(Runner& runner, bool debug)
{
// Setup all components
for (auto c : comps_)
@ -66,26 +54,43 @@ void Application::Run(bool debug)
}
// Everything is ready
OnReady();
runner.OnReady();
// Initialize variables
quiting_ = false;
last_update_time_ = Time::Now();
Window& window = Window::GetInstance();
while (!window.ShouldClose())
while (!quiting_)
{
while (EventPtr evt = window.PollEvent())
if (window.ShouldClose())
{
DispatchEvent(evt.get());
if (runner.OnClosing())
break;
else
window.SetShouldClose(false);
}
Update();
Render();
while (EventPtr evt = window.PollEvent())
{
this->DispatchEvent(evt.get());
}
this->Update();
this->Render();
}
// Destroy all resources
runner.OnDestroy();
this->Destroy();
// Destroy window
window.Destroy();
}
void Application::Quit()
{
Window::GetInstance().Destroy();
quiting_ = true;
}
void Application::Destroy()
@ -99,10 +104,6 @@ void Application::Destroy()
{
(*iter)->DestroyComponent();
}
render_comps_.clear();
update_comps_.clear();
event_comps_.clear();
comps_.clear();
}
void Application::Use(ComponentBase* component)

View File

@ -19,13 +19,13 @@
// THE SOFTWARE.
#pragma once
#include <mutex>
#include <kiwano/core/Common.h>
#include <kiwano/core/Component.h>
#include <kiwano/core/Time.h>
#include <kiwano/core/Runner.h>
#include <kiwano/core/Singleton.h>
#include <kiwano/core/event/Event.h>
#include <kiwano/core/event/KeyEvent.h>
#include <kiwano/core/event/MouseEvent.h>
#include <kiwano/core/event/WindowEvent.h>
#include <kiwano/platform/Window.h>
#include <kiwano/render/Renderer.h>
@ -35,35 +35,23 @@ namespace kiwano
* \~chinese
* @brief
*/
class KGE_API Application : protected Noncopyable
class KGE_API Application : public Singleton<Application>
{
friend Singleton<Application>;
public:
Application();
virtual ~Application();
/**
* \~chinese
* @brief
* @details
*/
virtual void OnReady();
/**
* \~chinese
* @brief
* @details
*/
virtual void OnDestroy();
/**
* \~chinese
* @brief
* @details OnReady
* @param[in] runner
* @param debug
* @note
*/
void Run(bool debug = false);
void Run(Runner& runner, bool debug = false);
/**
* \~chinese
@ -107,7 +95,7 @@ public:
* @details 线 Kiwano
* @param func
*/
static void PreformInMainThread(Function<void()> func);
void PreformInMainThread(Function<void()> func);
private:
/**
@ -123,15 +111,15 @@ private:
void Render();
private:
bool quiting_;
float time_scale_;
Time last_update_time_;
Vector<ComponentBase*> comps_;
Vector<RenderComponent*> render_comps_;
Vector<UpdateComponent*> update_comps_;
Vector<EventComponent*> event_comps_;
std::mutex perform_mutex_;
Queue<Function<void()>> functions_to_perform_;
};
inline void Application::OnReady() {}
inline void Application::OnDestroy() {}
} // namespace kiwano

View File

@ -70,6 +70,11 @@ bool Window::ShouldClose()
return should_close_;
}
void Window::SetShouldClose(bool should)
{
should_close_ = should;
}
void Window::PushEvent(EventPtr evt)
{
event_queue_.push(evt);

View File

@ -21,7 +21,6 @@
#pragma once
#include <kiwano/core/Common.h>
#include <kiwano/core/event/Event.h>
#include <kiwano/macros.h>
#include <kiwano/math/Math.h>
namespace kiwano
@ -158,6 +157,12 @@ public:
*/
bool ShouldClose();
/**
* \~chinese
* @brief
*/
void SetShouldClose(bool should);
/**
* \~chinese
* @brief

View File

@ -166,7 +166,7 @@ void WindowImpl::Create(String const& title, uint32_t width, uint32_t height, ui
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.lpszClassName = L"KiwanoAppWnd";
wcex.style = CS_HREDRAW | CS_VREDRAW /* | CS_DBLCLKS */;
wcex.lpfnWndProc = WindowImpl::WndProc;
wcex.lpfnWndProc = WindowImpl::StaticWndProc;
wcex.hIcon = nullptr;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = sizeof(LONG_PTR);
@ -437,25 +437,19 @@ void WindowImpl::SetActive(bool actived)
}
}
LRESULT CALLBACK WindowImpl::WndProc(HWND hwnd, UINT32 msg, WPARAM wparam, LPARAM lparam)
LRESULT WindowImpl::MessageProc(HWND hwnd, UINT32 msg, WPARAM wparam, LPARAM lparam)
{
WindowImpl* window = reinterpret_cast<WindowImpl*>(static_cast<LONG_PTR>(::GetWindowLongPtrW(hwnd, GWLP_USERDATA)));
if (window == nullptr)
{
return ::DefWindowProcW(hwnd, msg, wparam, lparam);
}
switch (msg)
{
case WM_KEYDOWN:
case WM_SYSKEYDOWN:
{
KeyCode key = window->key_map_[size_t(wparam)];
KeyCode key = this->key_map_[size_t(wparam)];
if (key != KeyCode::Unknown)
{
KeyDownEventPtr evt = new KeyDownEvent;
evt->code = key;
window->PushEvent(evt);
this->PushEvent(evt);
}
}
break;
@ -463,12 +457,12 @@ LRESULT CALLBACK WindowImpl::WndProc(HWND hwnd, UINT32 msg, WPARAM wparam, LPARA
case WM_KEYUP:
case WM_SYSKEYUP:
{
KeyCode key = window->key_map_[size_t(wparam)];
KeyCode key = this->key_map_[size_t(wparam)];
if (key != KeyCode::Unknown)
{
KeyUpEventPtr evt = new KeyUpEvent;
evt->code = key;
window->PushEvent(evt);
this->PushEvent(evt);
}
}
break;
@ -477,7 +471,7 @@ LRESULT CALLBACK WindowImpl::WndProc(HWND hwnd, UINT32 msg, WPARAM wparam, LPARA
{
KeyCharEventPtr evt = new KeyCharEvent;
evt->value = char(wparam);
window->PushEvent(evt);
this->PushEvent(evt);
}
break;
@ -504,7 +498,7 @@ LRESULT CALLBACK WindowImpl::WndProc(HWND hwnd, UINT32 msg, WPARAM wparam, LPARA
evt->button = MouseButton::Middle;
}
window->PushEvent(evt);
this->PushEvent(evt);
}
break;
@ -528,7 +522,7 @@ LRESULT CALLBACK WindowImpl::WndProc(HWND hwnd, UINT32 msg, WPARAM wparam, LPARA
evt->button = MouseButton::Middle;
}
window->PushEvent(evt);
this->PushEvent(evt);
}
break;
@ -536,7 +530,7 @@ LRESULT CALLBACK WindowImpl::WndProc(HWND hwnd, UINT32 msg, WPARAM wparam, LPARA
{
MouseMoveEventPtr evt = new MouseMoveEvent;
evt->pos = Point((float)GET_X_LPARAM(lparam), (float)GET_Y_LPARAM(lparam));
window->PushEvent(evt);
this->PushEvent(evt);
}
break;
@ -545,7 +539,7 @@ LRESULT CALLBACK WindowImpl::WndProc(HWND hwnd, UINT32 msg, WPARAM wparam, LPARA
MouseWheelEventPtr evt = new MouseWheelEvent;
evt->pos = Point((float)GET_X_LPARAM(lparam), (float)GET_Y_LPARAM(lparam));
evt->wheel = GET_WHEEL_DELTA_WPARAM(wparam) / (float)WHEEL_DELTA;
window->PushEvent(evt);
this->PushEvent(evt);
}
break;
@ -559,13 +553,13 @@ LRESULT CALLBACK WindowImpl::WndProc(HWND hwnd, UINT32 msg, WPARAM wparam, LPARA
{
// KGE_SYS_LOG("Window resized");
window->width_ = ((uint32_t)(short)LOWORD(lparam));
window->height_ = ((uint32_t)(short)HIWORD(lparam));
this->width_ = ((uint32_t)(short)LOWORD(lparam));
this->height_ = ((uint32_t)(short)HIWORD(lparam));
WindowResizedEventPtr evt = new WindowResizedEvent;
evt->width = window->GetWidth();
evt->height = window->GetHeight();
window->PushEvent(evt);
evt->width = this->GetWidth();
evt->height = this->GetHeight();
this->PushEvent(evt);
}
}
break;
@ -575,7 +569,7 @@ LRESULT CALLBACK WindowImpl::WndProc(HWND hwnd, UINT32 msg, WPARAM wparam, LPARA
WindowMovedEventPtr evt = new WindowMovedEvent;
evt->x = GET_X_LPARAM(lparam);
evt->y = GET_Y_LPARAM(lparam);
window->PushEvent(evt);
this->PushEvent(evt);
}
break;
@ -583,11 +577,11 @@ LRESULT CALLBACK WindowImpl::WndProc(HWND hwnd, UINT32 msg, WPARAM wparam, LPARA
{
bool active = (LOWORD(wparam) != WA_INACTIVE);
window->SetActive(active);
this->SetActive(active);
WindowFocusChangedEventPtr evt = new WindowFocusChangedEvent;
evt->focus = active;
window->PushEvent(evt);
this->PushEvent(evt);
}
break;
@ -595,11 +589,11 @@ LRESULT CALLBACK WindowImpl::WndProc(HWND hwnd, UINT32 msg, WPARAM wparam, LPARA
{
KGE_SYS_LOG("Window title changed");
window->title_ = WideToMultiByte(reinterpret_cast<LPCWSTR>(lparam));
this->title_ = WideToMultiByte(reinterpret_cast<LPCWSTR>(lparam));
WindowTitleChangedEventPtr evt = new WindowTitleChangedEvent;
evt->title = window->title_;
window->PushEvent(evt);
evt->title = this->title_;
this->PushEvent(evt);
}
break;
@ -619,7 +613,7 @@ LRESULT CALLBACK WindowImpl::WndProc(HWND hwnd, UINT32 msg, WPARAM wparam, LPARA
case WM_SETCURSOR:
{
window->UpdateCursor();
this->UpdateCursor();
}
break;
@ -628,8 +622,9 @@ LRESULT CALLBACK WindowImpl::WndProc(HWND hwnd, UINT32 msg, WPARAM wparam, LPARA
KGE_SYS_LOG("Window is closing");
WindowClosedEventPtr evt = new WindowClosedEvent;
window->PushEvent(evt);
window->Destroy();
this->PushEvent(evt);
this->SetShouldClose(true);
return 0;
}
break;
@ -646,6 +641,17 @@ LRESULT CALLBACK WindowImpl::WndProc(HWND hwnd, UINT32 msg, WPARAM wparam, LPARA
return ::DefWindowProcW(hwnd, msg, wparam, lparam);
}
LRESULT CALLBACK WindowImpl::StaticWndProc(HWND hwnd, UINT32 msg, WPARAM wparam, LPARAM lparam)
{
LONG_PTR ptr = static_cast<LONG_PTR>(::GetWindowLongPtrW(hwnd, GWLP_USERDATA));
if (ptr)
{
WindowImpl* window = reinterpret_cast<WindowImpl*>(ptr);
return window->MessageProc(hwnd, msg, wparam, lparam);
}
return ::DefWindowProcW(hwnd, msg, wparam, lparam);
}
} // namespace kiwano
#endif

View File

@ -62,7 +62,9 @@ private:
void SetActive(bool actived);
static LRESULT CALLBACK WndProc(HWND, UINT32, WPARAM, LPARAM);
LRESULT MessageProc(HWND, UINT32, WPARAM, LPARAM);
static LRESULT CALLBACK StaticWndProc(HWND, UINT32, WPARAM, LPARAM);
private:
bool resizable_;