From 1772a3baff9f478b0f38d4a757a41be94d14bd6d Mon Sep 17 00:00:00 2001 From: Simon Hardt Date: Sun, 6 Mar 2022 19:05:37 +0100 Subject: [PATCH] add: Widget registry --- .gitignore | 1 + frame/CMakeLists.txt | 5 +++ frame/src/ServiceLocator.cpp | 19 ++++++++++ frame/src/ServiceLocator.hpp | 40 +++++++++++++++++++++ frame/src/main.cpp | 9 +++-- frame/src/widgets/WidgetRegistry.cpp | 22 ++++++++++++ frame/src/widgets/WidgetRegistry.hpp | 52 ++++++++++++++++++++++++++++ frame/src/widgets/clock/Analog.cpp | 12 +++++-- 8 files changed, 155 insertions(+), 5 deletions(-) create mode 100644 frame/src/ServiceLocator.cpp create mode 100644 frame/src/ServiceLocator.hpp create mode 100644 frame/src/widgets/WidgetRegistry.cpp create mode 100644 frame/src/widgets/WidgetRegistry.hpp diff --git a/.gitignore b/.gitignore index 380dfe8..18cd728 100644 --- a/.gitignore +++ b/.gitignore @@ -35,3 +35,4 @@ build/* .vscode/* frame/src/Config.h +.editorconfig diff --git a/frame/CMakeLists.txt b/frame/CMakeLists.txt index a5eb74c..a9eb341 100644 --- a/frame/CMakeLists.txt +++ b/frame/CMakeLists.txt @@ -19,6 +19,9 @@ set(src src/ScreenManager.hpp src/ScreenManager.cpp + src/ServiceLocator.hpp + src/ServiceLocator.cpp + src/display/IDisplay.hpp src/display/Display.hpp src/display/Display.cpp @@ -33,6 +36,8 @@ set(src src/widgets/Widget.hpp src/widgets/Widget.cpp + src/widgets/WidgetRegistry.hpp + src/widgets/WidgetRegistry.cpp src/widgets/clock/Digital.hpp src/widgets/clock/Digital.cpp src/widgets/clock/Analog.hpp diff --git a/frame/src/ServiceLocator.cpp b/frame/src/ServiceLocator.cpp new file mode 100644 index 0000000..4a95f75 --- /dev/null +++ b/frame/src/ServiceLocator.cpp @@ -0,0 +1,19 @@ +#include "ServiceLocator.hpp" + +namespace frame +{ + + IService::IService(std::string_view name) + : name(name) + { + } + + std::string_view IService::getName() const + { + return name; + } + + std::unordered_map> + Service::Services = {}; + +} // namespace frame \ No newline at end of file diff --git a/frame/src/ServiceLocator.hpp b/frame/src/ServiceLocator.hpp new file mode 100644 index 0000000..9bd5b47 --- /dev/null +++ b/frame/src/ServiceLocator.hpp @@ -0,0 +1,40 @@ +#pragma once +#include +#include +#include +#include +#include + +namespace frame +{ + class IService + { + std::string name; + + public: + IService(std::string_view name); + virtual ~IService() = default; + + std::string_view getName() const; + }; + + class Service + { + static std::unordered_map> + Services; + + public: + template + static std::shared_ptr get() + { + auto const type = std::type_index(typeid(SERVICE)); + if(Services.find(type) == Services.end()) + { + Services[type] = std::make_shared(); + } + + return std::static_pointer_cast(Services[type]); + } + }; + +} // namespace frame \ No newline at end of file diff --git a/frame/src/main.cpp b/frame/src/main.cpp index 9065f03..affe3e4 100644 --- a/frame/src/main.cpp +++ b/frame/src/main.cpp @@ -9,8 +9,9 @@ using namespace std::chrono_literals; #include "ScreenManager.hpp" #include "display/Display.hpp" #include "font/Font.hpp" -#include "render/RenderTarget.hpp" -#include "widgets/clock/Analog.hpp" +//#include "render/RenderTarget.hpp" +//#include "widgets/clock/Analog.hpp" +#include "widgets/WidgetRegistry.hpp" int main() { @@ -25,7 +26,9 @@ int main() frame::ScreenManager screen(std::move(display)); - screen.setRoot(frame::widgets::AnalogClock::Create()); + auto const& widgets = frame::Service::get(); + + screen.setRoot(widgets->Create("AnalogClock")); screen.MainLoop(); } diff --git a/frame/src/widgets/WidgetRegistry.cpp b/frame/src/widgets/WidgetRegistry.cpp new file mode 100644 index 0000000..561f581 --- /dev/null +++ b/frame/src/widgets/WidgetRegistry.cpp @@ -0,0 +1,22 @@ +#include "WidgetRegistry.hpp" + +namespace frame::widgets +{ + + WidgetRegistry::WidgetRegistry() + : IService("WidgetRegistry") + { + } + + Widget::shared_ptr WidgetRegistry::Create(std::string_view name) const + { + auto it = mWidgets.find(std::string{name}); + if(it == mWidgets.end()) + { + fmt::print("[ERROR] Widget {} not found!\n", name); + return nullptr; + } + return it->second(); + } + +} // namespace frame::widgets \ No newline at end of file diff --git a/frame/src/widgets/WidgetRegistry.hpp b/frame/src/widgets/WidgetRegistry.hpp new file mode 100644 index 0000000..315d490 --- /dev/null +++ b/frame/src/widgets/WidgetRegistry.hpp @@ -0,0 +1,52 @@ +#pragma once +#include "../ServiceLocator.hpp" +#include "Widget.hpp" + +#include +#include +#include +#include + +#define REGISTER_WIDGET(TYPE, NAME) \ + static bool registered = \ + frame::Service::get()->Register( \ + NAME) + +namespace frame::widgets +{ + + class WidgetRegistry : public IService + { + + using Creator = std::function; + + std::unordered_map mWidgets; + + public: + WidgetRegistry(); + + template + bool Register(std::string_view name); + + Widget::shared_ptr Create(std::string_view name) const; + }; + + template + bool WidgetRegistry::Register(std::string_view name) + { + auto const name_string = std::string{name}; + if(mWidgets.find(name_string) != mWidgets.end()) + { + fmt::print("Widget {} already registered!\n", name); + return true; + } + + mWidgets[name_string] = []() -> Widget::shared_ptr { + return WIDGET::Create(); + }; + + fmt::print("Widget {} registered!\n", name); + return true; + } + +} // namespace frame::widgets \ No newline at end of file diff --git a/frame/src/widgets/clock/Analog.cpp b/frame/src/widgets/clock/Analog.cpp index 946b119..62119cb 100644 --- a/frame/src/widgets/clock/Analog.cpp +++ b/frame/src/widgets/clock/Analog.cpp @@ -5,6 +5,14 @@ constexpr double pi = 3.14159; +#include "../WidgetRegistry.hpp" +/* +static bool registerd = + frame::Service::get() + ->Register("AnalogClock");*/ + +REGISTER_WIDGET(frame::widgets::AnalogClock, "AnalogClock"); + namespace frame::widgets { @@ -72,8 +80,8 @@ namespace frame::widgets auto const min_rad = (min_steps * c_time->tm_min - 90) * pi / 180.f; rt.DrawLine(center, - {center.x + int32_t(std::cos(min_rad) * radius), - center.y + int32_t(std::sin(min_rad) * radius)}); + {center.x + int32_t(std::cos(min_rad) * radius * 0.8), + center.y + int32_t(std::sin(min_rad) * radius * 0.8)}); // Render Pointer Hour