aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/cru/platform/graph/graph_factory.hpp6
-rw-r--r--include/cru/platform/native/native_window.hpp4
-rw-r--r--include/cru/platform/native/ui_applicaition.hpp24
-rw-r--r--include/cru/ui/window.hpp6
-rw-r--r--include/cru/win/graph/win_graph_factory.hpp2
-rw-r--r--include/cru/win/native/win_application.hpp17
-rw-r--r--include/cru/win/native/win_native_window.hpp4
-rw-r--r--src/main.cpp4
-rw-r--r--src/ui/ui_manager.cpp2
-rw-r--r--src/ui/window.cpp2
-rw-r--r--src/win/native/win_application.cpp47
11 files changed, 69 insertions, 49 deletions
diff --git a/include/cru/platform/graph/graph_factory.hpp b/include/cru/platform/graph/graph_factory.hpp
index b2619e8d..60d4ed8a 100644
--- a/include/cru/platform/graph/graph_factory.hpp
+++ b/include/cru/platform/graph/graph_factory.hpp
@@ -15,10 +15,14 @@
namespace cru::platform::graph {
// Entry point of the graph module.
+// If you create a IUiApplication instance, then you should not create
+// IGraphFactory manually. IUiApplication will call
+// IGraphFactory::CreateInstance and set auto-delete to true.
+// The manual creation method of IGraphFactory provides a you a way to use graph
+// related tools without interact with actual ui like window system.
struct IGraphFactory : virtual Interface, virtual IAutoDelete {
// Create a platform-specific instance and save it as the global instance.
// Do not create the instance twice. Implements should assert for that.
- // After the
// After creating, get the instance by GetInstance.
static IGraphFactory* CreateInstance();
diff --git a/include/cru/platform/native/native_window.hpp b/include/cru/platform/native/native_window.hpp
index 0e076348..3a0fd3e1 100644
--- a/include/cru/platform/native/native_window.hpp
+++ b/include/cru/platform/native/native_window.hpp
@@ -10,7 +10,7 @@ struct IPainter;
}
namespace cru::platform::native {
-struct NativeWindow : public virtual Interface {
+struct INativeWindow : public virtual Interface {
// Return if the window is still valid, that is, hasn't been closed or
// destroyed.
virtual bool IsValid() = 0;
@@ -18,7 +18,7 @@ struct NativeWindow : public virtual Interface {
virtual void Close() = 0;
- virtual NativeWindow* GetParent() = 0;
+ virtual INativeWindow* GetParent() = 0;
virtual bool IsVisible() = 0;
virtual void SetVisible(bool is_visible) = 0;
diff --git a/include/cru/platform/native/ui_applicaition.hpp b/include/cru/platform/native/ui_applicaition.hpp
index 0188393e..655b8ea0 100644
--- a/include/cru/platform/native/ui_applicaition.hpp
+++ b/include/cru/platform/native/ui_applicaition.hpp
@@ -1,16 +1,28 @@
#pragma once
#include "cru/common/base.hpp"
+#include "cru/common/auto_delete.hpp"
+
#include <chrono>
#include <functional>
#include <vector>
namespace cru::platform::native {
-struct NativeWindow;
+struct INativeWindow;
+
+// The entry point of a ui application.
+// It will call IGraphFactory::CreateInstance during its creation
+// and set graph factory to be auto deleted. If you want to keep
+// the graph factory then you should manually set it to false after
+// creating the ui application.
+struct IUiApplication : virtual Interface, virtual IAutoDelete {
+ // Create a platform-specific instance and save it as the global instance.
+ // Do not create the instance twice. Implements should assert for that.
+ // After creating, get the instance by GetInstance.
+ static IUiApplication* CreateInstance();
-struct UiApplication : public virtual Interface {
- static UiApplication* CreateInstance();
- static UiApplication* GetInstance();
+ // Get the global instance. If it is not created, then return nullptr.
+ static IUiApplication* GetInstance();
virtual int Run() = 0;
virtual void Quit(int quite_code) = 0;
@@ -24,7 +36,7 @@ struct UiApplication : public virtual Interface {
const std::function<void()>& action) = 0;
virtual void CancelTimer(unsigned long id) = 0;
- virtual std::vector<NativeWindow*> GetAllWindow() = 0;
- virtual NativeWindow* CreateWindow(NativeWindow* parent) = 0;
+ virtual std::vector<INativeWindow*> GetAllWindow() = 0;
+ virtual INativeWindow* CreateWindow(INativeWindow* parent) = 0;
};
} // namespace cru::platform::ui
diff --git a/include/cru/ui/window.hpp b/include/cru/ui/window.hpp
index 140ac531..2ed05192 100644
--- a/include/cru/ui/window.hpp
+++ b/include/cru/ui/window.hpp
@@ -7,7 +7,7 @@
#include <vector>
namespace cru::platform::native {
-struct NativeWindow;
+struct INativeWindow;
}
namespace cru::ui {
@@ -39,7 +39,7 @@ class Window final : public ContentControl {
render::RenderObject* GetRenderObject() const override;
- platform::native::NativeWindow* GetNativeWindow() const { return native_window_; }
+ platform::native::INativeWindow* GetNativeWindow() const { return native_window_; }
Control* GetMouseHoverControl() const { return mouse_hover_control_; }
@@ -82,7 +82,7 @@ class Window final : public ContentControl {
const Point& point);
private:
- platform::native::NativeWindow* native_window_;
+ platform::native::INativeWindow* native_window_;
std::vector<EventRevokerGuard> event_revoker_guards_;
std::shared_ptr<render::WindowRenderObject> render_object_;
diff --git a/include/cru/win/graph/win_graph_factory.hpp b/include/cru/win/graph/win_graph_factory.hpp
index 02f1a0fc..2df7ed9a 100644
--- a/include/cru/win/graph/win_graph_factory.hpp
+++ b/include/cru/win/graph/win_graph_factory.hpp
@@ -8,7 +8,7 @@ namespace cru::win::graph {
class WinGraphFactory : public Object,
public virtual platform::graph::IGraphFactory,
public virtual IWinNativeFactory {
- friend IGraphFactory* ::cru::platform::graph::IGraphFactory::CreateInstance();
+ friend IGraphFactory* IGraphFactory::CreateInstance();
public:
static WinGraphFactory* GetInstance();
diff --git a/include/cru/win/native/win_application.hpp b/include/cru/win/native/win_application.hpp
index 5bdb753e..d3e705e1 100644
--- a/include/cru/win/native/win_application.hpp
+++ b/include/cru/win/native/win_application.hpp
@@ -11,14 +11,12 @@ class TimerManager;
class WindowManager;
class WinApplication : public Object,
- public virtual platform::native::UiApplication {
+ public virtual platform::native::IUiApplication {
+ friend IUiApplication* IUiApplication::CreateInstance();
public:
static WinApplication* GetInstance();
private:
- static WinApplication* instance;
-
- private:
explicit WinApplication(HINSTANCE h_instance);
public:
@@ -41,9 +39,12 @@ class WinApplication : public Object,
const std::function<void()>& action) override;
void CancelTimer(unsigned long id) override;
- std::vector<platform::native::NativeWindow*> GetAllWindow() override;
- platform::native::NativeWindow* CreateWindow(
- platform::native::NativeWindow* parent) override;
+ std::vector<platform::native::INativeWindow*> GetAllWindow() override;
+ platform::native::INativeWindow* CreateWindow(
+ platform::native::INativeWindow* parent) override;
+
+ bool IsAutoDelete() const override { return auto_delete_; }
+ void SetAutoDelete(bool value) override { auto_delete_ = value; }
HINSTANCE GetInstanceHandle() const { return h_instance_; }
@@ -52,6 +53,8 @@ class WinApplication : public Object,
WindowManager* GetWindowManager() const { return window_manager_.get(); }
private:
+ bool auto_delete_ = false;
+
HINSTANCE h_instance_;
std::shared_ptr<GodWindow> god_window_;
diff --git a/include/cru/win/native/win_native_window.hpp b/include/cru/win/native/win_native_window.hpp
index 272ca14b..0fafc7fd 100644
--- a/include/cru/win/native/win_native_window.hpp
+++ b/include/cru/win/native/win_native_window.hpp
@@ -13,7 +13,7 @@ class WindowManager;
class WindowRenderTarget;
class WinNativeWindow : public Object,
- public virtual platform::native::NativeWindow {
+ public virtual platform::native::INativeWindow {
public:
WinNativeWindow(WinApplication* application,
std::shared_ptr<WindowClass> window_class, DWORD window_style,
@@ -29,7 +29,7 @@ class WinNativeWindow : public Object,
void Close() override;
- NativeWindow* GetParent() override { return parent_window_; }
+ INativeWindow* GetParent() override { return parent_window_; }
bool IsVisible() override;
void SetVisible(bool is_visible) override;
diff --git a/src/main.cpp b/src/main.cpp
index ecaebda5..ee381430 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -5,7 +5,7 @@
#include "cru/ui/controls/text_block.hpp"
#include "cru/ui/window.hpp"
-using cru::platform::native::UiApplication;
+using cru::platform::native::IUiApplication;
using cru::ui::Rect;
using cru::ui::Thickness;
using cru::ui::Window;
@@ -21,7 +21,7 @@ int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
*/
int main() {
- auto application = UiApplication::GetInstance();
+ std::unique_ptr<IUiApplication> application(IUiApplication::CreateInstance());
const auto window = Window::CreateOverlapped();
diff --git a/src/ui/ui_manager.cpp b/src/ui/ui_manager.cpp
index 82b859c8..cc741ec5 100644
--- a/src/ui/ui_manager.cpp
+++ b/src/ui/ui_manager.cpp
@@ -20,7 +20,7 @@ PredefineResources::PredefineResources() {
UiManager* UiManager::GetInstance() {
static UiManager* instance = new UiManager();
- platform::native::UiApplication::GetInstance()->AddOnQuitHandler([] {
+ platform::native::IUiApplication::GetInstance()->AddOnQuitHandler([] {
delete instance;
instance = nullptr;
});
diff --git a/src/ui/window.cpp b/src/ui/window.cpp
index 1c035081..48f046f1 100644
--- a/src/ui/window.cpp
+++ b/src/ui/window.cpp
@@ -102,7 +102,7 @@ Window::Window(tag_overlapped_constructor) {
using namespace std::placeholders;
native_window_ =
- platform::native::UiApplication::GetInstance()->CreateWindow(nullptr);
+ platform::native::IUiApplication::GetInstance()->CreateWindow(nullptr);
render_object_.reset(new render::WindowRenderObject(this));
event_revoker_guards_.push_back(
diff --git a/src/win/native/win_application.cpp b/src/win/native/win_application.cpp
index 00a16ff1..586af331 100644
--- a/src/win/native/win_application.cpp
+++ b/src/win/native/win_application.cpp
@@ -11,26 +11,27 @@
#include <VersionHelpers.h>
#include <cassert>
-namespace cru::platform::native {
-UiApplication* UiApplication::GetInstance() {
- return win::native::WinApplication::GetInstance();
-}
-} // namespace cru::platform::native
-
namespace cru::win::native {
-WinApplication* WinApplication::instance = nullptr;
-
namespace {
-bool application_constructing = false;
+WinApplication* instance = nullptr;
}
+} // namespace cru::win::native
-WinApplication* WinApplication::GetInstance() {
- if (instance == nullptr && !application_constructing) {
- application_constructing = true;
- instance = new WinApplication(::GetModuleHandleW(nullptr));
- }
- return instance;
+namespace cru::platform::native {
+IUiApplication* IUiApplication::CreateInstance() {
+ auto& i = ::cru::win::native::instance; // avoid long namespace prefix
+ assert(i == nullptr);
+ i = new win::native::WinApplication(::GetModuleHandleW(nullptr));
+ return i;
+}
+
+IUiApplication* IUiApplication::GetInstance() {
+ return ::cru::win::native::instance;
}
+} // namespace cru::platform::native
+
+namespace cru::win::native {
+WinApplication* WinApplication::GetInstance() { return instance; }
WinApplication::WinApplication(HINSTANCE h_instance) : h_instance_(h_instance) {
assert(instance == nullptr);
@@ -38,7 +39,8 @@ WinApplication::WinApplication(HINSTANCE h_instance) : h_instance_(h_instance) {
if (!::IsWindows8OrGreater())
throw std::runtime_error("Must run on Windows 8 or later.");
- graph::WinGraphFactory::CreateInstance();
+ const auto graph_factory = platform::graph::IGraphFactory::CreateInstance();
+ graph_factory->SetAutoDelete(true);
god_window_ = std::make_shared<GodWindow>(this);
timer_manager_ = std::make_shared<TimerManager>(god_window_.get());
@@ -56,8 +58,7 @@ int WinApplication::Run() {
for (const auto& handler : quit_handlers_) handler();
- delete graph::WinGraphFactory::GetInstance();
- delete this;
+ if (auto_delete_) delete this;
return static_cast<int>(msg.wParam);
}
@@ -94,17 +95,17 @@ void WinApplication::CancelTimer(unsigned long id) {
timer_manager_->KillTimer(static_cast<UINT_PTR>(id));
}
-std::vector<platform::native::NativeWindow*> WinApplication::GetAllWindow() {
+std::vector<platform::native::INativeWindow*> WinApplication::GetAllWindow() {
const auto&& windows = window_manager_->GetAllWindows();
- std::vector<platform::native::NativeWindow*> result;
+ std::vector<platform::native::INativeWindow*> result;
for (const auto w : windows) {
- result.push_back(static_cast<platform::native::NativeWindow*>(w));
+ result.push_back(static_cast<platform::native::INativeWindow*>(w));
}
return result;
}
-platform::native::NativeWindow* WinApplication::CreateWindow(
- platform::native::NativeWindow* parent) {
+platform::native::INativeWindow* WinApplication::CreateWindow(
+ platform::native::INativeWindow* parent) {
WinNativeWindow* p = nullptr;
if (parent != nullptr) {
p = dynamic_cast<WinNativeWindow*>(parent);