Update Runner

This commit is contained in:
Nomango 2020-02-14 22:01:56 +08:00
parent 72f8fd5e12
commit 94915b87ff
20 changed files with 457 additions and 291 deletions

View File

@ -22,7 +22,6 @@
<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" />
@ -61,9 +60,9 @@
<ClInclude Include="..\..\src\kiwano\platform\Application.h" />
<ClInclude Include="..\..\src\kiwano\platform\FileSystem.h" />
<ClInclude Include="..\..\src\kiwano\platform\Input.h" />
<ClInclude Include="..\..\src\kiwano\platform\Runner.h" />
<ClInclude Include="..\..\src\kiwano\platform\win32\ComPtr.hpp" />
<ClInclude Include="..\..\src\kiwano\platform\win32\libraries.h" />
<ClInclude Include="..\..\src\kiwano\platform\win32\WindowImpl.h" />
<ClInclude Include="..\..\src\kiwano\platform\Window.h" />
<ClInclude Include="..\..\src\kiwano\render\Brush.h" />
<ClInclude Include="..\..\src\kiwano\render\Color.h" />
@ -136,6 +135,7 @@
<ClCompile Include="..\..\src\kiwano\platform\Application.cpp" />
<ClCompile Include="..\..\src\kiwano\platform\FileSystem.cpp" />
<ClCompile Include="..\..\src\kiwano\platform\Input.cpp" />
<ClCompile Include="..\..\src\kiwano\platform\Runner.cpp" />
<ClCompile Include="..\..\src\kiwano\platform\win32\libraries.cpp" />
<ClCompile Include="..\..\src\kiwano\platform\win32\WindowImpl.cpp" />
<ClCompile Include="..\..\src\kiwano\platform\Window.cpp" />

View File

@ -285,9 +285,6 @@
<ClInclude Include="..\..\src\kiwano\render\DirectX\RendererImpl.h">
<Filter>render\DirectX</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\platform\win32\WindowImpl.h">
<Filter>platform\win32</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\core\Exception.h">
<Filter>core</Filter>
</ClInclude>
@ -297,12 +294,12 @@
<ClInclude Include="..\..\src\kiwano\render\Layer.h">
<Filter>render</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\core\Runner.h">
<Filter>core</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\core\Module.h">
<Filter>core</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\platform\Runner.h">
<Filter>platform</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\src\kiwano\2d\Canvas.cpp">
@ -512,5 +509,8 @@
<ClCompile Include="..\..\src\kiwano\core\Module.cpp">
<Filter>core</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kiwano\platform\Runner.cpp">
<Filter>platform</Filter>
</ClCompile>
</ItemGroup>
</Project>

View File

@ -5,7 +5,7 @@
#include <kiwano/core/event/KeyEvent.h>
#include <kiwano/core/event/MouseEvent.h>
#include <kiwano/platform/Input.h>
#include <kiwano/platform/win32/WindowImpl.h>
#include <kiwano/platform/Application.h>
#include <kiwano/render/Renderer.h>
#include <kiwano-imgui/ImGuiModule.h>
#include <kiwano-imgui/imgui_impl/imgui_impl.h>
@ -29,12 +29,14 @@ void ImGuiModule::SetupModule()
// Setup Dear ImGui style
ImGui::StyleColorsDark();
window_ = Application::GetInstance().GetMainWindow();
// Setup Platform/Renderer bindings
io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional)
io.BackendFlags |=
ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used)
io.BackendPlatformName = "imgui_impl_win32";
io.ImeWindowHandle = WindowImpl::GetInstance().GetHandle();
io.ImeWindowHandle = window_->GetHandle();
// Keyboard mapping. ImGui will use those indices to peek into the io.KeysDown[] array that we will update during
// the application lifetime.
@ -174,7 +176,7 @@ void ImGuiModule::UpdateMousePos()
if (io.WantSetMousePos)
{
POINT pos = { (int)io.MousePos.x, (int)io.MousePos.y };
::ClientToScreen(WindowImpl::GetInstance().GetHandle(), &pos);
::ClientToScreen(window_->GetHandle(), &pos);
::SetCursorPos(pos.x, pos.y);
}
@ -216,7 +218,7 @@ void ImGuiModule::UpdateMouseCursor()
break;
}
Window::GetInstance().SetCursor(cursor);
window_->SetCursor(cursor);
}
} // namespace imgui

View File

@ -21,6 +21,7 @@
#pragma once
#include <kiwano/core/Common.h>
#include <kiwano/core/Module.h>
#include <kiwano/platform/Window.h>
namespace kiwano
{
@ -58,6 +59,9 @@ private:
void UpdateMousePos();
void UpdateMouseCursor();
private:
WindowPtr window_;
};
} // namespace imgui

View File

@ -30,7 +30,7 @@ namespace network
{
/**
* \~chinese
* \defgroup Network
* \defgroup Network
*/
/**

View File

@ -30,7 +30,7 @@ KGE_DECLARE_SMART_PTR(World);
/**
* \~chinese
* \defgroup Physics
* \defgroup Physics
*/
/**

View File

@ -20,7 +20,7 @@
#include <kiwano/2d/Button.h>
#include <kiwano/2d/Stage.h>
#include <kiwano/platform/Window.h>
#include <kiwano/platform/Application.h>
namespace kiwano
{
@ -73,14 +73,14 @@ void Button::SetStatus(Status status)
if (status == Status::Normal)
{
Window::GetInstance().SetCursor(CursorType::Arrow);
Application::GetInstance().GetMainWindow()->SetCursor(CursorType::Arrow);
if (mouse_out_callback_)
mouse_out_callback_(this);
}
else if (status == Status::Hover)
{
Window::GetInstance().SetCursor(CursorType::Hand);
Application::GetInstance().GetMainWindow()->SetCursor(CursorType::Hand);
if (old_status != Status::Pressed)
{

View File

@ -105,10 +105,11 @@
// platform
//
#include <kiwano/platform/Window.h>
#include <kiwano/platform/Runner.h>
#include <kiwano/platform/Application.h>
#include <kiwano/platform/FileSystem.h>
#include <kiwano/platform/Input.h>
#include <kiwano/platform/Window.h>
//
// utils

View File

@ -22,6 +22,7 @@
#include <kiwano/platform/Input.h>
#include <kiwano/core/Director.h>
#include <kiwano/core/Logger.h>
#include <kiwano/render/Renderer.h>
#include <kiwano/render/TextureCache.h>
#include <kiwano/utils/ResourceCache.h>
@ -39,8 +40,11 @@ Application::Application()
Application::~Application() {}
void Application::Run(Runner& runner, bool debug)
void Application::Run(Runner* runner, bool debug)
{
KGE_ASSERT(runner);
runner_ = runner;
// Setup all modules
for (auto c : modules_)
{
@ -54,38 +58,18 @@ void Application::Run(Runner& runner, bool debug)
}
// Everything is ready
runner.OnReady();
runner->OnReady();
runner->SetLastUpdateTime(Time::Now());
// Initialize variables
quiting_ = false;
last_update_time_ = Time::Now();
Window& window = Window::GetInstance();
quiting_ = false;
while (!quiting_)
{
if (window.ShouldClose())
{
if (runner.OnClosing())
break;
else
window.SetShouldClose(false);
}
while (EventPtr evt = window.PollEvent())
{
this->DispatchEvent(evt.get());
}
this->Update();
this->Render();
quiting_ = !runner->MainLoop();
}
// Destroy all resources
runner.OnDestroy();
runner->OnDestroy();
this->Destroy();
// Destroy window
window.Destroy();
}
void Application::Quit()
@ -123,7 +107,7 @@ void Application::SetTimeScale(float scale_factor)
time_scale_ = scale_factor;
}
void Application::Update()
void Application::Update(Duration dt)
{
// Before update
for (auto comp : modules_)
@ -155,18 +139,12 @@ void Application::Update()
}
// Updating
Duration scaled_dt = dt * time_scale_;
for (auto comp : modules_)
{
const Time now = Time::Now();
const Duration dt = (now - last_update_time_) * time_scale_;
last_update_time_ = now;
for (auto comp : modules_)
if (auto update_comp = comp->Cast<UpdateModule>())
{
if (auto update_comp = comp->Cast<UpdateModule>())
{
update_comp->OnUpdate(dt);
}
update_comp->OnUpdate(scaled_dt);
}
}

View File

@ -23,11 +23,10 @@
#include <kiwano/core/Common.h>
#include <kiwano/core/Module.h>
#include <kiwano/core/Time.h>
#include <kiwano/core/Runner.h>
#include <kiwano/core/Singleton.h>
#include <kiwano/core/event/Event.h>
#include <kiwano/platform/Runner.h>
#include <kiwano/platform/Window.h>
#include <kiwano/render/Renderer.h>
namespace kiwano
{
@ -47,11 +46,20 @@ public:
/**
* \~chinese
* @brief
* @param[in] runner
* @param runner
* @param debug
* @note
*/
void Run(Runner& runner, bool debug = false);
void Run(RunnerPtr runner, bool debug = false);
/**
* \~chinese
* @brief
* @param runner
* @param debug
* @note
*/
void Run(Runner* runner, bool debug = false);
/**
* \~chinese
@ -65,6 +73,18 @@ public:
*/
void Destroy();
/**
* \~chinese
* @brief
*/
RunnerPtr GetRunner() const;
/**
* \~chinese
* @brief
*/
WindowPtr GetMainWindow() const;
/**
* \~chinese
* @brief
@ -97,26 +117,42 @@ public:
*/
void PreformInMainThread(Function<void()> func);
private:
/**
* \~chinese
* @brief
* @param dt
*/
void Update();
void Update(Duration dt);
/**
* \~chinese
* @brief
* @brief
*/
void Render();
private:
bool quiting_;
float time_scale_;
Time last_update_time_;
List<Module*> modules_;
RunnerPtr runner_;
List<Module*> modules_;
std::mutex perform_mutex_;
Queue<Function<void()>> functions_to_perform_;
};
inline void Application::Run(RunnerPtr runner, bool debug)
{
this->Run(runner.get(), debug);
}
inline RunnerPtr Application::GetRunner() const
{
return runner_;
}
inline WindowPtr Application::GetMainWindow() const
{
KGE_ASSERT(runner_);
return runner_->GetMainWindow();
}
} // namespace kiwano

View File

@ -0,0 +1,100 @@
// 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.
#include <kiwano/platform/Runner.h>
#include <kiwano/platform/Application.h>
namespace kiwano
{
RunnerPtr Runner::Create(WindowPtr main_window)
{
RunnerPtr ptr = new (std::nothrow) Runner;
if (ptr)
{
ptr->SetMainWindow(main_window);
}
return ptr;
}
RunnerPtr Runner::Create(WindowPtr main_window, Function<void()> on_ready, Function<void()> on_destroy)
{
class CallbackRunner : public Runner
{
public:
void OnReady() override
{
if (on_ready)
on_ready();
}
void OnDestroy() override
{
if (on_destroy)
on_destroy();
}
Function<void()> on_ready;
Function<void()> on_destroy;
};
SmartPtr<CallbackRunner> ptr = new (std::nothrow) CallbackRunner;
if (ptr)
{
ptr->on_ready = on_ready;
ptr->on_destroy = on_destroy;
ptr->SetMainWindow(main_window);
}
return ptr;
}
Runner::Runner() {}
Runner::~Runner() {}
bool Runner::MainLoop()
{
if (main_window_->ShouldClose())
{
if (this->OnClosing())
return false;
main_window_->SetShouldClose(false);
}
Application& app = Application::GetInstance();
// Poll events
while (EventPtr evt = main_window_->PollEvent())
{
app.DispatchEvent(evt.get());
}
// Update & render
const Time now = Time::Now();
const Duration dt = (now - last_update_time_);
last_update_time_ = now;
app.Update(dt);
app.Render();
return true;
}
} // namespace kiwano

View File

@ -20,25 +20,36 @@
#pragma once
#include <kiwano/core/Common.h>
#include <kiwano/core/Timer.h>
#include <kiwano/platform/Window.h>
namespace kiwano
{
KGE_DECLARE_SMART_PTR(Runner);
/**
* \~chinese
* @brief
*/
class KGE_API Runner
class KGE_API Runner : public virtual ObjectBase
{
public:
typedef Function<void()> Callback;
/// \~chinese
/// @brief 创建程序运行器
/// @param main_window 主窗口
static RunnerPtr Create(WindowPtr main_window);
/// \~chinese
/// @brief 创建程序运行器
/// @param main_window 主窗口
/// @param on_ready 应用程序初始化完成后执行的回调函数
/// @param on_destroy 应用程序销毁时执行的回调函数
static RunnerPtr Create(WindowPtr main_window, Function<void()> on_ready, Function<void()> on_destroy = nullptr);
Runner();
/// \~chinese
/// @brief 构造程序运行器
/// @param on_ready 应用程序初始化完成后执行的回调函数
/// @param on_destroy 应用程序销毁时执行的回调函数
Runner(const Callback& on_ready, const Callback& on_destroy = nullptr);
virtual ~Runner();
/// \~chinese
/// @brief 初始化完成处理
@ -51,44 +62,65 @@ public:
virtual void OnDestroy();
/// \~chinese
/// @brief 窗口关闭处理
/// @details 重载该函数以处理用户关闭窗口时的行为,如保存用户数据等
/// @return 返回true允许用户关闭窗口,否则阻止窗口关闭
/// @brief 应用程序关闭处理
/// @details 重载该函数以处理用户关闭应用程序时的行为,如保存用户数据等
/// @return 返回true允许用户关闭程序,否则阻止程序关闭
virtual bool OnClosing();
/// \~chinese
/// @brief 应用程序主循环
/// @details 重载该函数以
/// @return 返回false退出主循环否则继续运行主循环
virtual bool MainLoop();
/// \~chinese
/// @brief 获取主窗口
WindowPtr GetMainWindow() const;
/// \~chinese
/// @brief 设置主窗口
void SetMainWindow(WindowPtr window);
/// \~chinese
/// @brief 获取上一次更新时间
Time GetLastUpdateTime() const;
/// \~chinese
/// @brief 设置上一次更新时间
void SetLastUpdateTime(Time time);
private:
Callback on_ready_;
Callback on_destroy_;
WindowPtr main_window_;
Time last_update_time_;
};
inline void Runner::OnReady() {}
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 void Runner::OnDestroy() {}
inline bool Runner::OnClosing()
{
return true;
}
inline WindowPtr Runner::GetMainWindow() const
{
return main_window_;
}
inline void Runner::SetMainWindow(WindowPtr window)
{
main_window_ = window;
}
inline Time Runner::GetLastUpdateTime() const
{
return last_update_time_;
}
inline void Runner::SetLastUpdateTime(Time time)
{
last_update_time_ = time;
}
} // namespace kiwano

View File

@ -24,13 +24,17 @@ namespace kiwano
{
Window::Window()
: should_close_(false)
: handle_(nullptr)
, should_close_(false)
, width_(0)
, height_(0)
{
}
Window::~Window() {}
Window::~Window()
{
Destroy();
}
EventPtr Window::PollEvent()
{
@ -65,6 +69,11 @@ uint32_t Window::GetHeight() const
return height_;
}
WindowHandle Window::GetHandle() const
{
return handle_;
}
bool Window::ShouldClose()
{
return should_close_;

View File

@ -20,12 +20,15 @@
#pragma once
#include <kiwano/core/Common.h>
#include <kiwano/core/ObjectBase.h>
#include <kiwano/core/event/Event.h>
#include <kiwano/math/Math.h>
namespace kiwano
{
KGE_DECLARE_SMART_PTR(Window);
/**
* \~chinese
* @brief
@ -43,19 +46,18 @@ enum class CursorType
};
#if defined(KGE_WIN32)
typedef HWND WindowHandle;
#endif
/**
* \~chinese
* @brief
*/
class KGE_API Window : protected Noncopyable
class KGE_API Window : public ObjectBase
{
public:
/**
* \~chinese
* @brief
*/
static Window& GetInstance();
/**
* \~chinese
* @brief
@ -67,8 +69,8 @@ public:
* @param fullscreen
* @throw std::system_error
*/
virtual void Create(String const& title, uint32_t width, uint32_t height, uint32_t icon = 0, bool resizable = false,
bool fullscreen = false) = 0;
static WindowPtr Create(String const& title, uint32_t width, uint32_t height, uint32_t icon = 0,
bool resizable = false, bool fullscreen = false);
/**
* \~chinese
@ -98,6 +100,12 @@ public:
*/
uint32_t GetHeight() const;
/**
* \~chinese
* @brief
*/
WindowHandle GetHandle() const;
/**
* \~chinese
* @brief
@ -146,11 +154,17 @@ public:
/**
* \~chinese
* @brief
* @param evt
* @brief
* @param evt
*/
void PushEvent(EventPtr evt);
/**
* \~chinese
* @brief
*/
virtual void PumpEvents() = 0;
/**
* \~chinese
* @brief
@ -172,14 +186,13 @@ public:
protected:
Window();
~Window();
virtual void PumpEvents() = 0;
virtual ~Window();
protected:
bool should_close_;
uint32_t width_;
uint32_t height_;
WindowHandle handle_;
String title_;
std::queue<EventPtr> event_queue_;
};

View File

@ -18,37 +18,87 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#include <kiwano/platform/win32/WindowImpl.h>
#include <kiwano/platform/Window.h>
#if defined(KGE_WIN32)
#include <Windowsx.h> // GET_X_LPARAM, GET_Y_LPARAM
#include <imm.h> // ImmAssociateContext
#include <kiwano/core/Keys.h>
#include <kiwano/core/Exception.h>
#include <kiwano/core/Logger.h>
#include <kiwano/core/event/KeyEvent.h>
#include <kiwano/core/event/MouseEvent.h>
#include <kiwano/core/event/WindowEvent.h>
#include <kiwano/platform/Application.h>
#include <Windowsx.h> // GET_X_LPARAM, GET_Y_LPARAM
#include <imm.h> // ImmAssociateContext
#pragma comment(lib, "imm32.lib")
#define WINDOW_FIXED_STYLE WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX
#define WINDOW_RESIZABLE_STYLE WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_SIZEBOX | WS_MAXIMIZEBOX
#define WINDOW_FULLSCREEN_STYLE WS_CLIPCHILDREN | WS_POPUP
namespace kiwano
{
Window& Window::GetInstance()
KGE_DECLARE_SMART_PTR(WindowWin32Impl);
class KGE_API WindowWin32Impl : public Window
{
return WindowImpl::GetInstance();
public:
WindowWin32Impl();
virtual ~WindowWin32Impl();
void Init(String const& title, uint32_t width, uint32_t height, uint32_t icon, bool resizable, bool fullscreen);
void SetTitle(String const& title) override;
void SetIcon(uint32_t icon_resource) override;
void Resize(uint32_t width, uint32_t height) override;
void SetFullscreen(bool fullscreen) override;
void SetCursor(CursorType cursor) override;
void Destroy() override;
void PumpEvents() override;
DWORD GetStyle() const;
void UpdateCursor();
void SetActive(bool actived);
LRESULT MessageProc(HWND, UINT32, WPARAM, LPARAM);
static LRESULT CALLBACK StaticWndProc(HWND, UINT32, WPARAM, LPARAM);
private:
bool resizable_;
bool is_fullscreen_;
wchar_t* device_name_;
CursorType mouse_cursor_;
std::array<KeyCode, 256> key_map_;
};
WindowPtr Window::Create(String const& title, uint32_t width, uint32_t height, uint32_t icon, bool resizable,
bool fullscreen)
{
WindowWin32ImplPtr ptr = new (std::nothrow) WindowWin32Impl;
if (ptr)
{
ptr->Init(title, width, height, icon, resizable, fullscreen);
}
return ptr;
}
WindowImpl& WindowImpl::GetInstance()
} // namespace kiwano
namespace kiwano
{
static WindowImpl instance;
return instance;
}
#define WINDOW_FIXED_STYLE WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX
#define WINDOW_RESIZABLE_STYLE WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_SIZEBOX | WS_MAXIMIZEBOX
#define WINDOW_FULLSCREEN_STYLE WS_CLIPCHILDREN | WS_POPUP
namespace
{
@ -106,9 +156,8 @@ void RestoreResolution(WCHAR* device_name)
}
} // namespace
WindowImpl::WindowImpl()
: handle_(nullptr)
, device_name_(nullptr)
WindowWin32Impl::WindowWin32Impl()
: device_name_(nullptr)
, is_fullscreen_(false)
, resizable_(false)
, mouse_cursor_(CursorType::Arrow)
@ -156,17 +205,17 @@ WindowImpl::WindowImpl()
key_map_[VK_F1 + i] = KeyCode(size_t(KeyCode::F1) + i);
}
WindowImpl::~WindowImpl() {}
WindowWin32Impl::~WindowWin32Impl() {}
void WindowImpl::Create(String const& title, uint32_t width, uint32_t height, uint32_t icon, bool resizable,
bool fullscreen)
void WindowWin32Impl::Init(String const& title, uint32_t width, uint32_t height, uint32_t icon, bool resizable,
bool fullscreen)
{
HINSTANCE hinst = GetModuleHandleW(nullptr);
WNDCLASSEX wcex = { 0 };
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.lpszClassName = L"KiwanoAppWnd";
wcex.style = CS_HREDRAW | CS_VREDRAW /* | CS_DBLCLKS */;
wcex.lpfnWndProc = WindowImpl::StaticWndProc;
wcex.lpfnWndProc = WindowWin32Impl::StaticWndProc;
wcex.hIcon = nullptr;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = sizeof(LONG_PTR);
@ -257,12 +306,7 @@ void WindowImpl::Create(String const& title, uint32_t width, uint32_t height, ui
}
}
HWND WindowImpl::GetHandle() const
{
return handle_;
}
void WindowImpl::PumpEvents()
void WindowWin32Impl::PumpEvents()
{
MSG msg;
while (::PeekMessageW(&msg, nullptr, 0, 0, PM_REMOVE))
@ -272,7 +316,7 @@ void WindowImpl::PumpEvents()
}
}
void WindowImpl::SetTitle(String const& title)
void WindowWin32Impl::SetTitle(String const& title)
{
if (handle_)
{
@ -281,7 +325,7 @@ void WindowImpl::SetTitle(String const& title)
}
}
void WindowImpl::SetIcon(uint32_t icon_resource)
void WindowWin32Impl::SetIcon(uint32_t icon_resource)
{
if (handle_)
{
@ -294,7 +338,7 @@ void WindowImpl::SetIcon(uint32_t icon_resource)
}
}
void WindowImpl::Resize(uint32_t width, uint32_t height)
void WindowWin32Impl::Resize(uint32_t width, uint32_t height)
{
if (handle_ && !is_fullscreen_)
{
@ -307,7 +351,7 @@ void WindowImpl::Resize(uint32_t width, uint32_t height)
}
}
void WindowImpl::SetFullscreen(bool fullscreen)
void WindowWin32Impl::SetFullscreen(bool fullscreen)
{
if (is_fullscreen_ != fullscreen)
{
@ -349,12 +393,12 @@ void WindowImpl::SetFullscreen(bool fullscreen)
}
}
void WindowImpl::SetCursor(CursorType cursor)
void WindowWin32Impl::SetCursor(CursorType cursor)
{
mouse_cursor_ = cursor;
}
void WindowImpl::Destroy()
void WindowWin32Impl::Destroy()
{
if (is_fullscreen_)
RestoreResolution(device_name_);
@ -374,12 +418,12 @@ void WindowImpl::Destroy()
Window::Destroy();
}
DWORD WindowImpl::GetStyle() const
DWORD WindowWin32Impl::GetStyle() const
{
return is_fullscreen_ ? (WINDOW_FULLSCREEN_STYLE) : (resizable_ ? (WINDOW_RESIZABLE_STYLE) : (WINDOW_FIXED_STYLE));
}
void WindowImpl::UpdateCursor()
void WindowWin32Impl::UpdateCursor()
{
LPTSTR win32_cursor = IDC_ARROW;
switch (mouse_cursor_)
@ -412,7 +456,7 @@ void WindowImpl::UpdateCursor()
::SetCursor(::LoadCursorW(nullptr, win32_cursor));
}
void WindowImpl::SetActive(bool actived)
void WindowWin32Impl::SetActive(bool actived)
{
if (!handle_)
return;
@ -437,7 +481,7 @@ void WindowImpl::SetActive(bool actived)
}
}
LRESULT WindowImpl::MessageProc(HWND hwnd, UINT32 msg, WPARAM wparam, LPARAM lparam)
LRESULT WindowWin32Impl::MessageProc(HWND hwnd, UINT32 msg, WPARAM wparam, LPARAM lparam)
{
switch (msg)
{
@ -553,7 +597,7 @@ LRESULT WindowImpl::MessageProc(HWND hwnd, UINT32 msg, WPARAM wparam, LPARAM lpa
{
// KGE_SYS_LOG("Window resized");
this->width_ = ((uint32_t)(short)LOWORD(lparam));
this->width_ = ((uint32_t)(short)LOWORD(lparam));
this->height_ = ((uint32_t)(short)HIWORD(lparam));
WindowResizedEventPtr evt = new WindowResizedEvent;
@ -641,12 +685,12 @@ LRESULT WindowImpl::MessageProc(HWND hwnd, UINT32 msg, WPARAM wparam, LPARAM lpa
return ::DefWindowProcW(hwnd, msg, wparam, lparam);
}
LRESULT CALLBACK WindowImpl::StaticWndProc(HWND hwnd, UINT32 msg, WPARAM wparam, LPARAM lparam)
LRESULT CALLBACK WindowWin32Impl::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);
WindowWin32Impl* window = reinterpret_cast<WindowWin32Impl*>(ptr);
return window->MessageProc(hwnd, msg, wparam, lparam);
}
return ::DefWindowProcW(hwnd, msg, wparam, lparam);

View File

@ -1,81 +0,0 @@
// Copyright (c) 2016-2020 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/platform/Window.h>
#include <kiwano/core/Keys.h>
#if defined(KGE_WIN32)
namespace kiwano
{
class KGE_API WindowImpl : public Window
{
public:
static WindowImpl& GetInstance();
HWND GetHandle() const;
void Create(String const& title, uint32_t width, uint32_t height, uint32_t icon, bool resizable,
bool fullscreen) override;
void SetTitle(String const& title) override;
void SetIcon(uint32_t icon_resource) override;
void Resize(uint32_t width, uint32_t height) override;
void SetFullscreen(bool fullscreen) override;
void SetCursor(CursorType cursor) override;
void Destroy() override;
private:
WindowImpl();
~WindowImpl();
void PumpEvents() override;
DWORD GetStyle() const;
void UpdateCursor();
void SetActive(bool actived);
LRESULT MessageProc(HWND, UINT32, WPARAM, LPARAM);
static LRESULT CALLBACK StaticWndProc(HWND, UINT32, WPARAM, LPARAM);
private:
bool resizable_;
bool is_fullscreen_;
wchar_t* device_name_;
HWND handle_;
CursorType mouse_cursor_;
std::array<KeyCode, 256> key_map_;
};
} // namespace kiwano
#endif

View File

@ -22,7 +22,7 @@
#include <kiwano/core/Logger.h>
#include <kiwano/core/event/WindowEvent.h>
#include <kiwano/platform/FileSystem.h>
#include <kiwano/platform/win32/WindowImpl.h>
#include <kiwano/platform/Application.h>
#include <kiwano/render/ShapeSink.h>
#include <kiwano/render/DirectX/TextureRenderContextImpl.h>
#include <kiwano/render/DirectX/RendererImpl.h>
@ -46,14 +46,14 @@ RendererImpl::RendererImpl()
render_ctx_ = new RenderContextImpl;
}
void RendererImpl::SetupModule()
void RendererImpl::MakeContextForWindow(WindowPtr window)
{
KGE_SYS_LOG("Creating device resources");
ThrowIfFailed(::CoInitialize(nullptr), "CoInitialize failed");
HWND target_window = WindowImpl::GetInstance().GetHandle();
output_size_ = Window::GetInstance().GetSize();
HWND target_window = window->GetHandle();
output_size_ = window->GetSize();
d2d_res_ = nullptr;
d3d_res_ = nullptr;
@ -115,7 +115,7 @@ void RendererImpl::SetupModule()
ThrowIfFailed(hr, "Create render resources failed");
}
void RendererImpl::DestroyModule()
void RendererImpl::Destroy()
{
KGE_SYS_LOG("Destroying device resources");
@ -168,15 +168,6 @@ void RendererImpl::Present()
ThrowIfFailed(hr, "Unexpected DXGI exception");
}
void RendererImpl::HandleEvent(Event* evt)
{
if (evt->IsType<WindowResizedEvent>())
{
auto window_evt = dynamic_cast<WindowResizedEvent*>(evt);
Resize(window_evt->width, window_evt->height);
}
}
HRESULT RendererImpl::HandleDeviceLost()
{
KGE_ASSERT(d3d_res_ && d2d_res_ && render_ctx_);

View File

@ -44,55 +44,55 @@ class KGE_API RendererImpl
public:
static RendererImpl& GetInstance();
void CreateTexture(Texture& texture, String const& file_path);
void CreateTexture(Texture& texture, String const& file_path) override;
void CreateTexture(Texture& texture, Resource const& resource);
void CreateTexture(Texture& texture, Resource const& resource) override;
void CreateGifImage(GifImage& gif, String const& file_path);
void CreateGifImage(GifImage& gif, String const& file_path) override;
void CreateGifImage(GifImage& gif, Resource const& resource);
void CreateGifImage(GifImage& gif, Resource const& resource) override;
void CreateGifImageFrame(GifImage::Frame& frame, GifImage const& gif, size_t frame_index);
void CreateGifImageFrame(GifImage::Frame& frame, GifImage const& gif, size_t frame_index) override;
void CreateFontCollection(Font& font, String const& file_path);
void CreateFontCollection(Font& font, String const& file_path) override;
void CreateFontCollection(Font& font, Resource const& res);
void CreateFontCollection(Font& font, Resource const& res) override;
void CreateTextFormat(TextLayout& layout);
void CreateTextFormat(TextLayout& layout) override;
void CreateTextLayout(TextLayout& layout);
void CreateTextLayout(TextLayout& layout) override;
void CreateLineShape(Shape& shape, Point const& begin_pos, Point const& end_pos);
void CreateLineShape(Shape& shape, Point const& begin_pos, Point const& end_pos) override;
void CreateRectShape(Shape& shape, Rect const& rect);
void CreateRectShape(Shape& shape, Rect const& rect) override;
void CreateRoundedRectShape(Shape& shape, Rect const& rect, Vec2 const& radius);
void CreateRoundedRectShape(Shape& shape, Rect const& rect, Vec2 const& radius) override;
void CreateEllipseShape(Shape& shape, Point const& center, Vec2 const& radius);
void CreateEllipseShape(Shape& shape, Point const& center, Vec2 const& radius) override;
void CreateShapeSink(ShapeSink& sink);
void CreateShapeSink(ShapeSink& sink) override;
void CreateBrush(Brush& brush, Color const& color);
void CreateBrush(Brush& brush, Color const& color) override;
void CreateBrush(Brush& brush, LinearGradientStyle const& style);
void CreateBrush(Brush& brush, LinearGradientStyle const& style) override;
void CreateBrush(Brush& brush, RadialGradientStyle const& style);
void CreateBrush(Brush& brush, RadialGradientStyle const& style) override;
void CreateStrokeStyle(StrokeStyle& stroke_style, CapStyle cap, LineJoinStyle line_join, const float* dash_array,
size_t dash_size, float dash_offset);
size_t dash_size, float dash_offset) override;
TextureRenderContextPtr CreateTextureRenderContext(const Size* desired_size = nullptr);
TextureRenderContextPtr CreateTextureRenderContext(const Size* desired_size = nullptr) override;
public:
void BeginDraw();
void BeginDraw() override;
void EndDraw();
void EndDraw() override;
void Clear();
void Clear() override;
void Present();
void Present() override;
RenderContext& GetContext();
RenderContext& GetContext() override;
/// \~chinese
/// @brief 获取Direct2D设备资源
@ -102,19 +102,18 @@ public:
/// @brief 获取Direct3D设备资源
ID3DDeviceResources* GetD3DDeviceResources();
public:
void SetupModule() override;
/// \~chinese
/// @brief 重设渲染输出大小
void Resize(uint32_t width, uint32_t height) override;
void DestroyModule() override;
void HandleEvent(Event* evt) override;
private:
protected:
RendererImpl();
HRESULT HandleDeviceLost();
void MakeContextForWindow(WindowPtr window) override;
void Resize(uint32_t width, uint32_t height);
void Destroy() override;
HRESULT HandleDeviceLost();
private:
RenderContextImplPtr render_ctx_;

View File

@ -19,6 +19,8 @@
// THE SOFTWARE.
#include <kiwano/render/Renderer.h>
#include <kiwano/core/event/WindowEvent.h>
#include <kiwano/platform/Application.h>
namespace kiwano
{
@ -29,4 +31,24 @@ Renderer::Renderer()
{
}
void Renderer::SetupModule()
{
WindowPtr window = Application::GetInstance().GetMainWindow();
MakeContextForWindow(window);
}
void Renderer::DestroyModule()
{
Destroy();
}
void Renderer::HandleEvent(Event* evt)
{
if (evt->IsType<WindowResizedEvent>())
{
auto window_evt = dynamic_cast<WindowResizedEvent*>(evt);
Resize(window_evt->width, window_evt->height);
}
}
} // namespace kiwano

View File

@ -25,13 +25,14 @@
#include <kiwano/render/TextStyle.hpp>
#include <kiwano/render/RenderContext.h>
#include <kiwano/render/TextureRenderContext.h>
#include <kiwano/platform/Window.h>
namespace kiwano
{
/**
* \~chinese
* \defgroup Render
* \defgroup Render
*/
/**
@ -202,6 +203,14 @@ public:
virtual TextureRenderContextPtr CreateTextureRenderContext(const Size* desired_size = nullptr) = 0;
public:
/// \~chinese
/// @brief 获取渲染上下文
virtual RenderContext& GetContext() = 0;
/// \~chinese
/// @brief 获取渲染输出大小
virtual Size GetOutputSize() const;
/// \~chinese
/// @brief 开始渲染
virtual void BeginDraw() = 0;
@ -220,20 +229,27 @@ public:
virtual void Present() = 0;
/// \~chinese
/// @brief 获取渲染上下文
virtual RenderContext& GetContext() = 0;
/// @brief 重设渲染输出大小
virtual void Resize(uint32_t width, uint32_t height) = 0;
/// \~chinese
/// @brief 获取渲染输出大小
virtual Size GetOutputSize() const;
public:
void SetupModule() override;
void DestroyModule() override;
void HandleEvent(Event* evt) override;
protected:
Renderer();
virtual void MakeContextForWindow(WindowPtr window) = 0;
virtual void Destroy() = 0;
protected:
bool vsync_;
Color clear_color_;
Size output_size_;
bool vsync_;
Color clear_color_;
Size output_size_;
};
/** @} */