aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/application.cpp13
-rw-r--r--src/application.hpp46
-rw-r--r--src/base.hpp8
-rw-r--r--src/graph/graph.cpp5
-rw-r--r--src/graph/graph.hpp15
-rw-r--r--src/timer.cpp15
-rw-r--r--src/timer.hpp6
-rw-r--r--src/ui/animations/animation.cpp10
-rw-r--r--src/ui/animations/animation.hpp10
-rw-r--r--src/ui/control.cpp1
-rw-r--r--src/ui/controls/text_box.cpp1
-rw-r--r--src/ui/layout_base.cpp6
-rw-r--r--src/ui/layout_base.hpp4
-rw-r--r--src/ui/window.cpp22
-rw-r--r--src/ui/window.hpp3
15 files changed, 93 insertions, 72 deletions
diff --git a/src/application.cpp b/src/application.cpp
index df99cab8..dce01b11 100644
--- a/src/application.cpp
+++ b/src/application.cpp
@@ -5,7 +5,6 @@
#include "ui/window.hpp"
#include "ui/cursor.hpp"
#include "graph/graph.hpp"
-#include "ui/animations/animation.hpp"
namespace cru {
constexpr auto god_window_class_name = L"GodWindowClass";
@@ -64,12 +63,12 @@ namespace cru {
case WM_TIMER:
{
const auto id = static_cast<UINT_PTR>(w_param);
- const auto action = application_->GetTimerManager()->GetAction(id);
+ const auto action = TimerManager::GetInstance()->GetAction(id);
if (action.has_value())
{
(action.value().second)();
if (!action.value().first)
- Application::GetInstance()->GetTimerManager()->KillTimer(id);
+ TimerManager::GetInstance()->KillTimer(id);
return 0;
}
break;
@@ -117,11 +116,6 @@ namespace cru {
instance_ = this;
- window_manager_ = std::make_unique<ui::WindowManager>();
- graph_manager_ = std::make_unique<graph::GraphManager>();
- timer_manager_ = std::make_unique<TimerManager>();
- animation_manager_ = std::make_unique<ui::animations::details::AnimationManager>();
-
god_window_ = std::make_unique<GodWindow>(this);
#ifdef CRU_DEBUG_LAYOUT
@@ -137,7 +131,8 @@ namespace cru {
Application::~Application()
{
- animation_manager_.reset();
+ for (auto i = singleton_list_.crbegin(); i != singleton_list_.crend(); ++i)
+ delete *i;
instance_ = nullptr;
}
diff --git a/src/application.hpp b/src/application.hpp
index fe38ba0f..7357bbaf 100644
--- a/src/application.hpp
+++ b/src/application.hpp
@@ -4,6 +4,8 @@
#include <memory>
#include <optional>
#include <functional>
+#include <typeindex>
+#include <type_traits>
#include "base.hpp"
@@ -86,25 +88,6 @@ namespace cru
int Run();
void Quit(int quit_code);
- ui::WindowManager* GetWindowManager() const
- {
- return window_manager_.get();
- }
-
- graph::GraphManager* GetGraphManager() const
- {
- return graph_manager_.get();
- }
-
- TimerManager* GetTimerManager() const
- {
- return timer_manager_.get();
- }
-
- ui::animations::details::AnimationManager* GetAnimationManager() const
- {
- return animation_manager_.get();
- }
HINSTANCE GetInstanceHandle() const
{
@@ -116,6 +99,23 @@ namespace cru
return god_window_.get();
}
+ // Resolve a singleton.
+ // All singletons will be delete in reverse order of resolve.
+ template<typename T, typename = std::enable_if_t<std::is_base_of_v<Object, T>>>
+ T* ResolveSingleton(const std::function<T*(Application*)>& creator)
+ {
+ const auto& index = std::type_index{typeid(T)};
+ const auto find_result = singleton_map_.find(index);
+ if (find_result != singleton_map_.cend())
+ return static_cast<T*>(find_result->second);
+
+ auto singleton = creator(this);
+ singleton_map_.emplace(index, static_cast<Object*>(singleton));
+ singleton_list_.push_back(singleton);
+ return singleton;
+ }
+
+
CaretInfo GetCaretInfo() const
{
return caret_info_;
@@ -130,14 +130,12 @@ namespace cru
private:
HINSTANCE h_instance_;
-
- std::unique_ptr<ui::WindowManager> window_manager_;
- std::unique_ptr<graph::GraphManager> graph_manager_;
- std::unique_ptr<TimerManager> timer_manager_;
- std::unique_ptr<ui::animations::details::AnimationManager> animation_manager_;
std::unique_ptr<GodWindow> god_window_;
+ std::unordered_map<std::type_index, Object*> singleton_map_;
+ std::list<Object*> singleton_list_; // used for reverse destroy.
+
#ifdef CRU_DEBUG_LAYOUT
DebugLayoutResource debug_layout_resource_;
#endif
diff --git a/src/base.hpp b/src/base.hpp
index d4a3548f..5d8cb9ce 100644
--- a/src/base.hpp
+++ b/src/base.hpp
@@ -5,19 +5,15 @@
#include <string>
-#include <type_traits>
#include <stdexcept>
-#include <memory>
#include <string_view>
#include <chrono>
#include <optional>
+// ReSharper disable once CppUnusedIncludeDirective
+#include <type_traits>
namespace cru
{
- template<typename T> struct is_shared_ptr : std::false_type {};
- template<typename T> struct is_shared_ptr<std::shared_ptr<T>> : std::true_type {};
- template<typename T> constexpr bool is_shared_ptr_v = is_shared_ptr<T>::value;
-
template<typename T> struct type_tag {};
//typedefs
diff --git a/src/graph/graph.cpp b/src/graph/graph.cpp
index febb7fee..d37b5e2d 100644
--- a/src/graph/graph.cpp
+++ b/src/graph/graph.cpp
@@ -116,7 +116,10 @@ namespace cru::graph
GraphManager* GraphManager::GetInstance()
{
- return Application::GetInstance()->GetGraphManager();
+ return Application::GetInstance()->ResolveSingleton<GraphManager>([](auto)
+ {
+ return new GraphManager{};
+ });
}
GraphManager::GraphManager()
diff --git a/src/graph/graph.hpp b/src/graph/graph.hpp
index 9ef2e4b8..b98db5f4 100644
--- a/src/graph/graph.hpp
+++ b/src/graph/graph.hpp
@@ -2,9 +2,9 @@
#include "system_headers.hpp"
#include <memory>
+#include <functional>
#include "base.hpp"
-#include "application.hpp"
namespace cru::graph
@@ -62,13 +62,14 @@ namespace cru::graph
float y;
};
- class GraphManager : public Object
+ class GraphManager final : public Object
{
public:
static GraphManager* GetInstance();
- public:
+ private:
GraphManager();
+ public:
GraphManager(const GraphManager& other) = delete;
GraphManager(GraphManager&& other) = delete;
GraphManager& operator=(const GraphManager& other) = delete;
@@ -135,12 +136,12 @@ namespace cru::graph
inline int DipToPixelX(const float dip_x)
{
- return DipToPixelInternal(dip_x, Application::GetInstance()->GetGraphManager()->GetDpi().x);
+ return DipToPixelInternal(dip_x, GraphManager::GetInstance()->GetDpi().x);
}
inline int DipToPixelY(const float dip_y)
{
- return DipToPixelInternal(dip_y, Application::GetInstance()->GetGraphManager()->GetDpi().y);
+ return DipToPixelInternal(dip_y, GraphManager::GetInstance()->GetDpi().y);
}
inline float DipToPixelInternal(const int pixel, const float dpi)
@@ -150,12 +151,12 @@ namespace cru::graph
inline float PixelToDipX(const int pixel_x)
{
- return DipToPixelInternal(pixel_x, Application::GetInstance()->GetGraphManager()->GetDpi().x);
+ return DipToPixelInternal(pixel_x, GraphManager::GetInstance()->GetDpi().x);
}
inline float PixelToDipY(const int pixel_y)
{
- return DipToPixelInternal(pixel_y, Application::GetInstance()->GetGraphManager()->GetDpi().y);
+ return DipToPixelInternal(pixel_y, GraphManager::GetInstance()->GetDpi().y);
}
Microsoft::WRL::ComPtr<ID2D1DeviceContext> WindowRenderTarget::GetD2DDeviceContext() const
diff --git a/src/timer.cpp b/src/timer.cpp
index 3d89d567..c839a48d 100644
--- a/src/timer.cpp
+++ b/src/timer.cpp
@@ -4,9 +4,12 @@
namespace cru
{
- inline TimerManager* GetTimerManager()
+ TimerManager* TimerManager::GetInstance()
{
- return Application::GetInstance()->GetTimerManager();
+ return Application::GetInstance()->ResolveSingleton<TimerManager>([](auto)
+ {
+ return new TimerManager{};
+ });
}
UINT_PTR TimerManager::CreateTimer(const UINT milliseconds, const bool loop, const TimerAction& action)
@@ -41,20 +44,20 @@ namespace cru
}
- void TimerTask::Cancel()
+ void TimerTask::Cancel() const
{
- GetTimerManager()->KillTimer(id_);
+ TimerManager::GetInstance()->KillTimer(id_);
}
TimerTask SetTimeout(std::chrono::milliseconds milliseconds, const TimerAction& action)
{
- const auto id = GetTimerManager()->CreateTimer(static_cast<UINT>(milliseconds.count()), false, action);
+ const auto id = TimerManager::GetInstance()->CreateTimer(static_cast<UINT>(milliseconds.count()), false, action);
return TimerTask(id);
}
TimerTask SetInterval(std::chrono::milliseconds milliseconds, const TimerAction& action)
{
- const auto id = GetTimerManager()->CreateTimer(static_cast<UINT>(milliseconds.count()), true, action);
+ const auto id = TimerManager::GetInstance()->CreateTimer(static_cast<UINT>(milliseconds.count()), true, action);
return TimerTask(id);
}
}
diff --git a/src/timer.hpp b/src/timer.hpp
index 5d6e8b71..3488db45 100644
--- a/src/timer.hpp
+++ b/src/timer.hpp
@@ -16,7 +16,11 @@ namespace cru
class TimerManager : public Object
{
public:
+ static TimerManager* GetInstance();
+
+ private:
TimerManager() = default;
+ public:
TimerManager(const TimerManager& other) = delete;
TimerManager(TimerManager&& other) = delete;
TimerManager& operator=(const TimerManager& other) = delete;
@@ -47,7 +51,7 @@ namespace cru
TimerTask& operator=(TimerTask&& other) = default;
~TimerTask() = default;
- void Cancel();
+ void Cancel() const;
private:
UINT_PTR id_;
diff --git a/src/ui/animations/animation.cpp b/src/ui/animations/animation.cpp
index 33c743cf..b1f92a3e 100644
--- a/src/ui/animations/animation.cpp
+++ b/src/ui/animations/animation.cpp
@@ -2,6 +2,8 @@
#include <utility>
+#include "application.hpp"
+
namespace cru::ui::animations
{
namespace details
@@ -66,6 +68,14 @@ namespace cru::ui::animations
AnimationTimeUnit current_time_ = AnimationTimeUnit::zero();
};
+ AnimationManager* AnimationManager::GetInstance()
+ {
+ return Application::GetInstance()->ResolveSingleton<AnimationManager>([](auto)
+ {
+ return new AnimationManager{};
+ });
+ }
+
AnimationManager::AnimationManager()
{
diff --git a/src/ui/animations/animation.hpp b/src/ui/animations/animation.hpp
index 99389f33..f25e4699 100644
--- a/src/ui/animations/animation.hpp
+++ b/src/ui/animations/animation.hpp
@@ -3,7 +3,6 @@
#include <unordered_map>
#include "base.hpp"
-#include "application.hpp"
#include "timer.hpp"
namespace cru::ui::animations
@@ -53,13 +52,10 @@ namespace cru::ui::animations
class AnimationManager : public Object
{
public:
- static AnimationManager* GetInstance()
- {
- return Application::GetInstance()->GetAnimationManager();
- }
-
- public:
+ static AnimationManager* GetInstance();
+ private:
AnimationManager();
+ public:
AnimationManager(const AnimationManager& other) = delete;
AnimationManager(AnimationManager&& other) = delete;
AnimationManager& operator=(const AnimationManager& other) = delete;
diff --git a/src/ui/control.cpp b/src/ui/control.cpp
index bb3e35f8..31910328 100644
--- a/src/ui/control.cpp
+++ b/src/ui/control.cpp
@@ -3,6 +3,7 @@
#include <algorithm>
#include "window.hpp"
+#include "application.hpp"
#include "graph/graph.hpp"
#include "exception.hpp"
#include "cru_debug.hpp"
diff --git a/src/ui/controls/text_box.cpp b/src/ui/controls/text_box.cpp
index 605e1a24..cb5d79a2 100644
--- a/src/ui/controls/text_box.cpp
+++ b/src/ui/controls/text_box.cpp
@@ -5,6 +5,7 @@
#include "graph/graph.hpp"
#include "exception.hpp"
+#include "application.hpp"
namespace cru::ui::controls
{
diff --git a/src/ui/layout_base.cpp b/src/ui/layout_base.cpp
index a384500a..5363c52b 100644
--- a/src/ui/layout_base.cpp
+++ b/src/ui/layout_base.cpp
@@ -8,8 +8,10 @@ namespace cru::ui
{
LayoutManager* LayoutManager::GetInstance()
{
- static LayoutManager layout_manager;
- return &layout_manager;
+ return Application::GetInstance()->ResolveSingleton<LayoutManager>([](auto)
+ {
+ return new LayoutManager{};
+ });
}
void LayoutManager::InvalidateControlPositionCache(Control * control)
diff --git a/src/ui/layout_base.hpp b/src/ui/layout_base.hpp
index 1c35f0b7..512301b7 100644
--- a/src/ui/layout_base.hpp
+++ b/src/ui/layout_base.hpp
@@ -147,9 +147,9 @@ namespace cru::ui
{
public:
static LayoutManager* GetInstance();
-
- public:
+ private:
LayoutManager() = default;
+ public:
LayoutManager(const LayoutManager& other) = delete;
LayoutManager(LayoutManager&& other) = delete;
LayoutManager& operator=(const LayoutManager& other) = delete;
diff --git a/src/ui/window.cpp b/src/ui/window.cpp
index e426bc78..349b78ff 100644
--- a/src/ui/window.cpp
+++ b/src/ui/window.cpp
@@ -31,7 +31,7 @@ namespace cru::ui
}
LRESULT __stdcall GeneralWndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) {
- auto window = Application::GetInstance()->GetWindowManager()->FromHandle(hWnd);
+ auto window = WindowManager::GetInstance()->FromHandle(hWnd);
LRESULT result;
if (window != nullptr && window->HandleWindowMessage(hWnd, Msg, wParam, lParam, result))
@@ -40,6 +40,14 @@ namespace cru::ui
return DefWindowProc(hWnd, Msg, wParam, lParam);
}
+ WindowManager* WindowManager::GetInstance()
+ {
+ return Application::GetInstance()->ResolveSingleton<WindowManager>([](auto)
+ {
+ return new WindowManager{};
+ });
+ }
+
WindowManager::WindowManager() {
general_window_class_ = std::make_unique<WindowClass>(
L"CruUIWindowClass",
@@ -106,20 +114,20 @@ namespace cru::ui
}
Window::Window() : Control(WindowConstructorTag{}, this), control_list_({ this }) {
- const auto app = Application::GetInstance();
+ const auto window_manager = WindowManager::GetInstance();
hwnd_ = CreateWindowEx(0,
- app->GetWindowManager()->GetGeneralWindowClass()->GetName(),
+ window_manager->GetGeneralWindowClass()->GetName(),
L"", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
- nullptr, nullptr, app->GetInstanceHandle(), nullptr
+ nullptr, nullptr, Application::GetInstance()->GetInstanceHandle(), nullptr
);
if (hwnd_ == nullptr)
throw std::runtime_error("Failed to create window.");
- app->GetWindowManager()->RegisterWindow(hwnd_, this);
+ window_manager->RegisterWindow(hwnd_, this);
- render_target_ = app->GetGraphManager()->CreateWindowRenderTarget(hwnd_);
+ render_target_ = graph::GraphManager::GetInstance()->CreateWindowRenderTarget(hwnd_);
SetCursor(cursors::arrow);
}
@@ -511,7 +519,7 @@ namespace cru::ui
}
void Window::OnDestroyInternal() {
- Application::GetInstance()->GetWindowManager()->UnregisterWindow(hwnd_);
+ WindowManager::GetInstance()->UnregisterWindow(hwnd_);
hwnd_ = nullptr;
}
diff --git a/src/ui/window.hpp b/src/ui/window.hpp
index 9f773f55..2609594d 100644
--- a/src/ui/window.hpp
+++ b/src/ui/window.hpp
@@ -44,7 +44,10 @@ namespace cru::ui
class WindowManager : public Object
{
public:
+ static WindowManager* GetInstance();
+ private:
WindowManager();
+ public:
WindowManager(const WindowManager& other) = delete;
WindowManager(WindowManager&& other) = delete;
WindowManager& operator=(const WindowManager& other) = delete;