From d153f31a742f3da9b8ec63900ddbd3a16e04389d Mon Sep 17 00:00:00 2001 From: Nomango Date: Tue, 30 Jul 2019 15:27:01 +0800 Subject: [PATCH] refactor Singleton --- kiwano-audio/src/Sound.cpp | 2 +- kiwano-imgui/src/ImGuiModule.cpp | 16 +++++++------- kiwano-imgui/src/imgui_impl.h | 4 ++-- kiwano/2d/Canvas.cpp | 14 ++++++------- kiwano/2d/DebugNode.cpp | 12 +++++------ kiwano/2d/Geometry.cpp | 12 +++++------ kiwano/2d/GeometryNode.cpp | 4 ++-- kiwano/2d/GifImage.cpp | 8 +++---- kiwano/2d/Image.cpp | 4 ++-- kiwano/2d/Layer.cpp | 2 +- kiwano/2d/Node.cpp | 4 ++-- kiwano/2d/Scene.cpp | 2 +- kiwano/2d/Sprite.cpp | 2 +- kiwano/2d/Text.cpp | 8 +++---- kiwano/2d/Transition.cpp | 24 ++++++++++----------- kiwano/base/logs.h | 8 +++---- kiwano/common/Singleton.hpp | 36 +++++++++++++++++++++++++++----- kiwano/platform/Application.cpp | 27 +++++++++++------------- kiwano/platform/Application.h | 4 ---- kiwano/renderer/render.cpp | 6 +++--- kiwano/ui/Button.cpp | 4 ++-- samples/ImGuiSample/MainScene.h | 2 +- samples/ImGuiSample/main.cpp | 2 +- samples/Samples/Demo2.h | 14 ++++++------- samples/Samples/Demo3.h | 8 +++---- samples/Samples/Demo5.h | 20 +++++++++--------- samples/Samples/main.cpp | 6 +++--- 27 files changed, 137 insertions(+), 118 deletions(-) diff --git a/kiwano-audio/src/Sound.cpp b/kiwano-audio/src/Sound.cpp index 70e25190..96f9d02d 100644 --- a/kiwano-audio/src/Sound.cpp +++ b/kiwano-audio/src/Sound.cpp @@ -79,7 +79,7 @@ namespace kiwano return false; } - hr = Audio::Instance().CreateVoice(&voice_, transcoder.GetWaveFormatEx()); + hr = Audio::Instance()->CreateVoice(&voice_, transcoder.GetWaveFormatEx()); if (FAILED(hr)) { if (wave_data_) diff --git a/kiwano-imgui/src/ImGuiModule.cpp b/kiwano-imgui/src/ImGuiModule.cpp index 0d820192..d74b96d4 100644 --- a/kiwano-imgui/src/ImGuiModule.cpp +++ b/kiwano-imgui/src/ImGuiModule.cpp @@ -39,9 +39,9 @@ namespace kiwano //ImGui::StyleColorsClassic(); // Setup Platform/Renderer bindings - Init(app->GetWindow()->GetHandle()); + Init(Window::Instance()->GetHandle()); - target_window_ = Renderer::Instance().GetTargetWindow(); + target_window_ = Renderer::Instance()->GetTargetWindow(); } void ImGuiModule::DestroyComponent() @@ -58,9 +58,9 @@ namespace kiwano io.DeltaTime = dt; // Read keyboard modifiers inputs - io.KeyCtrl = Input::Instance().IsDown(KeyCode::Ctrl); - io.KeyShift = Input::Instance().IsDown(KeyCode::Shift); - io.KeyAlt = Input::Instance().IsDown(KeyCode::Alt); + io.KeyCtrl = Input::Instance()->IsDown(KeyCode::Ctrl); + io.KeyShift = Input::Instance()->IsDown(KeyCode::Shift); + io.KeyAlt = Input::Instance()->IsDown(KeyCode::Alt); io.KeySuper = false; // io.KeysDown[], io.MousePos, io.MouseDown[], io.MouseWheel: filled by the WndProc handler below. @@ -207,7 +207,7 @@ namespace kiwano KGE_ASSERT(io.Fonts->IsBuilt() && "Font atlas not built!"); // Setup display size (every frame to accommodate for window resizing) - Size display_size = Renderer::Instance().GetOutputSize(); + Size display_size = Renderer::Instance()->GetOutputSize(); io.DisplaySize = ImVec2(display_size.x, display_size.y); ImGui::NewFrame(); @@ -232,7 +232,7 @@ namespace kiwano ::SetCursorPos(pos.x, pos.y); } - Point pos = Input::Instance().GetMousePos(); + Point pos = Input::Instance()->GetMousePos(); io.MousePos = ImVec2(pos.x, pos.y); } @@ -254,7 +254,7 @@ namespace kiwano case ImGuiMouseCursor_Hand: cursor = MouseCursor::Hand; break; } - Window::Instance().SetMouseCursor(cursor); + Window::Instance()->SetMouseCursor(cursor); } void ImGuiModule::UpdateGamepads() { diff --git a/kiwano-imgui/src/imgui_impl.h b/kiwano-imgui/src/imgui_impl.h index b3e675aa..c1d3df34 100644 --- a/kiwano-imgui/src/imgui_impl.h +++ b/kiwano-imgui/src/imgui_impl.h @@ -6,7 +6,7 @@ #include "imgui_impl_dx11.h" -inline bool ImGui_Impl_Init(::kiwano::Renderer& renderer) { return ImGui_ImplDX11_Init(renderer.GetD3DDeviceResources()->GetDevice(), renderer.GetD3DDeviceResources()->GetDeviceContext()); } +inline bool ImGui_Impl_Init(::kiwano::Renderer* renderer) { return ImGui_ImplDX11_Init(renderer->GetD3DDeviceResources()->GetDevice(), renderer->GetD3DDeviceResources()->GetDeviceContext()); } inline void ImGui_Impl_Shutdown() { ImGui_ImplDX11_Shutdown(); } inline void ImGui_Impl_NewFrame() { ImGui_ImplDX11_NewFrame(); } inline void ImGui_Impl_RenderDrawData(ImDrawData* draw_data) { ImGui_ImplDX11_RenderDrawData(draw_data); } @@ -18,7 +18,7 @@ inline bool ImGui_Impl_CreateDeviceObjects() { return ImGui_ImplDX11_Cre #include "imgui_impl_dx10.h" -inline bool ImGui_Impl_Init(::kiwano::Renderer& renderer) { return ImGui_ImplDX10_Init(renderer.GetD3DDeviceResources()->GetDevice()); } +inline bool ImGui_Impl_Init(::kiwano::Renderer* renderer) { return ImGui_ImplDX10_Init(renderer->GetD3DDeviceResources()->GetDevice()); } inline void ImGui_Impl_Shutdown() { ImGui_ImplDX10_Shutdown(); } inline void ImGui_Impl_NewFrame() { ImGui_ImplDX10_NewFrame(); } inline void ImGui_Impl_RenderDrawData(ImDrawData* draw_data) { ImGui_ImplDX10_RenderDrawData(draw_data); } diff --git a/kiwano/2d/Canvas.cpp b/kiwano/2d/Canvas.cpp index 7bfd230b..55d88987 100644 --- a/kiwano/2d/Canvas.cpp +++ b/kiwano/2d/Canvas.cpp @@ -30,7 +30,7 @@ namespace kiwano : cache_expired_(false) , stroke_width_(1.0f) { - auto ctx = Renderer::Instance().GetD2DDeviceResources()->GetDeviceContext(); + auto ctx = Renderer::Instance()->GetD2DDeviceResources()->GetDeviceContext(); ThrowIfFailed( ctx->CreateCompatibleRenderTarget(&render_target_) @@ -98,7 +98,7 @@ namespace kiwano if (bitmap_cached_) { Rect bitmap_rect(0.f, 0.f, bitmap_cached_->GetSize().width, bitmap_cached_->GetSize().height); - Renderer::Instance().DrawBitmap( + Renderer::Instance()->DrawBitmap( bitmap_cached_, bitmap_rect, bitmap_rect @@ -123,7 +123,7 @@ namespace kiwano void Canvas::SetOutlineJoinStyle(StrokeStyle outline_join) { - outline_join_style_ = Renderer::Instance().GetD2DDeviceResources()->GetStrokeStyle(outline_join); + outline_join_style_ = Renderer::Instance()->GetD2DDeviceResources()->GetStrokeStyle(outline_join); } void Canvas::SetTextStyle(Font const& font, TextStyle const & text_style) @@ -136,7 +136,7 @@ namespace kiwano text_style_.outline, DX::ConvertToColorF(text_style_.outline_color), text_style_.outline_width, - Renderer::Instance().GetD2DDeviceResources()->GetStrokeStyle(text_style_.outline_stroke) + Renderer::Instance()->GetD2DDeviceResources()->GetStrokeStyle(text_style_.outline_stroke) ); // clear text format @@ -272,7 +272,7 @@ namespace kiwano if (!text_format_) { ThrowIfFailed( - Renderer::Instance().GetD2DDeviceResources()->CreateTextFormat( + Renderer::Instance()->GetD2DDeviceResources()->CreateTextFormat( text_format_, text_font_, text_style_ @@ -283,7 +283,7 @@ namespace kiwano ComPtr text_layout; Size layout_size; ThrowIfFailed( - Renderer::Instance().GetD2DDeviceResources()->CreateTextLayout( + Renderer::Instance()->GetD2DDeviceResources()->CreateTextLayout( text_layout, layout_size, text, @@ -392,7 +392,7 @@ namespace kiwano current_geometry_ = nullptr; ThrowIfFailed( - Renderer::Instance().GetD2DDeviceResources()->GetFactory()->CreatePathGeometry(¤t_geometry_) + Renderer::Instance()->GetD2DDeviceResources()->GetFactory()->CreatePathGeometry(¤t_geometry_) ); ThrowIfFailed( diff --git a/kiwano/2d/DebugNode.cpp b/kiwano/2d/DebugNode.cpp index 64870e76..bd5df4d4 100644 --- a/kiwano/2d/DebugNode.cpp +++ b/kiwano/2d/DebugNode.cpp @@ -51,12 +51,12 @@ namespace kiwano void DebugNode::OnRender() { - Renderer::Instance().SetTransform(Matrix{}); - Renderer::Instance().GetSolidColorBrush()->SetColor(D2D1::ColorF(0.0f, 0.0f, 0.0f, 0.5f)); + Renderer::Instance()->SetTransform(Matrix{}); + Renderer::Instance()->GetSolidColorBrush()->SetColor(D2D1::ColorF(0.0f, 0.0f, 0.0f, 0.5f)); - Renderer::Instance().GetD2DDeviceResources()->GetDeviceContext()->FillRectangle( + Renderer::Instance()->GetD2DDeviceResources()->GetDeviceContext()->FillRectangle( D2D1_RECT_F{ 10, 10, 30 + debug_text_->GetLayoutSize().x, 30 + debug_text_->GetLayoutSize().y }, - Renderer::Instance().GetSolidColorBrush() + Renderer::Instance()->GetSolidColorBrush() ); } @@ -77,9 +77,9 @@ namespace kiwano ss << "Objects: " << Object::__GetTracingObjects().size() << std::endl; #endif - ss << "Render: " << Renderer::Instance().GetStatus().duration.Milliseconds() << "ms" << std::endl; + ss << "Render: " << Renderer::Instance()->GetStatus().duration.Milliseconds() << "ms" << std::endl; - ss << "Primitives / sec: " << Renderer::Instance().GetStatus().primitives * frame_time_.size() << std::endl; + ss << "Primitives / sec: " << Renderer::Instance()->GetStatus().primitives * frame_time_.size() << std::endl; PROCESS_MEMORY_COUNTERS_EX pmc; GetProcessMemoryInfo(GetCurrentProcess(), (PROCESS_MEMORY_COUNTERS*)&pmc, sizeof(pmc)); diff --git a/kiwano/2d/Geometry.cpp b/kiwano/2d/Geometry.cpp index 2c3d89b0..5c2cfe63 100644 --- a/kiwano/2d/Geometry.cpp +++ b/kiwano/2d/Geometry.cpp @@ -128,7 +128,7 @@ namespace kiwano ComPtr path_geo; ComPtr path_sink; - HRESULT hr = Renderer::Instance().GetD2DDeviceResources()->GetFactory()->CreatePathGeometry(&path_geo); + HRESULT hr = Renderer::Instance()->GetD2DDeviceResources()->GetFactory()->CreatePathGeometry(&path_geo); if (SUCCEEDED(hr)) { @@ -185,7 +185,7 @@ namespace kiwano void RectangleGeometry::SetRect(Rect const & rect) { ComPtr geo; - auto factory = Renderer::Instance().GetD2DDeviceResources()->GetFactory(); + auto factory = Renderer::Instance()->GetD2DDeviceResources()->GetFactory(); if (SUCCEEDED(factory->CreateRectangleGeometry(DX::ConvertToRectF(rect), &geo))) { @@ -226,7 +226,7 @@ namespace kiwano void CircleGeometry::SetCircle(Point const & center, float radius) { ComPtr geo; - auto factory = Renderer::Instance().GetD2DDeviceResources()->GetFactory(); + auto factory = Renderer::Instance()->GetD2DDeviceResources()->GetFactory(); if (SUCCEEDED(factory->CreateEllipseGeometry( D2D1::Ellipse( @@ -274,7 +274,7 @@ namespace kiwano void EllipseGeometry::SetEllipse(Point const & center, float radius_x, float radius_y) { ComPtr geo; - auto factory = Renderer::Instance().GetD2DDeviceResources()->GetFactory(); + auto factory = Renderer::Instance()->GetD2DDeviceResources()->GetFactory(); if (SUCCEEDED(factory->CreateEllipseGeometry( D2D1::Ellipse( @@ -306,7 +306,7 @@ namespace kiwano { current_geometry_ = nullptr; - auto factory = Renderer::Instance().GetD2DDeviceResources()->GetFactory(); + auto factory = Renderer::Instance()->GetD2DDeviceResources()->GetFactory(); ThrowIfFailed( factory->CreatePathGeometry(¤t_geometry_) @@ -422,7 +422,7 @@ namespace kiwano void RoundedRectGeometry::SetRoundedRect(Rect const & rect, float radius_x, float radius_y) { ComPtr geo; - auto factory = Renderer::Instance().GetD2DDeviceResources()->GetFactory(); + auto factory = Renderer::Instance()->GetD2DDeviceResources()->GetFactory(); if (SUCCEEDED(factory->CreateRoundedRectangleGeometry( D2D1::RoundedRect( diff --git a/kiwano/2d/GeometryNode.cpp b/kiwano/2d/GeometryNode.cpp index b964efa8..8f29e7c1 100644 --- a/kiwano/2d/GeometryNode.cpp +++ b/kiwano/2d/GeometryNode.cpp @@ -70,12 +70,12 @@ namespace kiwano { if (geometry_ && geometry_->geo_) { - Renderer::Instance().FillGeometry( + Renderer::Instance()->FillGeometry( geometry_->geo_.Get(), fill_color_ ); - Renderer::Instance().DrawGeometry( + Renderer::Instance()->DrawGeometry( geometry_->geo_, stroke_color_, stroke_width_, diff --git a/kiwano/2d/GifImage.cpp b/kiwano/2d/GifImage.cpp index cc1414cd..e3f9fdb6 100644 --- a/kiwano/2d/GifImage.cpp +++ b/kiwano/2d/GifImage.cpp @@ -36,8 +36,8 @@ namespace kiwano , frame_position_{} , bg_color_{} { - factory_ = Renderer::Instance().GetD2DDeviceResources()->GetWICImagingFactory(); - auto ctx = Renderer::Instance().GetD2DDeviceResources()->GetDeviceContext(); + factory_ = Renderer::Instance()->GetD2DDeviceResources()->GetWICImagingFactory(); + auto ctx = Renderer::Instance()->GetD2DDeviceResources()->GetDeviceContext(); ThrowIfFailed( ctx->CreateCompatibleRenderTarget(&frame_rt_) @@ -157,7 +157,7 @@ namespace kiwano if (SUCCEEDED(frame_rt_->GetBitmap(&frame_to_render))) { Rect bounds = GetBounds(); - Renderer::Instance().DrawBitmap(frame_to_render, bounds, bounds); + Renderer::Instance()->DrawBitmap(frame_to_render, bounds, bounds); } } } @@ -192,7 +192,7 @@ namespace kiwano if (SUCCEEDED(hr)) { - auto ctx = Renderer::Instance().GetD2DDeviceResources()->GetDeviceContext(); + auto ctx = Renderer::Instance()->GetD2DDeviceResources()->GetDeviceContext(); // Create a D2DBitmap from IWICBitmapSource raw_frame_.Reset(); diff --git a/kiwano/2d/Image.cpp b/kiwano/2d/Image.cpp index 59c9449c..c1f07bdf 100644 --- a/kiwano/2d/Image.cpp +++ b/kiwano/2d/Image.cpp @@ -69,11 +69,11 @@ namespace kiwano return false; } #endif - hr = Renderer::Instance().GetD2DDeviceResources()->CreateBitmapFromFile(bitmap, res.GetFileName()); + hr = Renderer::Instance()->GetD2DDeviceResources()->CreateBitmapFromFile(bitmap, res.GetFileName()); } else { - hr = Renderer::Instance().GetD2DDeviceResources()->CreateBitmapFromResource(bitmap, res); + hr = Renderer::Instance()->GetD2DDeviceResources()->CreateBitmapFromResource(bitmap, res); } if (FAILED(hr)) diff --git a/kiwano/2d/Layer.cpp b/kiwano/2d/Layer.cpp index e9d2483a..5f4c8ba4 100644 --- a/kiwano/2d/Layer.cpp +++ b/kiwano/2d/Layer.cpp @@ -27,7 +27,7 @@ namespace kiwano Layer::Layer() : swallow_(false) { - SetSize(Renderer::Instance().GetOutputSize()); + SetSize(Renderer::Instance()->GetOutputSize()); auto handler = MakeClosure(this, &Layer::HandleMessages); diff --git a/kiwano/2d/Node.cpp b/kiwano/2d/Node.cpp index 52d18492..99e9fd1a 100644 --- a/kiwano/2d/Node.cpp +++ b/kiwano/2d/Node.cpp @@ -638,8 +638,8 @@ namespace kiwano void VisualNode::PrepareRender() { - Renderer::Instance().SetTransform(transform_matrix_); - Renderer::Instance().SetOpacity(displayed_opacity_); + Renderer::Instance()->SetTransform(transform_matrix_); + Renderer::Instance()->SetOpacity(displayed_opacity_); } } diff --git a/kiwano/2d/Scene.cpp b/kiwano/2d/Scene.cpp index 1cfe6b47..5cb6e6a5 100644 --- a/kiwano/2d/Scene.cpp +++ b/kiwano/2d/Scene.cpp @@ -29,7 +29,7 @@ namespace kiwano scene_ = this; SetAnchor(0, 0); - SetSize(Renderer::Instance().GetOutputSize()); + SetSize(Renderer::Instance()->GetOutputSize()); } Scene::~Scene() diff --git a/kiwano/2d/Sprite.cpp b/kiwano/2d/Sprite.cpp index 5cd71e0d..413ab894 100644 --- a/kiwano/2d/Sprite.cpp +++ b/kiwano/2d/Sprite.cpp @@ -99,7 +99,7 @@ namespace kiwano { if (image_) { - Renderer::Instance().DrawImage(image_, GetBounds()); + Renderer::Instance()->DrawImage(image_, GetBounds()); } } } \ No newline at end of file diff --git a/kiwano/2d/Text.cpp b/kiwano/2d/Text.cpp index 945f59b4..ec382941 100644 --- a/kiwano/2d/Text.cpp +++ b/kiwano/2d/Text.cpp @@ -303,14 +303,14 @@ namespace kiwano if (text_layout_) { - Renderer::Instance().SetTextStyle( + Renderer::Instance()->SetTextStyle( style_.color, style_.outline, style_.outline_color, style_.outline_width, style_.outline_stroke ); - Renderer::Instance().DrawTextLayout(text_layout_); + Renderer::Instance()->DrawTextLayout(text_layout_); } } @@ -327,7 +327,7 @@ namespace kiwano return; ThrowIfFailed( - Renderer::Instance().GetD2DDeviceResources()->CreateTextFormat( + Renderer::Instance()->GetD2DDeviceResources()->CreateTextFormat( text_format_, font_, style_ @@ -335,7 +335,7 @@ namespace kiwano ); ThrowIfFailed( - Renderer::Instance().GetD2DDeviceResources()->CreateTextLayout( + Renderer::Instance()->GetD2DDeviceResources()->CreateTextLayout( text_layout_, layout_size_, text_, diff --git a/kiwano/2d/Transition.cpp b/kiwano/2d/Transition.cpp index 5329cdcb..13a380f8 100644 --- a/kiwano/2d/Transition.cpp +++ b/kiwano/2d/Transition.cpp @@ -66,18 +66,18 @@ namespace kiwano if (in_scene_) { ThrowIfFailed( - Renderer::Instance().CreateLayer(in_layer_) + Renderer::Instance()->CreateLayer(in_layer_) ); } if (out_scene_) { ThrowIfFailed( - Renderer::Instance().CreateLayer(out_layer_) + Renderer::Instance()->CreateLayer(out_layer_) ); } - window_size_ = Renderer::Instance().GetOutputSize(); + window_size_ = Renderer::Instance()->GetOutputSize(); out_layer_prop_ = in_layer_prop_ = LayerProperties{ Rect(Point(), window_size_),1.f }; } @@ -101,34 +101,34 @@ namespace kiwano void Transition::Render() { - auto& renderer = Renderer::Instance(); + auto renderer = Renderer::Instance(); if (out_scene_) { - renderer.PushClip( + renderer->PushClip( out_scene_->GetTransformMatrix(), window_size_ ); - renderer.PushLayer(out_layer_, out_layer_prop_); + renderer->PushLayer(out_layer_, out_layer_prop_); out_scene_->Render(); - renderer.PopLayer(); - renderer.PopClip(); + renderer->PopLayer(); + renderer->PopClip(); } if (in_scene_) { - renderer.PushClip( + renderer->PushClip( in_scene_->GetTransformMatrix(), window_size_ ); - renderer.PushLayer(in_layer_, in_layer_prop_); + renderer->PushLayer(in_layer_, in_layer_prop_); in_scene_->Render(); - renderer.PopLayer(); - renderer.PopClip(); + renderer->PopLayer(); + renderer->PopClip(); } } diff --git a/kiwano/base/logs.h b/kiwano/base/logs.h index 95729974..7f5bf9cd 100644 --- a/kiwano/base/logs.h +++ b/kiwano/base/logs.h @@ -27,18 +27,18 @@ #ifndef KGE_LOG # ifdef KGE_DEBUG -# define KGE_LOG(FORMAT, ...) kiwano::Logger::Instance().Messagef((FORMAT ## "\n"), __VA_ARGS__) +# define KGE_LOG(FORMAT, ...) kiwano::Logger::Instance()->Messagef((FORMAT ## "\n"), __VA_ARGS__) # else # define KGE_LOG __noop # endif #endif #ifndef KGE_WARNING_LOG -# define KGE_WARNING_LOG(FORMAT, ...) kiwano::Logger::Instance().Warningf((FORMAT ## "\n"), __VA_ARGS__) +# define KGE_WARNING_LOG(FORMAT, ...) kiwano::Logger::Instance()->Warningf((FORMAT ## "\n"), __VA_ARGS__) #endif #ifndef KGE_ERROR_LOG -# define KGE_ERROR_LOG(FORMAT, ...) kiwano::Logger::Instance().Errorf((FORMAT ## "\n"), __VA_ARGS__) +# define KGE_ERROR_LOG(FORMAT, ...) kiwano::Logger::Instance()->Errorf((FORMAT ## "\n"), __VA_ARGS__) #endif namespace kiwano @@ -274,7 +274,7 @@ namespace kiwano inline std::wostream& Logger::DefaultOutputColor(std::wostream& out) { - ::SetConsoleTextAttribute(::GetStdHandle(STD_OUTPUT_HANDLE), Logger::Instance().default_stdout_color_); + ::SetConsoleTextAttribute(::GetStdHandle(STD_OUTPUT_HANDLE), Logger::Instance()->default_stdout_color_); return out; } } diff --git a/kiwano/common/Singleton.hpp b/kiwano/common/Singleton.hpp index b3906c7b..a2ae5584 100644 --- a/kiwano/common/Singleton.hpp +++ b/kiwano/common/Singleton.hpp @@ -19,25 +19,41 @@ // THE SOFTWARE. #pragma once +#include +#include // Class that will implement the singleton mode, // must use the macro in its delare file #ifndef KGE_DECLARE_SINGLETON #define KGE_DECLARE_SINGLETON( CLASS ) \ - friend class ::kiwano::Singleton< CLASS > + friend ::kiwano::Singleton< CLASS >; \ + friend ::std::default_delete< CLASS > #endif namespace kiwano { template - class Singleton + struct Singleton { public: - static inline _Ty& Instance() + static inline _Ty* Instance() { - static _Ty instance; // Thread-safe - return instance; + if (!instance_) + { + std::call_once(once_, Init); + } + return instance_.get(); + } + + static inline void Init() + { + if (!instance_) instance_.reset(new (std::nothrow) _Ty); + } + + static inline void Destroy() + { + instance_.reset(); } protected: @@ -47,5 +63,15 @@ namespace kiwano Singleton(const Singleton&) = delete; Singleton& operator=(const Singleton&) = delete; + + private: + static std::once_flag once_; + static std::unique_ptr<_Ty> instance_; }; + + template + std::once_flag Singleton<_Ty>::once_; + + template + std::unique_ptr<_Ty> Singleton<_Ty>::instance_; } diff --git a/kiwano/platform/Application.cpp b/kiwano/platform/Application.cpp index 43297563..481fd2bf 100644 --- a/kiwano/platform/Application.cpp +++ b/kiwano/platform/Application.cpp @@ -49,17 +49,14 @@ namespace kiwano Application::Application() : end_(true) , inited_(false) - , main_window_(nullptr) , time_scale_(1.f) { ThrowIfFailed( ::CoInitialize(nullptr) ); - main_window_ = &Window::Instance(); - - Use(&Renderer::Instance()); - Use(&Input::Instance()); + Use(Renderer::Instance()); + Use(Input::Instance()); } Application::~Application() @@ -72,7 +69,7 @@ namespace kiwano void Application::Init(const Options& options) { ThrowIfFailed( - main_window_->Create( + Window::Instance()->Create( options.title, options.width, options.height, @@ -82,8 +79,8 @@ namespace kiwano ) ); - Renderer::Instance().SetClearColor(options.clear_color); - Renderer::Instance().SetVSyncEnabled(options.vsync); + Renderer::Instance()->SetClearColor(options.clear_color); + Renderer::Instance()->SetVSyncEnabled(options.vsync); // Setup all components for (Component* c : components_) @@ -94,7 +91,7 @@ namespace kiwano // Everything is ready OnStart(); - HWND hwnd = main_window_->GetHandle(); + HWND hwnd = Window::Instance()->GetHandle(); // disable imm ::ImmAssociateContext(hwnd, nullptr); @@ -107,7 +104,7 @@ namespace kiwano void Application::Run() { - HWND hwnd = main_window_->GetHandle(); + HWND hwnd = Window::Instance()->GetHandle(); if (!hwnd) throw std::exception("Calling Application::Run before Application::Init"); @@ -115,7 +112,7 @@ namespace kiwano if (hwnd) { end_ = false; - main_window_->Prepare(); + Window::Instance()->Prepare(); MSG msg = {}; while (::GetMessageW(&msg, nullptr, 0, 0) && !end_) @@ -221,12 +218,12 @@ namespace kiwano if (show) { debug_node_ = new DebugNode; - Renderer::Instance().SetCollectingStatus(true); + Renderer::Instance()->SetCollectingStatus(true); } else { debug_node_.Reset(); - Renderer::Instance().SetCollectingStatus(false); + Renderer::Instance()->SetCollectingStatus(false); } } @@ -448,7 +445,7 @@ namespace kiwano app->curr_scene_->Dispatch(evt); } - app->GetWindow()->UpdateWindowRect(); + Window::Instance()->UpdateWindowRect(); } } break; @@ -472,7 +469,7 @@ namespace kiwano { bool active = (LOWORD(wparam) != WA_INACTIVE); - app->GetWindow()->SetActive(active); + Window::Instance()->SetActive(active); if (app->curr_scene_) { diff --git a/kiwano/platform/Application.h b/kiwano/platform/Application.h index 439caf3a..840b8c08 100644 --- a/kiwano/platform/Application.h +++ b/kiwano/platform/Application.h @@ -117,9 +117,6 @@ namespace kiwano // 获取当前场景 ScenePtr GetCurrentScene(); - // 获取主窗口 - inline Window* GetWindow() const { return main_window_; } - // 设置时间缩放因子 void SetTimeScale( float scale_factor @@ -153,7 +150,6 @@ namespace kiwano NodePtr debug_node_; TransitionPtr transition_; - Window* main_window_; Array components_; }; } diff --git a/kiwano/renderer/render.cpp b/kiwano/renderer/render.cpp index d1478213..4a6a8638 100644 --- a/kiwano/renderer/render.cpp +++ b/kiwano/renderer/render.cpp @@ -21,7 +21,7 @@ #include "render.h" #include "../2d/Image.h" #include "../base/logs.h" -#include "../platform/Application.h" +#include "../base/window.h" namespace kiwano { @@ -45,7 +45,7 @@ namespace kiwano { KGE_LOG(L"Creating device resources"); - hwnd_ = app->GetWindow()->GetHandle(); + hwnd_ = Window::Instance()->GetHandle(); ThrowIfFailed(hwnd_ ? S_OK : E_FAIL); @@ -87,7 +87,7 @@ namespace kiwano CreateDeviceResources() ); - output_size_ = app->GetWindow()->GetSize(); + output_size_ = Window::Instance()->GetSize(); } void Renderer::DestroyComponent() diff --git a/kiwano/ui/Button.cpp b/kiwano/ui/Button.cpp index 7497bd30..699eff81 100644 --- a/kiwano/ui/Button.cpp +++ b/kiwano/ui/Button.cpp @@ -112,7 +112,7 @@ namespace kiwano if (evt.type == Event::MouseHover) { SetStatus(Status::Hover); - Window::Instance().SetMouseCursor(MouseCursor::Hand); + Window::Instance()->SetMouseCursor(MouseCursor::Hand); if (mouse_over_callback_) mouse_over_callback_(); @@ -120,7 +120,7 @@ namespace kiwano else if (evt.type == Event::MouseOut) { SetStatus(Status::Normal); - Window::Instance().SetMouseCursor(MouseCursor::Arrow); + Window::Instance()->SetMouseCursor(MouseCursor::Arrow); if (mouse_out_callback_) mouse_out_callback_(); diff --git a/samples/ImGuiSample/MainScene.h b/samples/ImGuiSample/MainScene.h index e9a2d0cd..c2e96205 100644 --- a/samples/ImGuiSample/MainScene.h +++ b/samples/ImGuiSample/MainScene.h @@ -59,7 +59,7 @@ public: ImGui::End(); // 修改窗口背景色 - Renderer::Instance().SetClearColor(clear_color); + Renderer::Instance()->SetClearColor(clear_color); } void AnotherWindow() diff --git a/samples/ImGuiSample/main.cpp b/samples/ImGuiSample/main.cpp index b821cc61..4a0834cb 100644 --- a/samples/ImGuiSample/main.cpp +++ b/samples/ImGuiSample/main.cpp @@ -11,7 +11,7 @@ public: ImGuiApp() { // 添加 ImGui 组件 - Use(&ImGuiModule::Instance()); + Use(ImGuiModule::Instance()); // 初始化 Options options(L"ImGui Demo", 1280, 800); diff --git a/samples/Samples/Demo2.h b/samples/Samples/Demo2.h index ae591942..d318632a 100644 --- a/samples/Samples/Demo2.h +++ b/samples/Samples/Demo2.h @@ -21,30 +21,30 @@ public: void OnUpdate(Duration dt) override { // 获取输入设备 - auto& input = Input::Instance(); + auto input = Input::Instance(); // 按下左右键 - if (input.IsDown(KeyCode::Left)) + if (input->IsDown(KeyCode::Left)) { this->Move(-2, 0); } - else if (input.IsDown(KeyCode::Right)) + else if (input->IsDown(KeyCode::Right)) { this->Move(2, 0); } // 按下上下键 - if (input.IsDown(KeyCode::Up)) + if (input->IsDown(KeyCode::Up)) { this->Move(0, -2); } - else if (input.IsDown(KeyCode::Down)) + else if (input->IsDown(KeyCode::Down)) { this->Move(0, 2); } // 按下鼠标左键,顺时针旋转角色 - if (input.IsDown(MouseButton::Left)) + if (input->IsDown(MouseButton::Left)) { // 获取当前旋转角度 float rotation = this->GetRotation(); @@ -53,7 +53,7 @@ public: } // 点击鼠标右键,隐藏或显示角色 - if (input.WasPressed(MouseButton::Right)) + if (input->WasPressed(MouseButton::Right)) { // 获取当前显示状态 bool visible = this->IsVisible(); diff --git a/samples/Samples/Demo3.h b/samples/Samples/Demo3.h index 139db5e6..2ea0073f 100644 --- a/samples/Samples/Demo3.h +++ b/samples/Samples/Demo3.h @@ -63,20 +63,20 @@ public: state_text->SetText(playing ? L"当前状态:正在播放" : L"当前状态:停止播放"); // 获取输入设备 - auto& input = Input::Instance(); + auto input = Input::Instance(); // 按空格键暂停或继续 - if (input.WasPressed(KeyCode::Space)) + if (input->WasPressed(KeyCode::Space)) { bgmusic->IsPlaying() ? bgmusic->Pause() : bgmusic->Resume(); } // 按上下键调整音量 - if (input.WasPressed(KeyCode::Up)) + if (input->WasPressed(KeyCode::Up)) { bgmusic->SetVolume(volume + 0.1f); } - else if (input.WasPressed(KeyCode::Down)) + else if (input->WasPressed(KeyCode::Down)) { bgmusic->SetVolume(volume - 0.1f); } diff --git a/samples/Samples/Demo5.h b/samples/Samples/Demo5.h index d64114bf..63b5cddd 100644 --- a/samples/Samples/Demo5.h +++ b/samples/Samples/Demo5.h @@ -33,13 +33,13 @@ public: void OnEnter() override { // 进入场景时打开控制台 - Logger::Instance().ShowConsole(true); + Logger::Instance()->ShowConsole(true); } void OnExit() override { // 退出场景时关闭控制台 - Logger::Instance().ShowConsole(false); + Logger::Instance()->ShowConsole(false); } void OnKeyDown(Event const& e) @@ -66,7 +66,7 @@ public: void SendGetRequest() { // 发送 GET 请求 - Logger::Instance().Println(L"Start to send GET request..."); + Logger::Instance()->Println(L"Start to send GET request..."); HttpRequestPtr request = new HttpRequest; // 设置请求 URL @@ -77,13 +77,13 @@ public: request->SetResponseCallback(MakeClosure(this, &Demo5::Complete)); // 发送 HTTP 请求 - HttpClient::Instance().Send(request); + HttpClient::Instance()->Send(request); } void SendPostRequest() { // 发送 POST 请求 - Logger::Instance().Println(L"Start to send POST request..."); + Logger::Instance()->Println(L"Start to send POST request..."); // 创建 JSON 格式的 POST 数据 Json request_data = { @@ -102,13 +102,13 @@ public: request->SetJsonData(request_data); request->SetResponseCallback(MakeClosure(this, &Demo5::Complete)); - HttpClient::Instance().Send(request); + HttpClient::Instance()->Send(request); } void SendPutRequest() { // 发送 PUT 请求 - Logger::Instance().Println(L"Start to send PUT request..."); + Logger::Instance()->Println(L"Start to send PUT request..."); // 创建 JSON 格式的 PUT 数据 Json request_data = Json::array({ 1, 2, 3 }); @@ -120,20 +120,20 @@ public: request->SetJsonData(request_data); request->SetResponseCallback(MakeClosure(this, &Demo5::Complete)); - HttpClient::Instance().Send(request); + HttpClient::Instance()->Send(request); } void SendDeleteRequest() { // 发送 DELETE 请求 - Logger::Instance().Println(L"Start to send DELETE request..."); + Logger::Instance()->Println(L"Start to send DELETE request..."); HttpRequestPtr request = new HttpRequest; request->SetUrl(L"http://httpbin.org/delete"); request->SetType(HttpRequest::Type::Delete); request->SetResponseCallback(MakeClosure(this, &Demo5::Complete)); - HttpClient::Instance().Send(request); + HttpClient::Instance()->Send(request); } void Complete(HttpRequestPtr request, HttpResponsePtr response) diff --git a/samples/Samples/main.cpp b/samples/Samples/main.cpp index 5d0096e9..d6c8f4a4 100644 --- a/samples/Samples/main.cpp +++ b/samples/Samples/main.cpp @@ -32,10 +32,10 @@ public: DemoApp() { // 使用 Audio 组件 - Use(&Audio::Instance()); + Use(Audio::Instance()); // 使用 HttpClient 组件 - Use(&HttpClient::Instance()); + Use(HttpClient::Instance()); Options options(L"Kiwano示例程序", WINDOW_WIDTH, WINDOW_HEIGHT); Init(options); @@ -53,7 +53,7 @@ public: s_CurrIndex = index; String title = s_Demos[index].title; - GetWindow()->SetTitle(L"Kiwano示例程序 - " + title); + Window::Instance()->SetTitle(L"Kiwano示例程序 - " + title); ScenePtr scene = s_Demos[index].Create(); EnterScene(scene);