add: Widget registry

This commit is contained in:
Simon Hardt
2022-03-06 19:05:37 +01:00
parent 243bf41e90
commit 1772a3baff
8 changed files with 155 additions and 5 deletions

1
.gitignore vendored
View File

@@ -35,3 +35,4 @@
build/* build/*
.vscode/* .vscode/*
frame/src/Config.h frame/src/Config.h
.editorconfig

View File

@@ -19,6 +19,9 @@ set(src
src/ScreenManager.hpp src/ScreenManager.hpp
src/ScreenManager.cpp src/ScreenManager.cpp
src/ServiceLocator.hpp
src/ServiceLocator.cpp
src/display/IDisplay.hpp src/display/IDisplay.hpp
src/display/Display.hpp src/display/Display.hpp
src/display/Display.cpp src/display/Display.cpp
@@ -33,6 +36,8 @@ set(src
src/widgets/Widget.hpp src/widgets/Widget.hpp
src/widgets/Widget.cpp src/widgets/Widget.cpp
src/widgets/WidgetRegistry.hpp
src/widgets/WidgetRegistry.cpp
src/widgets/clock/Digital.hpp src/widgets/clock/Digital.hpp
src/widgets/clock/Digital.cpp src/widgets/clock/Digital.cpp
src/widgets/clock/Analog.hpp src/widgets/clock/Analog.hpp

View File

@@ -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<std::type_index, std::shared_ptr<IService>>
Service::Services = {};
} // namespace frame

View File

@@ -0,0 +1,40 @@
#pragma once
#include <memory>
#include <string>
#include <typeindex>
#include <typeinfo>
#include <unordered_map>
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<std::type_index, std::shared_ptr<IService>>
Services;
public:
template<class SERVICE>
static std::shared_ptr<SERVICE> get()
{
auto const type = std::type_index(typeid(SERVICE));
if(Services.find(type) == Services.end())
{
Services[type] = std::make_shared<SERVICE>();
}
return std::static_pointer_cast<SERVICE>(Services[type]);
}
};
} // namespace frame

View File

@@ -9,8 +9,9 @@ using namespace std::chrono_literals;
#include "ScreenManager.hpp" #include "ScreenManager.hpp"
#include "display/Display.hpp" #include "display/Display.hpp"
#include "font/Font.hpp" #include "font/Font.hpp"
#include "render/RenderTarget.hpp" //#include "render/RenderTarget.hpp"
#include "widgets/clock/Analog.hpp" //#include "widgets/clock/Analog.hpp"
#include "widgets/WidgetRegistry.hpp"
int main() int main()
{ {
@@ -25,7 +26,9 @@ int main()
frame::ScreenManager screen(std::move(display)); frame::ScreenManager screen(std::move(display));
screen.setRoot(frame::widgets::AnalogClock::Create()); auto const& widgets = frame::Service::get<frame::widgets::WidgetRegistry>();
screen.setRoot(widgets->Create("AnalogClock"));
screen.MainLoop(); screen.MainLoop();
} }

View File

@@ -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

View File

@@ -0,0 +1,52 @@
#pragma once
#include "../ServiceLocator.hpp"
#include "Widget.hpp"
#include <fmt/format.h>
#include <functional>
#include <string>
#include <unordered_map>
#define REGISTER_WIDGET(TYPE, NAME) \
static bool registered = \
frame::Service::get<frame::widgets::WidgetRegistry>()->Register<TYPE>( \
NAME)
namespace frame::widgets
{
class WidgetRegistry : public IService
{
using Creator = std::function<Widget::shared_ptr()>;
std::unordered_map<std::string, Creator> mWidgets;
public:
WidgetRegistry();
template<class WIDGET>
bool Register(std::string_view name);
Widget::shared_ptr Create(std::string_view name) const;
};
template<class WIDGET>
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

View File

@@ -5,6 +5,14 @@
constexpr double pi = 3.14159; constexpr double pi = 3.14159;
#include "../WidgetRegistry.hpp"
/*
static bool registerd =
frame::Service::get<frame::widgets::WidgetRegistry>()
->Register<frame::widgets::AnalogClock>("AnalogClock");*/
REGISTER_WIDGET(frame::widgets::AnalogClock, "AnalogClock");
namespace frame::widgets namespace frame::widgets
{ {
@@ -72,8 +80,8 @@ namespace frame::widgets
auto const min_rad = (min_steps * c_time->tm_min - 90) * pi / 180.f; auto const min_rad = (min_steps * c_time->tm_min - 90) * pi / 180.f;
rt.DrawLine(center, rt.DrawLine(center,
{center.x + int32_t(std::cos(min_rad) * radius), {center.x + int32_t(std::cos(min_rad) * radius * 0.8),
center.y + int32_t(std::sin(min_rad) * radius)}); center.y + int32_t(std::sin(min_rad) * radius * 0.8)});
// Render Pointer Hour // Render Pointer Hour