From 62df36423b9ce0d88db13d8564bbfa45329e87b0 Mon Sep 17 00:00:00 2001 From: Michal Date: Sun, 17 May 2026 22:55:59 +0200 Subject: [PATCH 1/6] refactor: replace switch case in Parser::buildComponent with ComponentRegistry * replace some of includes with forward declarations * verify if Scene Objects contain only one component of given type --- include/parser/Parser.hpp | 10 +++- include/scene/Scene.hpp | 2 +- include/scene/SceneAll.hpp | 14 ----- include/scene/SceneObject.hpp | 6 +-- include/scene/components/BlinkComponent.hpp | 9 +++- .../scene/components/ComponentRegistry.hpp | 38 ++++++++++++++ protoFiles/tests/test_scene.pb | Bin 173 -> 160 bytes protoFiles/tests/test_scene.pbtxt | 6 --- src/CMakeLists.txt | 6 ++- src/parser/Parser.cpp | 49 ++++++------------ src/scene/components/BlinkComponent.cpp | 22 ++++++++ src/scene/components/ComponentRegistry.cpp | 17 ++++++ 12 files changed, 117 insertions(+), 62 deletions(-) delete mode 100644 include/scene/SceneAll.hpp create mode 100644 include/scene/components/ComponentRegistry.hpp create mode 100644 src/scene/components/BlinkComponent.cpp create mode 100644 src/scene/components/ComponentRegistry.cpp diff --git a/include/parser/Parser.hpp b/include/parser/Parser.hpp index a6f509e..d19fb98 100644 --- a/include/parser/Parser.hpp +++ b/include/parser/Parser.hpp @@ -5,8 +5,14 @@ #include #include -#include "neuronide.pb.h" -#include "scene/SceneAll.hpp" +class Scene; +class SceneObject; +class Component; + +namespace NeuronIDE { +class SceneObject; +class Component; +} // namespace NeuronIDE class Parser { public: diff --git a/include/scene/Scene.hpp b/include/scene/Scene.hpp index 8aeee55..77c6be5 100644 --- a/include/scene/Scene.hpp +++ b/include/scene/Scene.hpp @@ -5,7 +5,7 @@ #include #include -#include "SceneObject.hpp" +class SceneObject; class Scene { private: diff --git a/include/scene/SceneAll.hpp b/include/scene/SceneAll.hpp deleted file mode 100644 index 058318b..0000000 --- a/include/scene/SceneAll.hpp +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef SCENE_ALL_HPP -#define SCENE_ALL_HPP - -// 1. Główne struktury danych sceny -#include "Scene.hpp" -#include "SceneObject.hpp" - -// 2. Interfejs komponentu -#include "components/Component.hpp" - -// 3. Wszystkie konkretne komponenty -#include "components/BlinkComponent.hpp" - -#endif // SCENE_ALL_HPP \ No newline at end of file diff --git a/include/scene/SceneObject.hpp b/include/scene/SceneObject.hpp index 20c5424..9a14571 100644 --- a/include/scene/SceneObject.hpp +++ b/include/scene/SceneObject.hpp @@ -6,7 +6,7 @@ #include #include -#include "components/Component.hpp" +class Component; class SceneObject { public: @@ -23,9 +23,7 @@ class SceneObject { std::cout << " [SceneObject] Utworzono obiekt: " << name << "\n"; } - void setTransform(double posX, double posY, double width, double height, double rotation) { - transform = {posX, posY, width, height, rotation}; - } + void setTransform(Transform t) { transform = t; } void addComponent(std::unique_ptr comp) { components.push_back(std::move(comp)); } }; diff --git a/include/scene/components/BlinkComponent.hpp b/include/scene/components/BlinkComponent.hpp index 0964343..59816b2 100644 --- a/include/scene/components/BlinkComponent.hpp +++ b/include/scene/components/BlinkComponent.hpp @@ -2,16 +2,23 @@ #define BLINKCOMPONENT_HPP #include +#include #include "Component.hpp" +namespace NeuronIDE { +class Component; +} + class BlinkComponent : public Component { public: BlinkComponent(double freq) : blinkFrequencyHz(freq) { std::cout << " + [BlinkComponent] Utworzono z czestotliwoscia: " << blinkFrequencyHz << "Hz\n"; } - void setFrequency(double freq) { blinkFrequencyHz = freq; } + void setFrequency(double freq); + + static std::unique_ptr createBlinker(const NeuronIDE::Component& protoComp); private: double blinkFrequencyHz = 0.0; diff --git a/include/scene/components/ComponentRegistry.hpp b/include/scene/components/ComponentRegistry.hpp new file mode 100644 index 0000000..0c370f7 --- /dev/null +++ b/include/scene/components/ComponentRegistry.hpp @@ -0,0 +1,38 @@ +#ifndef COMPONENTREGISTRY_HPP +#define COMPONENTREGISTRY_HPP + +#include +#include +#include + +class Component; +namespace NeuronIDE { +class Component; +} + +using ComponentCreatorFunc = std::function(const NeuronIDE::Component&)>; + +class ComponentRegistry { + public: + ComponentRegistry(const ComponentRegistry&) = delete; + ComponentRegistry& operator=(const ComponentRegistry&) = delete; + + ComponentRegistry(ComponentRegistry&&) = delete; + ComponentRegistry& operator=(ComponentRegistry&&) = delete; + + static ComponentRegistry& instance() { + static ComponentRegistry instance; + return instance; + } + + void registerCreator(int typeId, ComponentCreatorFunc creator) { creators[typeId] = creator; } + + std::unique_ptr build(const NeuronIDE::Component& protoComp); + + private: + ComponentRegistry() = default; + + std::unordered_map creators; +}; + +#endif // COMPONENTREGISTRY_HPP \ No newline at end of file diff --git a/protoFiles/tests/test_scene.pb b/protoFiles/tests/test_scene.pb index 73e8e4ea370bee42c5dcad715f28c3247adff5c2..ed6cd4c8e423c9161d82dfefb9de6a10765bcb9d 100644 GIT binary patch delta 14 VcmZ3>xPWnjG^5Q#8Jmfz9snT%1YZCE delta 28 gcmZ3$xR!B(G^6K485>?DZYfSq1~A}om>A&!093>U4FCWD diff --git a/protoFiles/tests/test_scene.pbtxt b/protoFiles/tests/test_scene.pbtxt index 84ab0ed..e2781cf 100644 --- a/protoFiles/tests/test_scene.pbtxt +++ b/protoFiles/tests/test_scene.pbtxt @@ -17,12 +17,6 @@ scene_objects { blink_frequency_hz: 1.5 } } - - components { - blinker { - blink_frequency_hz: 3 - } - } } scene_objects { diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 81c6b44..15c4b54 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,8 +1,10 @@ protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS ${CMAKE_CURRENT_SOURCE_DIR}/../protoFiles/neuronide.proto) -add_library(runtime_core +add_library(runtime_core OBJECT Runtime.cpp - parser/Parser.cpp + parser/Parser.cpp + scene/components/ComponentRegistry.cpp + scene/components/BlinkComponent.cpp ${PROTO_SRCS} ${PROTO_HDRS} ) diff --git a/src/parser/Parser.cpp b/src/parser/Parser.cpp index bd7a77d..a22dea8 100644 --- a/src/parser/Parser.cpp +++ b/src/parser/Parser.cpp @@ -1,14 +1,16 @@ #include "parser/Parser.hpp" -#include // dla .pbtxt jeśli będzie potrzeba - #include #include +#include #include "neuronide.pb.h" -#include "scene/SceneAll.hpp" +#include "scene/Scene.hpp" +#include "scene/SceneObject.hpp" +#include "scene/components/Component.hpp" +#include "scene/components/ComponentRegistry.hpp" -std::shared_ptr<::Scene> Parser::parse(const std::string& filePath) { +std::shared_ptr Parser::parse(const std::string& filePath) { NeuronIDE::Scene protoScene; std::ifstream file(filePath, std::ios::binary); @@ -36,10 +38,19 @@ std::shared_ptr Parser::buildSceneObject(const NeuronIDE::SceneObje if (protoObj.has_transform()) { const auto& tra = protoObj.transform(); - obj->setTransform(tra.x(), tra.y(), tra.width(), tra.height(), tra.rotation()); + obj->setTransform({tra.x(), tra.y(), tra.width(), tra.height(), tra.rotation()}); } + std::unordered_set seenComponentTypes; + for (const auto& protoComp : protoObj.components()) { + int typeId = static_cast(protoComp.component_type_case()); + + if (seenComponentTypes.find(typeId) != seenComponentTypes.end()) { + throw std::runtime_error("Parser: duplicate component type in object '" + protoObj.name() + "'."); + } + seenComponentTypes.insert(typeId); + auto comp = buildComponent(protoComp); if (comp) { obj->addComponent(std::move(comp)); @@ -50,31 +61,5 @@ std::shared_ptr Parser::buildSceneObject(const NeuronIDE::SceneObje } std::unique_ptr Parser::buildComponent(const NeuronIDE::Component& protoComp) { - using CT = NeuronIDE::Component::ComponentTypeCase; - - switch (protoComp.component_type_case()) { - // case CT::kRenderer: { - // const auto& ren = protoComp.renderer(); - // return std::make_unique(ren.texture_path(), ren.img_path()); - // } - - // case CT::kText: { - // const auto& txt = protoComp.text(); - // return std::make_unique(txt.text(), txt.font_path(), - // txt.font_size()); - // } - - case CT::kBlinker: { - const auto& bli = protoComp.blinker(); - return std::make_unique(bli.blink_frequency_hz()); - } - - // case CT::kScript: { - // const auto& scr = protoComp.script(); - // return std::make_unique(scr.script_path()); - // } - - default: - return nullptr; - } + return ComponentRegistry::instance().build(protoComp); } \ No newline at end of file diff --git a/src/scene/components/BlinkComponent.cpp b/src/scene/components/BlinkComponent.cpp new file mode 100644 index 0000000..d2dec5f --- /dev/null +++ b/src/scene/components/BlinkComponent.cpp @@ -0,0 +1,22 @@ +#include "scene/components/BlinkComponent.hpp" + +#include "neuronide.pb.h" +#include "scene/components/ComponentRegistry.hpp" + +void BlinkComponent::setFrequency(double freq) { blinkFrequencyHz = freq; } + +std::unique_ptr BlinkComponent::createBlinker(const NeuronIDE::Component& protoComp) { + return std::make_unique(protoComp.blinker().blink_frequency_hz()); +} + +// Anonymous namespace to register the BlinkComponent creator in the ComponentRegistry at program startup +namespace { +struct BlinkRegistrar { + BlinkRegistrar() { + ComponentRegistry::instance().registerCreator( + static_cast(NeuronIDE::Component::kBlinker), BlinkComponent::createBlinker); + } +}; + +static BlinkRegistrar global_blink_registrar; +} // namespace \ No newline at end of file diff --git a/src/scene/components/ComponentRegistry.cpp b/src/scene/components/ComponentRegistry.cpp new file mode 100644 index 0000000..d89b63a --- /dev/null +++ b/src/scene/components/ComponentRegistry.cpp @@ -0,0 +1,17 @@ +#include "scene/components/ComponentRegistry.hpp" + +#include "neuronide.pb.h" +#include "scene/components/Component.hpp" + +std::unique_ptr ComponentRegistry::build(const NeuronIDE::Component& protoComp) { + auto activeCase = protoComp.component_type_case(); + + int typeId = static_cast(activeCase); + + auto it = creators.find(typeId); + if (it != creators.end()) { + return it->second(protoComp); + } + + return nullptr; +} \ No newline at end of file From 9f94b3c7fd34a11657573d5452e1d1e48e79b32d Mon Sep 17 00:00:00 2001 From: Michal Date: Sun, 17 May 2026 23:29:41 +0200 Subject: [PATCH 2/6] fix: format code --- src/parser/Parser.cpp | 5 +++-- src/scene/components/BlinkComponent.cpp | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/parser/Parser.cpp b/src/parser/Parser.cpp index a22dea8..79de0bc 100644 --- a/src/parser/Parser.cpp +++ b/src/parser/Parser.cpp @@ -45,9 +45,10 @@ std::shared_ptr Parser::buildSceneObject(const NeuronIDE::SceneObje for (const auto& protoComp : protoObj.components()) { int typeId = static_cast(protoComp.component_type_case()); - + if (seenComponentTypes.find(typeId) != seenComponentTypes.end()) { - throw std::runtime_error("Parser: duplicate component type in object '" + protoObj.name() + "'."); + throw std::runtime_error("Parser: duplicate component type in object '" + + protoObj.name() + "'."); } seenComponentTypes.insert(typeId); diff --git a/src/scene/components/BlinkComponent.cpp b/src/scene/components/BlinkComponent.cpp index d2dec5f..93f009b 100644 --- a/src/scene/components/BlinkComponent.cpp +++ b/src/scene/components/BlinkComponent.cpp @@ -9,7 +9,8 @@ std::unique_ptr BlinkComponent::createBlinker(const NeuronIDE::Compon return std::make_unique(protoComp.blinker().blink_frequency_hz()); } -// Anonymous namespace to register the BlinkComponent creator in the ComponentRegistry at program startup +// Anonymous namespace to register the BlinkComponent creator in the ComponentRegistry at program +// startup namespace { struct BlinkRegistrar { BlinkRegistrar() { From 1fb818edf6d3d1391a0a45e74b75bb4de42aad99 Mon Sep 17 00:00:00 2001 From: Michal Date: Sun, 24 May 2026 15:07:00 +0200 Subject: [PATCH 3/6] refactor: move SceneObject functions implementation to seperate .cpp file --- include/scene/SceneObject.hpp | 8 +++----- src/CMakeLists.txt | 1 + src/scene/SceneObject.cpp | 11 +++++++++++ 3 files changed, 15 insertions(+), 5 deletions(-) create mode 100644 src/scene/SceneObject.cpp diff --git a/include/scene/SceneObject.hpp b/include/scene/SceneObject.hpp index 9a14571..bf6ef92 100644 --- a/include/scene/SceneObject.hpp +++ b/include/scene/SceneObject.hpp @@ -19,13 +19,11 @@ class SceneObject { std::vector> components; - SceneObject(std::string n, bool visible = true) : name(std::move(n)), isVisible(visible) { - std::cout << " [SceneObject] Utworzono obiekt: " << name << "\n"; - } + SceneObject(std::string n, bool visible = true); - void setTransform(Transform t) { transform = t; } + void setTransform(Transform t); - void addComponent(std::unique_ptr comp) { components.push_back(std::move(comp)); } + void addComponent(std::unique_ptr comp); }; #endif // SCENEOBJECT_HPP \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 15c4b54..ced725f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -5,6 +5,7 @@ add_library(runtime_core OBJECT parser/Parser.cpp scene/components/ComponentRegistry.cpp scene/components/BlinkComponent.cpp + scene/SceneObject.cpp ${PROTO_SRCS} ${PROTO_HDRS} ) diff --git a/src/scene/SceneObject.cpp b/src/scene/SceneObject.cpp new file mode 100644 index 0000000..2b92865 --- /dev/null +++ b/src/scene/SceneObject.cpp @@ -0,0 +1,11 @@ +#include "scene/SceneObject.hpp" +#include +#include "scene/components/Component.hpp" + +SceneObject::SceneObject(std::string n, bool visible) : name(std::move(n)), isVisible(visible) { + std::cout << " [SceneObject] Utworzono obiekt: " << name << "\n"; +} + +void SceneObject::setTransform(Transform t) { transform = t; } + +void SceneObject::addComponent(std::unique_ptr comp) { components.push_back(std::move(comp)); } \ No newline at end of file From 3e3b3e3c2acdc385a94ef2e763af65d1c4cc0399 Mon Sep 17 00:00:00 2001 From: Michal Date: Sun, 24 May 2026 15:09:32 +0200 Subject: [PATCH 4/6] fix: format code --- src/scene/SceneObject.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/scene/SceneObject.cpp b/src/scene/SceneObject.cpp index 2b92865..06d7dae 100644 --- a/src/scene/SceneObject.cpp +++ b/src/scene/SceneObject.cpp @@ -1,5 +1,7 @@ #include "scene/SceneObject.hpp" + #include + #include "scene/components/Component.hpp" SceneObject::SceneObject(std::string n, bool visible) : name(std::move(n)), isVisible(visible) { @@ -8,4 +10,6 @@ SceneObject::SceneObject(std::string n, bool visible) : name(std::move(n)), isVi void SceneObject::setTransform(Transform t) { transform = t; } -void SceneObject::addComponent(std::unique_ptr comp) { components.push_back(std::move(comp)); } \ No newline at end of file +void SceneObject::addComponent(std::unique_ptr comp) { + components.push_back(std::move(comp)); +} \ No newline at end of file From bb4acfecfe68c9c66636eaf01e27dc12a8573b2c Mon Sep 17 00:00:00 2001 From: Michal Date: Sun, 24 May 2026 15:20:05 +0200 Subject: [PATCH 5/6] refactor: throw error if component creator function has already been registered --- include/scene/components/ComponentRegistry.hpp | 2 +- src/scene/components/ComponentRegistry.cpp | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/include/scene/components/ComponentRegistry.hpp b/include/scene/components/ComponentRegistry.hpp index 0c370f7..9ae1859 100644 --- a/include/scene/components/ComponentRegistry.hpp +++ b/include/scene/components/ComponentRegistry.hpp @@ -25,7 +25,7 @@ class ComponentRegistry { return instance; } - void registerCreator(int typeId, ComponentCreatorFunc creator) { creators[typeId] = creator; } + void registerCreator(int typeId, ComponentCreatorFunc creator); std::unique_ptr build(const NeuronIDE::Component& protoComp); diff --git a/src/scene/components/ComponentRegistry.cpp b/src/scene/components/ComponentRegistry.cpp index d89b63a..52faf24 100644 --- a/src/scene/components/ComponentRegistry.cpp +++ b/src/scene/components/ComponentRegistry.cpp @@ -1,8 +1,18 @@ #include "scene/components/ComponentRegistry.hpp" +#include +#include + #include "neuronide.pb.h" #include "scene/components/Component.hpp" +void ComponentRegistry::registerCreator(int typeId, ComponentCreatorFunc creator) { + if (creators.find(typeId) != creators.end()) { + throw std::runtime_error("Creator for this typeId is already registered."); + } + creators[typeId] = std::move(creator); +} + std::unique_ptr ComponentRegistry::build(const NeuronIDE::Component& protoComp) { auto activeCase = protoComp.component_type_case(); From 22d00dafca0426bb254eac84739f861eb8a4ff8e Mon Sep 17 00:00:00 2001 From: Michal Date: Mon, 25 May 2026 22:34:59 +0200 Subject: [PATCH 6/6] feat: create macro for registering components --- include/scene/components/ComponentRegistry.hpp | 14 ++++++++++++++ src/scene/components/BlinkComponent.cpp | 13 +------------ 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/include/scene/components/ComponentRegistry.hpp b/include/scene/components/ComponentRegistry.hpp index 9ae1859..d6ac0fe 100644 --- a/include/scene/components/ComponentRegistry.hpp +++ b/include/scene/components/ComponentRegistry.hpp @@ -35,4 +35,18 @@ class ComponentRegistry { std::unordered_map creators; }; +#define COMPONENT_REGISTRATION_CONCAT_IMPL(x, y) x##y +#define COMPONENT_REGISTRATION_CONCAT(x, y) COMPONENT_REGISTRATION_CONCAT_IMPL(x, y) + +#define REGISTER_COMPONENT(typeId, creatorFunc) \ + namespace { \ + struct COMPONENT_REGISTRATION_CONCAT(ComponentRegistrar_, __LINE__) { \ + COMPONENT_REGISTRATION_CONCAT(ComponentRegistrar_, __LINE__)() { \ + ComponentRegistry::instance().registerCreator(static_cast(typeId), creatorFunc);\ + } \ + }; \ + static COMPONENT_REGISTRATION_CONCAT(ComponentRegistrar_, __LINE__) \ + COMPONENT_REGISTRATION_CONCAT(global_registrar_, __LINE__); \ + } + #endif // COMPONENTREGISTRY_HPP \ No newline at end of file diff --git a/src/scene/components/BlinkComponent.cpp b/src/scene/components/BlinkComponent.cpp index 93f009b..3830efa 100644 --- a/src/scene/components/BlinkComponent.cpp +++ b/src/scene/components/BlinkComponent.cpp @@ -9,15 +9,4 @@ std::unique_ptr BlinkComponent::createBlinker(const NeuronIDE::Compon return std::make_unique(protoComp.blinker().blink_frequency_hz()); } -// Anonymous namespace to register the BlinkComponent creator in the ComponentRegistry at program -// startup -namespace { -struct BlinkRegistrar { - BlinkRegistrar() { - ComponentRegistry::instance().registerCreator( - static_cast(NeuronIDE::Component::kBlinker), BlinkComponent::createBlinker); - } -}; - -static BlinkRegistrar global_blink_registrar; -} // namespace \ No newline at end of file +REGISTER_COMPONENT(NeuronIDE::Component::kBlinker, BlinkComponent::createBlinker) \ No newline at end of file