diff --git a/projects/kiwano/kiwano.vcxproj b/projects/kiwano/kiwano.vcxproj
index e07983f0..8e09898c 100644
--- a/projects/kiwano/kiwano.vcxproj
+++ b/projects/kiwano/kiwano.vcxproj
@@ -22,7 +22,6 @@
-
@@ -61,9 +60,9 @@
+
-
@@ -136,6 +135,7 @@
+
diff --git a/projects/kiwano/kiwano.vcxproj.filters b/projects/kiwano/kiwano.vcxproj.filters
index daf84566..d470f726 100644
--- a/projects/kiwano/kiwano.vcxproj.filters
+++ b/projects/kiwano/kiwano.vcxproj.filters
@@ -285,9 +285,6 @@
render\DirectX
-
- platform\win32
-
core
@@ -297,12 +294,12 @@
render
-
- core
-
core
+
+ platform
+
@@ -512,5 +509,8 @@
core
+
+ platform
+
\ No newline at end of file
diff --git a/src/kiwano-imgui/ImGuiModule.cpp b/src/kiwano-imgui/ImGuiModule.cpp
index 3a7dbba2..396967e1 100644
--- a/src/kiwano-imgui/ImGuiModule.cpp
+++ b/src/kiwano-imgui/ImGuiModule.cpp
@@ -5,7 +5,7 @@
#include
#include
#include
-#include
+#include
#include
#include
#include
@@ -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
diff --git a/src/kiwano-imgui/ImGuiModule.h b/src/kiwano-imgui/ImGuiModule.h
index 0a5c34aa..1b17c59e 100644
--- a/src/kiwano-imgui/ImGuiModule.h
+++ b/src/kiwano-imgui/ImGuiModule.h
@@ -21,6 +21,7 @@
#pragma once
#include
#include
+#include
namespace kiwano
{
@@ -58,6 +59,9 @@ private:
void UpdateMousePos();
void UpdateMouseCursor();
+
+private:
+ WindowPtr window_;
};
} // namespace imgui
diff --git a/src/kiwano-network/HttpModule.h b/src/kiwano-network/HttpModule.h
index 8450fa0c..bb51b8f8 100644
--- a/src/kiwano-network/HttpModule.h
+++ b/src/kiwano-network/HttpModule.h
@@ -30,7 +30,7 @@ namespace network
{
/**
* \~chinese
- * \defgroup Network 网络通信
+ * \defgroup Network 网络模块
*/
/**
diff --git a/src/kiwano-physics/World.h b/src/kiwano-physics/World.h
index 6b5a4a49..1e635fc4 100644
--- a/src/kiwano-physics/World.h
+++ b/src/kiwano-physics/World.h
@@ -30,7 +30,7 @@ KGE_DECLARE_SMART_PTR(World);
/**
* \~chinese
- * \defgroup Physics 物理引擎
+ * \defgroup Physics 物理模块
*/
/**
diff --git a/src/kiwano/2d/Button.cpp b/src/kiwano/2d/Button.cpp
index 519b88f4..d112f4a3 100644
--- a/src/kiwano/2d/Button.cpp
+++ b/src/kiwano/2d/Button.cpp
@@ -20,7 +20,7 @@
#include
#include
-#include
+#include
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)
{
diff --git a/src/kiwano/kiwano.h b/src/kiwano/kiwano.h
index 38953e4f..af047772 100644
--- a/src/kiwano/kiwano.h
+++ b/src/kiwano/kiwano.h
@@ -105,10 +105,11 @@
// platform
//
+#include
+#include
#include
#include
#include
-#include
//
// utils
diff --git a/src/kiwano/platform/Application.cpp b/src/kiwano/platform/Application.cpp
index c3a3498d..efd45494 100644
--- a/src/kiwano/platform/Application.cpp
+++ b/src/kiwano/platform/Application.cpp
@@ -22,6 +22,7 @@
#include
#include
#include
+#include
#include
#include
@@ -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())
{
- if (auto update_comp = comp->Cast())
- {
- update_comp->OnUpdate(dt);
- }
+ update_comp->OnUpdate(scaled_dt);
}
}
diff --git a/src/kiwano/platform/Application.h b/src/kiwano/platform/Application.h
index 090aff07..49e6cad5 100644
--- a/src/kiwano/platform/Application.h
+++ b/src/kiwano/platform/Application.h
@@ -23,11 +23,10 @@
#include
#include
#include
-#include
#include
#include
+#include
#include
-#include
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 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 modules_;
+ RunnerPtr runner_;
+ List modules_;
std::mutex perform_mutex_;
Queue> 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
diff --git a/src/kiwano/platform/Runner.cpp b/src/kiwano/platform/Runner.cpp
new file mode 100644
index 00000000..d5f24c3f
--- /dev/null
+++ b/src/kiwano/platform/Runner.cpp
@@ -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
+#include
+
+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 on_ready, Function on_destroy)
+{
+ class CallbackRunner : public Runner
+ {
+ public:
+ void OnReady() override
+ {
+ if (on_ready)
+ on_ready();
+ }
+
+ void OnDestroy() override
+ {
+ if (on_destroy)
+ on_destroy();
+ }
+
+ Function on_ready;
+ Function on_destroy;
+ };
+
+ SmartPtr 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
diff --git a/src/kiwano/core/Runner.h b/src/kiwano/platform/Runner.h
similarity index 52%
rename from src/kiwano/core/Runner.h
rename to src/kiwano/platform/Runner.h
index 6752b5b9..7f4d5f51 100644
--- a/src/kiwano/core/Runner.h
+++ b/src/kiwano/platform/Runner.h
@@ -20,25 +20,36 @@
#pragma once
#include
+#include
+#include
namespace kiwano
{
+
+KGE_DECLARE_SMART_PTR(Runner);
+
/**
* \~chinese
* @brief 程序运行器
*/
-class KGE_API Runner
+class KGE_API Runner : public virtual ObjectBase
{
public:
- typedef Function 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 on_ready, Function 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
diff --git a/src/kiwano/platform/Window.cpp b/src/kiwano/platform/Window.cpp
index 01dd6820..35ccc97e 100644
--- a/src/kiwano/platform/Window.cpp
+++ b/src/kiwano/platform/Window.cpp
@@ -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_;
diff --git a/src/kiwano/platform/Window.h b/src/kiwano/platform/Window.h
index efcca5f6..526b63f3 100644
--- a/src/kiwano/platform/Window.h
+++ b/src/kiwano/platform/Window.h
@@ -20,12 +20,15 @@
#pragma once
#include
+#include
#include
#include
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 event_queue_;
};
diff --git a/src/kiwano/platform/win32/WindowImpl.cpp b/src/kiwano/platform/win32/WindowImpl.cpp
index 12c38bee..dab99056 100644
--- a/src/kiwano/platform/win32/WindowImpl.cpp
+++ b/src/kiwano/platform/win32/WindowImpl.cpp
@@ -18,37 +18,87 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
-#include
+#include
#if defined(KGE_WIN32)
-#include // GET_X_LPARAM, GET_Y_LPARAM
-#include // ImmAssociateContext
+#include
#include
#include
#include
#include
#include
#include
+#include // GET_X_LPARAM, GET_Y_LPARAM
+#include // 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 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(::GetWindowLongPtrW(hwnd, GWLP_USERDATA));
if (ptr)
{
- WindowImpl* window = reinterpret_cast(ptr);
+ WindowWin32Impl* window = reinterpret_cast(ptr);
return window->MessageProc(hwnd, msg, wparam, lparam);
}
return ::DefWindowProcW(hwnd, msg, wparam, lparam);
diff --git a/src/kiwano/platform/win32/WindowImpl.h b/src/kiwano/platform/win32/WindowImpl.h
deleted file mode 100644
index 65fff529..00000000
--- a/src/kiwano/platform/win32/WindowImpl.h
+++ /dev/null
@@ -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
-#include
-
-#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 key_map_;
-};
-
-} // namespace kiwano
-
-#endif
diff --git a/src/kiwano/render/DirectX/RendererImpl.cpp b/src/kiwano/render/DirectX/RendererImpl.cpp
index 494bdc91..6a7e5a78 100644
--- a/src/kiwano/render/DirectX/RendererImpl.cpp
+++ b/src/kiwano/render/DirectX/RendererImpl.cpp
@@ -22,7 +22,7 @@
#include
#include
#include
-#include
+#include
#include
#include
#include
@@ -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())
- {
- auto window_evt = dynamic_cast(evt);
- Resize(window_evt->width, window_evt->height);
- }
-}
-
HRESULT RendererImpl::HandleDeviceLost()
{
KGE_ASSERT(d3d_res_ && d2d_res_ && render_ctx_);
diff --git a/src/kiwano/render/DirectX/RendererImpl.h b/src/kiwano/render/DirectX/RendererImpl.h
index 2c010a2d..a9e1712d 100644
--- a/src/kiwano/render/DirectX/RendererImpl.h
+++ b/src/kiwano/render/DirectX/RendererImpl.h
@@ -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_;
diff --git a/src/kiwano/render/Renderer.cpp b/src/kiwano/render/Renderer.cpp
index 53904c2c..c9e3ed55 100644
--- a/src/kiwano/render/Renderer.cpp
+++ b/src/kiwano/render/Renderer.cpp
@@ -19,6 +19,8 @@
// THE SOFTWARE.
#include
+#include
+#include
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())
+ {
+ auto window_evt = dynamic_cast(evt);
+ Resize(window_evt->width, window_evt->height);
+ }
+}
+
} // namespace kiwano
diff --git a/src/kiwano/render/Renderer.h b/src/kiwano/render/Renderer.h
index 85c1f906..cfe67cc1 100644
--- a/src/kiwano/render/Renderer.h
+++ b/src/kiwano/render/Renderer.h
@@ -25,13 +25,14 @@
#include
#include
#include
+#include
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_;
};
/** @} */