-
Notifications
You must be signed in to change notification settings - Fork 0
feat: parser implementation and structure refactor #11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
9f41c06
5bc891f
ee7e952
79660b9
f2623c5
c784dc1
61c713d
352d4ff
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| #ifndef PARSER_HPP | ||
| #define PARSER_HPP | ||
|
|
||
| #include <iostream> | ||
| #include <memory> | ||
| #include <string> | ||
|
|
||
| #include "neuronide.pb.h" | ||
| #include "scene/SceneAll.hpp" | ||
|
|
||
| class Parser { | ||
| public: | ||
| Parser() = default; | ||
|
|
||
| std::shared_ptr<Scene> parse(const std::string& filePath); | ||
|
|
||
| private: | ||
| static std::shared_ptr<SceneObject> buildSceneObject(const NeuronIDE::SceneObject& protoObj); | ||
| static std::unique_ptr<Component> buildComponent(const NeuronIDE::Component& protoComp); | ||
| }; | ||
|
|
||
| #endif // PARSER_HPP |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| #ifndef SCENE_HPP | ||
| #define SCENE_HPP | ||
|
|
||
| #include <memory> | ||
| #include <string> | ||
| #include <vector> | ||
|
|
||
| #include "SceneObject.hpp" | ||
|
|
||
| class Scene { | ||
| private: | ||
| std::string experimentName; | ||
| std::vector<std::shared_ptr<SceneObject>> objects; | ||
|
|
||
| public: | ||
| void setExperimentName(const std::string& name) { experimentName = name; } | ||
|
|
||
| void addObject(std::shared_ptr<SceneObject> obj) { objects.push_back(std::move(obj)); } | ||
|
|
||
| const std::string& getExperimentName() const { return experimentName; } | ||
| const std::vector<std::shared_ptr<SceneObject>>& getObjects() const { return objects; } | ||
| }; | ||
|
|
||
| #endif // SCENE_HPP |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| #ifndef SCENEOBJECT_HPP | ||
| #define SCENEOBJECT_HPP | ||
|
|
||
| #include <iostream> | ||
| #include <memory> | ||
| #include <string> | ||
| #include <vector> | ||
|
|
||
| #include "components/Component.hpp" | ||
|
|
||
| class SceneObject { | ||
| public: | ||
| std::string name; | ||
| bool isVisible = true; | ||
|
|
||
| struct Transform { | ||
| double posX = 0, posY = 0, width = 0, height = 0, rotation = 0; | ||
| } transform; | ||
|
|
||
| std::vector<std::unique_ptr<Component>> 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) { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This seems like it should be abstracted in the future, into either just math vectors or a custom better suited Transform type. I would just make the user pass in the transform struct instead of this in-place construction |
||
| transform = {posX, posY, width, height, rotation}; | ||
| } | ||
|
|
||
| void addComponent(std::unique_ptr<Component> comp) { components.push_back(std::move(comp)); } | ||
| }; | ||
|
|
||
| #endif // SCENEOBJECT_HPP | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| #ifndef BLINKCOMPONENT_HPP | ||
| #define BLINKCOMPONENT_HPP | ||
|
|
||
| #include <iostream> | ||
|
|
||
| #include "Component.hpp" | ||
|
|
||
| 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_HPP |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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; | ||
| Component& operator=(const Component&) = default; | ||
| Component& operator=(Component&&) = default; | ||
| }; | ||
|
|
||
| #endif // COMPONENT_HPP |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. additional dictionary or something for script parameters? Or are we just expecting each Script passed to be void -> void ? |
||
| 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; | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 | ||
| } | ||
| } | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we should also validate the .pb files, because no object should ever have 2 components of the same type, we should throw some error. |
||
| } | ||
|
|
||
| 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 | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,12 +1,24 @@ | ||
| add_library(runtime_core Runtime.cpp) | ||
| target_include_directories(runtime_core PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../include) | ||
| protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS ${CMAKE_CURRENT_SOURCE_DIR}/../protoFiles/neuronide.proto) | ||
|
|
||
| target_link_libraries(runtime_core PUBLIC | ||
| add_library(runtime_core | ||
| Runtime.cpp | ||
| parser/Parser.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) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,4 @@ | ||
| #include <Runtime.hpp> | ||
| #include <iostream> | ||
|
|
||
| int main(int argc, char* argv[]) { | ||
| Runtime::start(); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,80 @@ | ||
| #include "parser/Parser.hpp" | ||
|
|
||
| #include <google/protobuf/text_format.h> // dla .pbtxt jeśli będzie potrzeba | ||
|
|
||
| #include <fstream> | ||
| #include <stdexcept> | ||
|
|
||
| #include "neuronide.pb.h" | ||
| #include "scene/SceneAll.hpp" | ||
|
|
||
| std::shared_ptr<::Scene> Parser::parse(const std::string& filePath) { | ||
| 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); | ||
| } | ||
|
|
||
| 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; | ||
| } | ||
|
|
||
| std::shared_ptr<SceneObject> Parser::buildSceneObject(const NeuronIDE::SceneObject& protoObj) { | ||
| auto obj = std::make_shared<SceneObject>(protoObj.name(), protoObj.is_visible()); | ||
|
|
||
| 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<Component> Parser::buildComponent(const NeuronIDE::Component& protoComp) { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Delegate this to the components themselves?
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure if we can "just do inheritence" here, we could however use map instead of switch case, maybe we could store that map in some seperate ComponentRegistry class. |
||
| using CT = NeuronIDE::Component::ComponentTypeCase; | ||
|
|
||
| switch (protoComp.component_type_case()) { | ||
| // case CT::kRenderer: { | ||
| // const auto& ren = protoComp.renderer(); | ||
| // return std::make_unique<SpriteRenderer>(ren.texture_path(), ren.img_path()); | ||
| // } | ||
|
|
||
| // case CT::kText: { | ||
| // const auto& txt = protoComp.text(); | ||
| // return std::make_unique<TextRenderer>(txt.text(), txt.font_path(), | ||
| // txt.font_size()); | ||
| // } | ||
|
|
||
| case CT::kBlinker: { | ||
| const auto& bli = protoComp.blinker(); | ||
| return std::make_unique<BlinkComponent>(bli.blink_frequency_hz()); | ||
| } | ||
|
|
||
| // case CT::kScript: { | ||
| // const auto& scr = protoComp.script(); | ||
| // return std::make_unique<ScriptComponent>(scr.script_path()); | ||
| // } | ||
|
|
||
| default: | ||
| return nullptr; | ||
| } | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.