From c6f082f51be36e27e224ec3849753b8cef9358d5 Mon Sep 17 00:00:00 2001 From: Wojciech Piwocha Date: Thu, 14 May 2026 13:46:45 +0200 Subject: [PATCH 01/14] feat: parser implementation and scene structure --- include/Parser.hpp | 25 +++++++ include/Scene.hpp | 27 ++++++++ include/SceneObject.hpp | 36 +++++++++++ include/components/BlinkComponent.hpp | 20 ++++++ include/components/Component.hpp | 15 +++++ src/CMakeLists.txt | 24 +++++-- src/Parser.cpp | 90 ++++++++++++++++++++++++++ src/main.cpp | 16 +++++ src/neuronide.proto | 51 +++++++++++++++ tests/test_scene.pb | Bin 0 -> 173 bytes tests/test_scene.pbtxt | 45 +++++++++++++ 11 files changed, 345 insertions(+), 4 deletions(-) create mode 100644 include/Parser.hpp create mode 100644 include/Scene.hpp create mode 100644 include/SceneObject.hpp create mode 100644 include/components/BlinkComponent.hpp create mode 100644 include/components/Component.hpp create mode 100644 src/Parser.cpp create mode 100644 src/neuronide.proto create mode 100644 tests/test_scene.pb create mode 100644 tests/test_scene.pbtxt diff --git a/include/Parser.hpp b/include/Parser.hpp new file mode 100644 index 0000000..44ef580 --- /dev/null +++ b/include/Parser.hpp @@ -0,0 +1,25 @@ +#ifndef PARSER_HPP +#define PARSER_HPP + +#include +#include +#include + +#include "Scene.hpp" +#include "SceneObject.hpp" +#include "components/Component.hpp" +#include "neuronide.pb.h" + +class Parser { + public: + Parser() = default; + + // Parsuje plik protobuff .proto -> natywna Scene + auto parse(const std::string& filePath) -> std::shared_ptr<::Scene>; + private: + // Konwertery proto -> typy sceny + static auto buildSceneObject(const NeuronIDE::SceneObject& protoObj) -> std::shared_ptr; + static auto buildComponent(const NeuronIDE::Component& protoComp) -> std::unique_ptr; +}; + +#endif // PARSER_HPP \ No newline at end of file diff --git a/include/Scene.hpp b/include/Scene.hpp new file mode 100644 index 0000000..5338b5e --- /dev/null +++ b/include/Scene.hpp @@ -0,0 +1,27 @@ +#ifndef SCENE_H +#define SCENE_H + +#include +#include +#include +#include "SceneObject.hpp" + +class Scene { +private: + std::string experimentName; + std::vector> objects; + +public: + void setExperimentName(const std::string& name) { + experimentName = name; + } + + void addObject(std::shared_ptr obj) { + objects.push_back(std::move(obj)); + } + + const std::string& getExperimentName() const { return experimentName; } + const std::vector>& getObjects() const { return objects; } +}; + +#endif // SCENE_H \ No newline at end of file diff --git a/include/SceneObject.hpp b/include/SceneObject.hpp new file mode 100644 index 0000000..5b71643 --- /dev/null +++ b/include/SceneObject.hpp @@ -0,0 +1,36 @@ +#ifndef SCENEOBJECT_HPP +#define SCENEOBJECT_HPP + +#include +#include +#include +#include +#include "components/Component.hpp" + +class SceneObject { +public: + std::string name; + bool isVisible = true; + + // Struktura trzymająca pozycję + struct Transform { + double posX = 0, posY = 0, width = 0, height = 0, rotation = 0; + } transform; + + std::vector> components; + + SceneObject(std::string n, bool visible = true) + : name(std::move(n)), isVisible(visible) { + 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 addComponent(std::unique_ptr comp) { + components.push_back(std::move(comp)); + } +}; + +#endif // SCENEOBJECT_HPP \ No newline at end of file diff --git a/include/components/BlinkComponent.hpp b/include/components/BlinkComponent.hpp new file mode 100644 index 0000000..6f02eb9 --- /dev/null +++ b/include/components/BlinkComponent.hpp @@ -0,0 +1,20 @@ +#ifndef BLINKCOMPONENT_HPP +#define BLINKCOMPONENT_HPP + +#include "Component.hpp" +#include + +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; + } + +private: + double blinkFrequencyHz = 0.0; +}; + +#endif // BLINKCOMPONENT_H \ No newline at end of file diff --git a/include/components/Component.hpp b/include/components/Component.hpp new file mode 100644 index 0000000..3e344de --- /dev/null +++ b/include/components/Component.hpp @@ -0,0 +1,15 @@ +#ifndef COMPONENT_HPP +#define COMPONENT_HPP + +class Component { +public: + Component() = default; + virtual ~Component() = default; + + Component(const Component&) = default; + Component(Component&&) = default; + auto operator=(const Component&) -> Component& = default; + auto operator=(Component&&) -> Component& = default; +}; + +#endif // COMPONENT_H \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 854e2c8..0e57a49 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,12 +1,28 @@ -add_library(runtime_core Runtime.cpp) -target_include_directories(runtime_core PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../include) +protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS neuronide.proto) -target_link_libraries(runtime_core PUBLIC +add_library(runtime_core OBJECT + Runtime.cpp + parser/Parser.cpp + scene/components/ComponentRegistry.cpp + scene/components/BlinkComponent.cpp + scene/SceneObject.cpp + ${PROTO_SRCS} + ${PROTO_HDRS} +) + +target_include_directories(runtime_core SYSTEM PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/../include + ${CMAKE_CURRENT_BINARY_DIR} + ${SDL2_INCLUDE_DIRS} +) + +target_link_libraries(runtime_core PUBLIC lsl concurrentqueue + protobuf::libprotobuf ${SDL2_LIBRARIES} ) -target_include_directories(runtime_core PUBLIC ${SDL2_INCLUDE_DIRS}) + add_executable(NeuronIDE main.cpp) target_link_libraries(NeuronIDE PRIVATE runtime_core) \ No newline at end of file diff --git a/src/Parser.cpp b/src/Parser.cpp new file mode 100644 index 0000000..e29cad1 --- /dev/null +++ b/src/Parser.cpp @@ -0,0 +1,90 @@ +#include "Parser.hpp" + +#include "components/BlinkComponent.hpp" +#include "Scene.hpp" +#include "SceneObject.hpp" +#include "components/Component.hpp" +// TO DO TE PLIKI +// #include "components/ScriptComponent.hpp" +// #include "components/SpriteRenderer.hpp" +// #include "components/TextRenderer.hpp" + +#include // dla .pbtxt jeśli będzie potrzeba + +#include +#include + + +#include "neuronide.pb.h" // wygenerowany przez protoc + +auto Parser::parse(const std::string& filePath) -> std::shared_ptr { + NeuronIDE::Scene protoScene; + + std::ifstream file(filePath, std::ios::binary); + if (!file.is_open()) { + throw std::runtime_error("Parser: cannot open file: " + filePath); + } + + if (!protoScene.ParseFromIstream(&file)) { + throw std::runtime_error("Parser: failed to parse protobuf from: " + filePath); + } + + // Budowanie natywnej sceny silnika + auto scene = std::make_shared<::Scene>(); + scene->setExperimentName(protoScene.project_name()); + + for (const auto& protoObj : protoScene.scene_objects()) { + auto obj = buildSceneObject(protoObj); + scene->addObject(std::move(obj)); + } + + return scene; +} + +auto Parser::buildSceneObject(const NeuronIDE::SceneObject& protoObj) -> std::shared_ptr{ + auto obj = std::make_shared(protoObj.name(), protoObj.is_visible()); + + // Transform (jeśli wyciągnięty poza oneof) + if (protoObj.has_transform()) { + const auto& tra = protoObj.transform(); + obj->setTransform(tra.x(), tra.y(), tra.width(), tra.height(), tra.rotation()); + } + + for (const auto& protoComp : protoObj.components()) { + auto comp = buildComponent(protoComp); + if (comp) { + obj->addComponent(std::move(comp)); + } + } + + return obj; +} + +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; +} +} \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 1ddb7e1..bcb0f5d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,7 +1,23 @@ #include +#include #include int main(int argc, char* argv[]) { Runtime::start(); + try { + Parser parser; + std::cout << "Rozpoczynam parsowanie pliku...\n"; + + + // Podaj ścieżkę do wygenerowanego z .proto pliku binarnego .pb + auto scene = parser.parse("tests/test_scene.pb"); + + std::cout << "\n--- SUKCES ---\n"; + std::cout << "Zaladowano projekt: " << scene->getExperimentName() << "\n"; + std::cout << "Liczba obiektow w scenie: " << scene->getObjects().size() << "\n"; + + } catch (const std::exception& e) { + std::cerr << "Blad parsowania: " << e.what() << '\n'; + } return 0; } \ No newline at end of file diff --git a/src/neuronide.proto b/src/neuronide.proto new file mode 100644 index 0000000..24e15a3 --- /dev/null +++ b/src/neuronide.proto @@ -0,0 +1,51 @@ +syntax = "proto3"; + +package NeuronIDE; + +message SpriteRenderer { + string texture_path = 1; + string img_path = 2; +} + +message TextRenderer { + string text = 1; + string font_path = 2; + uint32 font_size = 3; +} + +message BlinkComponent { + double blink_frequency_hz = 1; +} + +message ScriptComponent { + string script_path = 1; +} + +message Transform { + double x = 1; + double y = 2; + double width = 3; + double height = 4; + double rotation = 5; +} + +message Component { + oneof component_type { + SpriteRenderer renderer = 1; + TextRenderer text = 2; + BlinkComponent blinker = 3; + ScriptComponent script = 4; + } +} + +message SceneObject { + string name = 1; + bool is_visible = 2; + Transform transform = 3; + repeated Component components = 4; +} + +message Scene { + string project_name = 1; + repeated SceneObject scene_objects = 2; +} \ No newline at end of file diff --git a/tests/test_scene.pb b/tests/test_scene.pb new file mode 100644 index 0000000000000000000000000000000000000000..73e8e4ea370bee42c5dcad715f28c3247adff5c2 GIT binary patch literal 173 zcmd;*@XgOs2*^w=Dle|8RB+8ME=Vn^%uUTJ5%T0>buUUxt`cCBQsHC(gGdKK2qV)$ z62b^@P=qm*xTQFu>VDWGaX1`=+_?Dt5(_em6$0|hGfNV4@+y%Gt%Mos2{rUU5zNp? J2PAVu8~|Gj925Wm literal 0 HcmV?d00001 diff --git a/tests/test_scene.pbtxt b/tests/test_scene.pbtxt new file mode 100644 index 0000000..84ab0ed --- /dev/null +++ b/tests/test_scene.pbtxt @@ -0,0 +1,45 @@ +project_name: "Moj Pierwszy Eksperyment" + +scene_objects { + name: "Gracz" + is_visible: true + + transform { + x: 100.0 + y: 200.0 + width: 64.0 + height: 64.0 + rotation: 0.0 + } + + components { + blinker { + blink_frequency_hz: 1.5 + } + } + + components { + blinker { + blink_frequency_hz: 3 + } + } +} + +scene_objects { + name: "Napis Powitalny" + is_visible: true + + transform { + x: 400.0 + y: 50.0 + width: 300.0 + height: 100.0 + rotation: 0.0 + } + + components { + blinker { + blink_frequency_hz: 5 + } + } +} \ No newline at end of file From ce21d4b9ff8a0874be88f0730eca42a5755a7268 Mon Sep 17 00:00:00 2001 From: Michal Date: Tue, 12 May 2026 14:35:56 +0200 Subject: [PATCH 02/14] feat: add lsl and sdl dependencies --- cmake/Dependencies.cmake | 5 ++++- src/CMakeLists.txt | 1 - 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/cmake/Dependencies.cmake b/cmake/Dependencies.cmake index 0c2b475..bce5c33 100644 --- a/cmake/Dependencies.cmake +++ b/cmake/Dependencies.cmake @@ -28,4 +28,7 @@ FetchContent_Declare( FetchContent_MakeAvailable(concurrentqueue) # 4. SDL2 (System installed) -find_package(SDL2 REQUIRED) \ No newline at end of file +find_package(SDL2 REQUIRED) + +# 5. Protobuf (System installed) +find_package(Protobuf REQUIRED) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0e57a49..03873de 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -23,6 +23,5 @@ target_link_libraries(runtime_core PUBLIC ${SDL2_LIBRARIES} ) - add_executable(NeuronIDE main.cpp) target_link_libraries(NeuronIDE PRIVATE runtime_core) \ No newline at end of file From 4041748465d96bcab05a903b1bd67eb89b989b58 Mon Sep 17 00:00:00 2001 From: Wojciech Piwocha Date: Thu, 14 May 2026 13:46:45 +0200 Subject: [PATCH 03/14] feat: parser implementation and scene structure --- CMakeLists.txt | 2 +- proto/neuronide.proto | 51 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 proto/neuronide.proto diff --git a/CMakeLists.txt b/CMakeLists.txt index 2f28891..326ad2e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,7 +5,7 @@ set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) enable_testing() - + list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") include(Dependencies) diff --git a/proto/neuronide.proto b/proto/neuronide.proto new file mode 100644 index 0000000..24e15a3 --- /dev/null +++ b/proto/neuronide.proto @@ -0,0 +1,51 @@ +syntax = "proto3"; + +package NeuronIDE; + +message SpriteRenderer { + string texture_path = 1; + string img_path = 2; +} + +message TextRenderer { + string text = 1; + string font_path = 2; + uint32 font_size = 3; +} + +message BlinkComponent { + double blink_frequency_hz = 1; +} + +message ScriptComponent { + string script_path = 1; +} + +message Transform { + double x = 1; + double y = 2; + double width = 3; + double height = 4; + double rotation = 5; +} + +message Component { + oneof component_type { + SpriteRenderer renderer = 1; + TextRenderer text = 2; + BlinkComponent blinker = 3; + ScriptComponent script = 4; + } +} + +message SceneObject { + string name = 1; + bool is_visible = 2; + Transform transform = 3; + repeated Component components = 4; +} + +message Scene { + string project_name = 1; + repeated SceneObject scene_objects = 2; +} \ No newline at end of file From 27ffe0a9428ab418f448e810abb10abb06e96c96 Mon Sep 17 00:00:00 2001 From: Michal Date: Fri, 15 May 2026 13:30:14 +0200 Subject: [PATCH 04/14] fix: comment code that uses classes that do not exist yet --- src/CMakeLists.txt | 2 +- src/Parser.cpp | 14 ++++++------- src/main.cpp | 17 --------------- src/neuronide.proto | 51 --------------------------------------------- 4 files changed, 8 insertions(+), 76 deletions(-) delete mode 100644 src/neuronide.proto diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 03873de..5b5d900 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,4 +1,4 @@ -protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS neuronide.proto) +protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS ${CMAKE_CURRENT_SOURCE_DIR}/../proto/neuronide.proto) add_library(runtime_core OBJECT Runtime.cpp diff --git a/src/Parser.cpp b/src/Parser.cpp index e29cad1..88649ba 100644 --- a/src/Parser.cpp +++ b/src/Parser.cpp @@ -64,25 +64,25 @@ std::unique_ptr Parser::buildComponent(const NeuronIDE::Component& pr using CT = NeuronIDE::Component::ComponentTypeCase; switch (protoComp.component_type_case()) { - case CT::kRenderer: { + /*case CT::kRenderer: { const auto& ren = protoComp.renderer(); - return std::make_unique(ren.texture_path(), ren.img_path()); + return std::make_unique(); } case CT::kText: { const auto& txt = protoComp.text(); - return std::make_unique(txt.text(), txt.font_path(), txt.font_size()); - } + return std::make_unique(); + }*/ case CT::kBlinker: { const auto& bli = protoComp.blinker(); return std::make_unique(bli.blink_frequency_hz()); } - case CT::kScript: { + /*case CT::kScript: { const auto& scr = protoComp.script(); - return std::make_unique(scr.script_path()); - } + return std::make_unique(); + }*/ default: return nullptr; diff --git a/src/main.cpp b/src/main.cpp index bcb0f5d..1b85885 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,23 +1,6 @@ #include -#include -#include int main(int argc, char* argv[]) { Runtime::start(); - try { - Parser parser; - std::cout << "Rozpoczynam parsowanie pliku...\n"; - - - // Podaj ścieżkę do wygenerowanego z .proto pliku binarnego .pb - auto scene = parser.parse("tests/test_scene.pb"); - - std::cout << "\n--- SUKCES ---\n"; - std::cout << "Zaladowano projekt: " << scene->getExperimentName() << "\n"; - std::cout << "Liczba obiektow w scenie: " << scene->getObjects().size() << "\n"; - - } catch (const std::exception& e) { - std::cerr << "Blad parsowania: " << e.what() << '\n'; - } return 0; } \ No newline at end of file diff --git a/src/neuronide.proto b/src/neuronide.proto deleted file mode 100644 index 24e15a3..0000000 --- a/src/neuronide.proto +++ /dev/null @@ -1,51 +0,0 @@ -syntax = "proto3"; - -package NeuronIDE; - -message SpriteRenderer { - string texture_path = 1; - string img_path = 2; -} - -message TextRenderer { - string text = 1; - string font_path = 2; - uint32 font_size = 3; -} - -message BlinkComponent { - double blink_frequency_hz = 1; -} - -message ScriptComponent { - string script_path = 1; -} - -message Transform { - double x = 1; - double y = 2; - double width = 3; - double height = 4; - double rotation = 5; -} - -message Component { - oneof component_type { - SpriteRenderer renderer = 1; - TextRenderer text = 2; - BlinkComponent blinker = 3; - ScriptComponent script = 4; - } -} - -message SceneObject { - string name = 1; - bool is_visible = 2; - Transform transform = 3; - repeated Component components = 4; -} - -message Scene { - string project_name = 1; - repeated SceneObject scene_objects = 2; -} \ No newline at end of file From 99f07daa6e56a764f403a7ab6b88edc0d5fc17fb Mon Sep 17 00:00:00 2001 From: Wojciech Piwocha Date: Fri, 15 May 2026 14:58:56 +0200 Subject: [PATCH 05/14] refactor: reorganize project structure and standarized code --- include/Parser.hpp | 25 ----------- include/parser/Parser.hpp | 24 ++++++++++ include/{ => scene}/Scene.hpp | 0 include/scene/SceneAll.hpp | 14 ++++++ include/{ => scene}/SceneObject.hpp | 0 .../{ => scene}/components/BlinkComponent.hpp | 0 include/{ => scene}/components/Component.hpp | 4 +- {proto => protoFiles}/neuronide.proto | 0 {tests => protoFiles/tests}/test_scene.pb | Bin {tests => protoFiles/tests}/test_scene.pbtxt | 0 src/CMakeLists.txt | 4 +- src/{ => parser}/Parser.cpp | 41 ++++++++---------- 12 files changed, 59 insertions(+), 53 deletions(-) delete mode 100644 include/Parser.hpp create mode 100644 include/parser/Parser.hpp rename include/{ => scene}/Scene.hpp (100%) create mode 100644 include/scene/SceneAll.hpp rename include/{ => scene}/SceneObject.hpp (100%) rename include/{ => scene}/components/BlinkComponent.hpp (100%) rename include/{ => scene}/components/Component.hpp (66%) rename {proto => protoFiles}/neuronide.proto (100%) rename {tests => protoFiles/tests}/test_scene.pb (100%) rename {tests => protoFiles/tests}/test_scene.pbtxt (100%) rename src/{ => parser}/Parser.cpp (66%) diff --git a/include/Parser.hpp b/include/Parser.hpp deleted file mode 100644 index 44ef580..0000000 --- a/include/Parser.hpp +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef PARSER_HPP -#define PARSER_HPP - -#include -#include -#include - -#include "Scene.hpp" -#include "SceneObject.hpp" -#include "components/Component.hpp" -#include "neuronide.pb.h" - -class Parser { - public: - Parser() = default; - - // Parsuje plik protobuff .proto -> natywna Scene - auto parse(const std::string& filePath) -> std::shared_ptr<::Scene>; - private: - // Konwertery proto -> typy sceny - static auto buildSceneObject(const NeuronIDE::SceneObject& protoObj) -> std::shared_ptr; - static auto buildComponent(const NeuronIDE::Component& protoComp) -> std::unique_ptr; -}; - -#endif // PARSER_HPP \ No newline at end of file diff --git a/include/parser/Parser.hpp b/include/parser/Parser.hpp new file mode 100644 index 0000000..41edb7b --- /dev/null +++ b/include/parser/Parser.hpp @@ -0,0 +1,24 @@ +#ifndef PARSER_HPP +#define PARSER_HPP + +#include +#include +#include + +#include "scene/SceneAll.hpp" +#include "neuronide.pb.h" + +class Parser { +public: + Parser() = default; + + // Parsuje plik protobuff .proto -> natywna Scene + std::shared_ptr<::Scene> parse(const std::string& filePath); + +private: + // Konwertery proto -> typy sceny + static std::shared_ptr buildSceneObject(const NeuronIDE::SceneObject& protoObj); + static std::unique_ptr buildComponent(const NeuronIDE::Component& protoComp); +}; + +#endif // PARSER_HPP \ No newline at end of file diff --git a/include/Scene.hpp b/include/scene/Scene.hpp similarity index 100% rename from include/Scene.hpp rename to include/scene/Scene.hpp diff --git a/include/scene/SceneAll.hpp b/include/scene/SceneAll.hpp new file mode 100644 index 0000000..203a771 --- /dev/null +++ b/include/scene/SceneAll.hpp @@ -0,0 +1,14 @@ +#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/SceneObject.hpp b/include/scene/SceneObject.hpp similarity index 100% rename from include/SceneObject.hpp rename to include/scene/SceneObject.hpp diff --git a/include/components/BlinkComponent.hpp b/include/scene/components/BlinkComponent.hpp similarity index 100% rename from include/components/BlinkComponent.hpp rename to include/scene/components/BlinkComponent.hpp diff --git a/include/components/Component.hpp b/include/scene/components/Component.hpp similarity index 66% rename from include/components/Component.hpp rename to include/scene/components/Component.hpp index 3e344de..45310b5 100644 --- a/include/components/Component.hpp +++ b/include/scene/components/Component.hpp @@ -8,8 +8,8 @@ class Component { Component(const Component&) = default; Component(Component&&) = default; - auto operator=(const Component&) -> Component& = default; - auto operator=(Component&&) -> Component& = default; + Component& operator=(const Component&) = default; + Component& operator=(Component&&) = default; }; #endif // COMPONENT_H \ No newline at end of file diff --git a/proto/neuronide.proto b/protoFiles/neuronide.proto similarity index 100% rename from proto/neuronide.proto rename to protoFiles/neuronide.proto diff --git a/tests/test_scene.pb b/protoFiles/tests/test_scene.pb similarity index 100% rename from tests/test_scene.pb rename to protoFiles/tests/test_scene.pb diff --git a/tests/test_scene.pbtxt b/protoFiles/tests/test_scene.pbtxt similarity index 100% rename from tests/test_scene.pbtxt rename to protoFiles/tests/test_scene.pbtxt diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 5b5d900..c47317e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,4 +1,4 @@ -protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS ${CMAKE_CURRENT_SOURCE_DIR}/../proto/neuronide.proto) +protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS ${CMAKE_CURRENT_SOURCE_DIR}/../protoFiles/neuronide.proto) add_library(runtime_core OBJECT Runtime.cpp @@ -6,7 +6,7 @@ add_library(runtime_core OBJECT scene/components/ComponentRegistry.cpp scene/components/BlinkComponent.cpp scene/SceneObject.cpp - ${PROTO_SRCS} + ${PROTO_SRCS} ${PROTO_HDRS} ) diff --git a/src/Parser.cpp b/src/parser/Parser.cpp similarity index 66% rename from src/Parser.cpp rename to src/parser/Parser.cpp index 88649ba..ec7dc7c 100644 --- a/src/Parser.cpp +++ b/src/parser/Parser.cpp @@ -1,13 +1,6 @@ -#include "Parser.hpp" +#include "parser/Parser.hpp" -#include "components/BlinkComponent.hpp" -#include "Scene.hpp" -#include "SceneObject.hpp" -#include "components/Component.hpp" -// TO DO TE PLIKI -// #include "components/ScriptComponent.hpp" -// #include "components/SpriteRenderer.hpp" -// #include "components/TextRenderer.hpp" +#include "scene/SceneAll.hpp" #include // dla .pbtxt jeśli będzie potrzeba @@ -17,7 +10,7 @@ #include "neuronide.pb.h" // wygenerowany przez protoc -auto Parser::parse(const std::string& filePath) -> std::shared_ptr { +std::shared_ptr<::Scene> Parser::parse(const std::string& filePath) { NeuronIDE::Scene protoScene; std::ifstream file(filePath, std::ios::binary); @@ -41,7 +34,7 @@ auto Parser::parse(const std::string& filePath) -> std::shared_ptr { return scene; } -auto Parser::buildSceneObject(const NeuronIDE::SceneObject& protoObj) -> std::shared_ptr{ +std::shared_ptr Parser::buildSceneObject(const NeuronIDE::SceneObject& protoObj) { auto obj = std::make_shared(protoObj.name(), protoObj.is_visible()); // Transform (jeśli wyciągnięty poza oneof) @@ -64,27 +57,27 @@ std::unique_ptr Parser::buildComponent(const NeuronIDE::Component& pr using CT = NeuronIDE::Component::ComponentTypeCase; switch (protoComp.component_type_case()) { - /*case CT::kRenderer: { - const auto& ren = protoComp.renderer(); - return std::make_unique(); - } + // 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(); - }*/ + // 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(); - }*/ + // case CT::kScript: { + // const auto& scr = protoComp.script(); + // return std::make_unique(scr.script_path()); + // } default: return nullptr; -} + } } \ No newline at end of file From 666fc82f8ab6ae2ca411c26b45d862874c07c805 Mon Sep 17 00:00:00 2001 From: Michal Date: Sun, 17 May 2026 05:29:50 +0200 Subject: [PATCH 06/14] fix: format code --- include/parser/Parser.hpp | 14 ++++----- include/scene/Scene.hpp | 23 +++++++------- include/scene/SceneAll.hpp | 2 +- include/scene/SceneObject.hpp | 21 ++++++------- include/scene/components/BlinkComponent.hpp | 16 +++++----- include/scene/components/Component.hpp | 12 ++++---- src/parser/Parser.cpp | 33 ++++++++++----------- 7 files changed, 55 insertions(+), 66 deletions(-) diff --git a/include/parser/Parser.hpp b/include/parser/Parser.hpp index 41edb7b..a6f509e 100644 --- a/include/parser/Parser.hpp +++ b/include/parser/Parser.hpp @@ -2,23 +2,21 @@ #define PARSER_HPP #include -#include #include +#include -#include "scene/SceneAll.hpp" #include "neuronide.pb.h" +#include "scene/SceneAll.hpp" class Parser { -public: + public: Parser() = default; - // Parsuje plik protobuff .proto -> natywna Scene - std::shared_ptr<::Scene> parse(const std::string& filePath); + std::shared_ptr parse(const std::string& filePath); -private: - // Konwertery proto -> typy sceny + private: static std::shared_ptr buildSceneObject(const NeuronIDE::SceneObject& protoObj); - static std::unique_ptr buildComponent(const NeuronIDE::Component& protoComp); + static std::unique_ptr buildComponent(const NeuronIDE::Component& protoComp); }; #endif // PARSER_HPP \ No newline at end of file diff --git a/include/scene/Scene.hpp b/include/scene/Scene.hpp index 5338b5e..8aeee55 100644 --- a/include/scene/Scene.hpp +++ b/include/scene/Scene.hpp @@ -1,27 +1,24 @@ -#ifndef SCENE_H -#define SCENE_H +#ifndef SCENE_HPP +#define SCENE_HPP +#include #include #include -#include + #include "SceneObject.hpp" class Scene { -private: - std::string experimentName; + private: + std::string experimentName; std::vector> objects; -public: - void setExperimentName(const std::string& name) { - experimentName = name; - } + public: + void setExperimentName(const std::string& name) { experimentName = name; } - void addObject(std::shared_ptr obj) { - objects.push_back(std::move(obj)); - } + void addObject(std::shared_ptr obj) { objects.push_back(std::move(obj)); } const std::string& getExperimentName() const { return experimentName; } const std::vector>& getObjects() const { return objects; } }; -#endif // SCENE_H \ No newline at end of file +#endif // SCENE_HPP \ No newline at end of file diff --git a/include/scene/SceneAll.hpp b/include/scene/SceneAll.hpp index 203a771..058318b 100644 --- a/include/scene/SceneAll.hpp +++ b/include/scene/SceneAll.hpp @@ -11,4 +11,4 @@ // 3. Wszystkie konkretne komponenty #include "components/BlinkComponent.hpp" -#endif // SCENE_ALL_HPP \ No newline at end of file +#endif // SCENE_ALL_HPP \ No newline at end of file diff --git a/include/scene/SceneObject.hpp b/include/scene/SceneObject.hpp index 5b71643..20c5424 100644 --- a/include/scene/SceneObject.hpp +++ b/include/scene/SceneObject.hpp @@ -1,26 +1,25 @@ #ifndef SCENEOBJECT_HPP #define SCENEOBJECT_HPP +#include +#include #include #include -#include -#include + #include "components/Component.hpp" class SceneObject { -public: + public: std::string name; - bool isVisible = true; - - // Struktura trzymająca pozycję + bool isVisible = true; + struct Transform { double posX = 0, posY = 0, width = 0, height = 0, rotation = 0; } transform; std::vector> components; - SceneObject(std::string n, bool visible = true) - : name(std::move(n)), isVisible(visible) { + SceneObject(std::string n, bool visible = true) : name(std::move(n)), isVisible(visible) { std::cout << " [SceneObject] Utworzono obiekt: " << name << "\n"; } @@ -28,9 +27,7 @@ class SceneObject { transform = {posX, posY, width, height, rotation}; } - void addComponent(std::unique_ptr comp) { - components.push_back(std::move(comp)); - } + void addComponent(std::unique_ptr comp) { components.push_back(std::move(comp)); } }; -#endif // SCENEOBJECT_HPP \ No newline at end of file +#endif // SCENEOBJECT_HPP \ No newline at end of file diff --git a/include/scene/components/BlinkComponent.hpp b/include/scene/components/BlinkComponent.hpp index 6f02eb9..0964343 100644 --- a/include/scene/components/BlinkComponent.hpp +++ b/include/scene/components/BlinkComponent.hpp @@ -1,20 +1,20 @@ #ifndef BLINKCOMPONENT_HPP #define BLINKCOMPONENT_HPP -#include "Component.hpp" #include +#include "Component.hpp" + class BlinkComponent : public Component { -public: + public: BlinkComponent(double freq) : blinkFrequencyHz(freq) { - std::cout << " + [BlinkComponent] Utworzono z czestotliwoscia: " << blinkFrequencyHz << "Hz\n"; - } - void setFrequency(double freq) { - blinkFrequencyHz = freq; + std::cout << " + [BlinkComponent] Utworzono z czestotliwoscia: " << blinkFrequencyHz + << "Hz\n"; } + void setFrequency(double freq) { blinkFrequencyHz = freq; } -private: + private: double blinkFrequencyHz = 0.0; }; -#endif // BLINKCOMPONENT_H \ No newline at end of file +#endif // BLINKCOMPONENT_HPP \ No newline at end of file diff --git a/include/scene/components/Component.hpp b/include/scene/components/Component.hpp index 45310b5..1b15b63 100644 --- a/include/scene/components/Component.hpp +++ b/include/scene/components/Component.hpp @@ -2,14 +2,14 @@ #define COMPONENT_HPP class Component { -public: - Component() = default; + public: + Component() = default; virtual ~Component() = default; - Component(const Component&) = default; - Component(Component&&) = default; + Component(const Component&) = default; + Component(Component&&) = default; Component& operator=(const Component&) = default; - Component& operator=(Component&&) = default; + Component& operator=(Component&&) = default; }; -#endif // COMPONENT_H \ No newline at end of file +#endif // COMPONENT_HPP \ No newline at end of file diff --git a/src/parser/Parser.cpp b/src/parser/Parser.cpp index ec7dc7c..bd7a77d 100644 --- a/src/parser/Parser.cpp +++ b/src/parser/Parser.cpp @@ -1,14 +1,12 @@ #include "parser/Parser.hpp" -#include "scene/SceneAll.hpp" - #include // dla .pbtxt jeśli będzie potrzeba #include #include - -#include "neuronide.pb.h" // wygenerowany przez protoc +#include "neuronide.pb.h" +#include "scene/SceneAll.hpp" std::shared_ptr<::Scene> Parser::parse(const std::string& filePath) { NeuronIDE::Scene protoScene; @@ -22,7 +20,6 @@ std::shared_ptr<::Scene> Parser::parse(const std::string& filePath) { throw std::runtime_error("Parser: failed to parse protobuf from: " + filePath); } - // Budowanie natywnej sceny silnika auto scene = std::make_shared<::Scene>(); scene->setExperimentName(protoScene.project_name()); @@ -37,7 +34,6 @@ std::shared_ptr<::Scene> Parser::parse(const std::string& filePath) { std::shared_ptr Parser::buildSceneObject(const NeuronIDE::SceneObject& protoObj) { auto obj = std::make_shared(protoObj.name(), protoObj.is_visible()); - // Transform (jeśli wyciągnięty poza oneof) if (protoObj.has_transform()) { const auto& tra = protoObj.transform(); obj->setTransform(tra.x(), tra.y(), tra.width(), tra.height(), tra.rotation()); @@ -57,25 +53,26 @@ std::unique_ptr Parser::buildComponent(const NeuronIDE::Component& pr 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::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::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()); - // } + // case CT::kScript: { + // const auto& scr = protoComp.script(); + // return std::make_unique(scr.script_path()); + // } default: return nullptr; From 3040e93cb620ced893c0a44e1e27681e69935774 Mon Sep 17 00:00:00 2001 From: Michal Date: Sun, 17 May 2026 10:25:30 +0200 Subject: [PATCH 07/14] fix: install protobuf on CI --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9d1028c..6806370 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,7 +17,7 @@ jobs: - name: Install dependencies run: | sudo apt-get update - sudo apt-get install -y cmake clang-format clang-tidy libsdl2-dev + sudo apt-get install -y cmake clang-format clang-tidy libsdl2-dev protobuf-compiler - name: Check Code Formatting run: | From e99be070681e0beb7324fa3829e0e3ace1fbc9dd Mon Sep 17 00:00:00 2001 From: Michal Date: Sun, 17 May 2026 22:55:59 +0200 Subject: [PATCH 08/14] 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/parser/Parser.cpp | 49 ++++++------------ src/scene/components/BlinkComponent.cpp | 22 ++++++++ src/scene/components/ComponentRegistry.cpp | 17 ++++++ 11 files changed, 113 insertions(+), 60 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/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 3602b3c2bd820cff28eec45f9f3417d7d180dbd8 Mon Sep 17 00:00:00 2001 From: Michal Date: Sun, 17 May 2026 23:29:41 +0200 Subject: [PATCH 09/14] 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 7efae6beab7b2d1f89aee7b6bdd9be5d90746190 Mon Sep 17 00:00:00 2001 From: Michal Date: Sun, 24 May 2026 15:07:00 +0200 Subject: [PATCH 10/14] refactor: move SceneObject functions implementation to seperate .cpp file --- include/scene/SceneObject.hpp | 8 +++----- src/CMakeLists.txt | 2 +- src/scene/SceneObject.cpp | 11 +++++++++++ 3 files changed, 15 insertions(+), 6 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 c47317e..ced725f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -6,7 +6,7 @@ add_library(runtime_core OBJECT scene/components/ComponentRegistry.cpp scene/components/BlinkComponent.cpp scene/SceneObject.cpp - ${PROTO_SRCS} + ${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 fea613869171c5526ffd9452e9bd9bfd68e00e1e Mon Sep 17 00:00:00 2001 From: Michal Date: Sun, 24 May 2026 15:09:32 +0200 Subject: [PATCH 11/14] 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 706a9f49ab68d2d031e8161c9eee05e99f437d06 Mon Sep 17 00:00:00 2001 From: Michal Date: Sun, 24 May 2026 15:20:05 +0200 Subject: [PATCH 12/14] 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 b14e23b3d30b13f870860f1d966780db46a8caf5 Mon Sep 17 00:00:00 2001 From: Michal Date: Mon, 25 May 2026 22:34:59 +0200 Subject: [PATCH 13/14] 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 From 5254dc2755e700b8065a1152934276d6ff71a86b Mon Sep 17 00:00:00 2001 From: Michal Date: Mon, 25 May 2026 22:39:07 +0200 Subject: [PATCH 14/14] fix: format code --- include/scene/components/ComponentRegistry.hpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/include/scene/components/ComponentRegistry.hpp b/include/scene/components/ComponentRegistry.hpp index d6ac0fe..da89f8a 100644 --- a/include/scene/components/ComponentRegistry.hpp +++ b/include/scene/components/ComponentRegistry.hpp @@ -38,15 +38,15 @@ class ComponentRegistry { #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__); \ +#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