From 79fa829c2cae5928b61c83da041af8c007fe60f1 Mon Sep 17 00:00:00 2001 From: Michal Date: Mon, 1 Jun 2026 17:04:21 +0200 Subject: [PATCH 1/6] refactor: update Component class * add update() function * store weak_ptr to the owner of the object --- include/parser/Parser.hpp | 3 +-- include/scene/components/BlinkComponent.hpp | 7 ++----- include/scene/components/ComponentRegistry.hpp | 6 ++---- src/parser/Parser.cpp | 4 ++++ src/scene/components/ComponentRegistry.cpp | 3 +-- 5 files changed, 10 insertions(+), 13 deletions(-) diff --git a/include/parser/Parser.hpp b/include/parser/Parser.hpp index 26bf0dd..e4d6b93 100644 --- a/include/parser/Parser.hpp +++ b/include/parser/Parser.hpp @@ -22,8 +22,7 @@ class Parser { private: static std::shared_ptr buildSceneObject(const NeuronIDE::SceneObject& protoObj); - static std::unique_ptr buildComponent(const NeuronIDE::Component& protoComp, - const std::shared_ptr& owner); + static std::unique_ptr buildComponent(const NeuronIDE::Component& protoComp, const std::shared_ptr& owner); }; #endif // PARSER_HPP \ No newline at end of file diff --git a/include/scene/components/BlinkComponent.hpp b/include/scene/components/BlinkComponent.hpp index b4814e9..1c941c5 100644 --- a/include/scene/components/BlinkComponent.hpp +++ b/include/scene/components/BlinkComponent.hpp @@ -11,15 +11,12 @@ class Component; class BlinkComponent : public Component { public: - BlinkComponent(std::shared_ptr owner, double freq) - : Component(owner), blinkFrequencyHz(freq) {} + BlinkComponent(std::shared_ptr owner, double freq) : Component(owner), blinkFrequencyHz(freq) {} void setFrequency(double freq); void update(const Context& context) override; - void render(SDL_Renderer* renderer) override; - static std::unique_ptr createBlinker(const NeuronIDE::Component& protoComp, - const std::shared_ptr& owner); + static std::unique_ptr createBlinker(const NeuronIDE::Component& protoComp, const std::shared_ptr& owner); private: double blinkFrequencyHz = 0.0; diff --git a/include/scene/components/ComponentRegistry.hpp b/include/scene/components/ComponentRegistry.hpp index 668dc4a..1b1a4c2 100644 --- a/include/scene/components/ComponentRegistry.hpp +++ b/include/scene/components/ComponentRegistry.hpp @@ -11,8 +11,7 @@ class Component; } class SceneObject; -using ComponentCreatorFunc = std::function( - const NeuronIDE::Component&, const std::shared_ptr&)>; +using ComponentCreatorFunc = std::function(const NeuronIDE::Component&, const std::shared_ptr&)>; class ComponentRegistry { public: @@ -29,8 +28,7 @@ class ComponentRegistry { void registerCreator(int typeId, ComponentCreatorFunc creator); - std::unique_ptr build(const NeuronIDE::Component& protoComp, - const std::shared_ptr& owner); + std::unique_ptr build(const NeuronIDE::Component& protoComp, const std::shared_ptr& owner); private: ComponentRegistry() = default; diff --git a/src/parser/Parser.cpp b/src/parser/Parser.cpp index 235dba1..de05e23 100644 --- a/src/parser/Parser.cpp +++ b/src/parser/Parser.cpp @@ -61,7 +61,11 @@ std::shared_ptr Parser::buildSceneObject(const NeuronIDE::SceneObje return obj; } +<<<<<<< HEAD std::unique_ptr Parser::buildComponent(const NeuronIDE::Component& protoComp, const std::shared_ptr& owner) { +======= +std::unique_ptr Parser::buildComponent(const NeuronIDE::Component& protoComp, const std::shared_ptr& owner) { +>>>>>>> 9d8d705 (refactor: update Component class) return ComponentRegistry::instance().build(protoComp, owner); } \ No newline at end of file diff --git a/src/scene/components/ComponentRegistry.cpp b/src/scene/components/ComponentRegistry.cpp index b3419fc..ff05cd2 100644 --- a/src/scene/components/ComponentRegistry.cpp +++ b/src/scene/components/ComponentRegistry.cpp @@ -13,8 +13,7 @@ void ComponentRegistry::registerCreator(int typeId, ComponentCreatorFunc creator creators[typeId] = std::move(creator); } -std::unique_ptr ComponentRegistry::build(const NeuronIDE::Component& protoComp, - const std::shared_ptr& owner) { +std::unique_ptr ComponentRegistry::build(const NeuronIDE::Component& protoComp, const std::shared_ptr& owner) { auto activeCase = protoComp.component_type_case(); int typeId = static_cast(activeCase); From ae0249efb1d48f3664b52aa99950b9707500aa5a Mon Sep 17 00:00:00 2001 From: Michal Date: Mon, 1 Jun 2026 17:15:36 +0200 Subject: [PATCH 2/6] fix: format code --- include/parser/Parser.hpp | 3 ++- include/scene/components/BlinkComponent.hpp | 6 ++++-- include/scene/components/ComponentRegistry.hpp | 6 ++++-- src/parser/Parser.cpp | 4 ---- src/scene/components/ComponentRegistry.cpp | 3 ++- 5 files changed, 12 insertions(+), 10 deletions(-) diff --git a/include/parser/Parser.hpp b/include/parser/Parser.hpp index e4d6b93..26bf0dd 100644 --- a/include/parser/Parser.hpp +++ b/include/parser/Parser.hpp @@ -22,7 +22,8 @@ class Parser { private: static std::shared_ptr buildSceneObject(const NeuronIDE::SceneObject& protoObj); - static std::unique_ptr buildComponent(const NeuronIDE::Component& protoComp, const std::shared_ptr& owner); + static std::unique_ptr buildComponent(const NeuronIDE::Component& protoComp, + const std::shared_ptr& owner); }; #endif // PARSER_HPP \ No newline at end of file diff --git a/include/scene/components/BlinkComponent.hpp b/include/scene/components/BlinkComponent.hpp index 1c941c5..947bf51 100644 --- a/include/scene/components/BlinkComponent.hpp +++ b/include/scene/components/BlinkComponent.hpp @@ -11,12 +11,14 @@ class Component; class BlinkComponent : public Component { public: - BlinkComponent(std::shared_ptr owner, double freq) : Component(owner), blinkFrequencyHz(freq) {} + BlinkComponent(std::shared_ptr owner, double freq) + : Component(owner), blinkFrequencyHz(freq) {} void setFrequency(double freq); void update(const Context& context) override; - static std::unique_ptr createBlinker(const NeuronIDE::Component& protoComp, const std::shared_ptr& owner); + static std::unique_ptr createBlinker(const NeuronIDE::Component& protoComp, + const std::shared_ptr& owner); private: double blinkFrequencyHz = 0.0; diff --git a/include/scene/components/ComponentRegistry.hpp b/include/scene/components/ComponentRegistry.hpp index 1b1a4c2..668dc4a 100644 --- a/include/scene/components/ComponentRegistry.hpp +++ b/include/scene/components/ComponentRegistry.hpp @@ -11,7 +11,8 @@ class Component; } class SceneObject; -using ComponentCreatorFunc = std::function(const NeuronIDE::Component&, const std::shared_ptr&)>; +using ComponentCreatorFunc = std::function( + const NeuronIDE::Component&, const std::shared_ptr&)>; class ComponentRegistry { public: @@ -28,7 +29,8 @@ class ComponentRegistry { void registerCreator(int typeId, ComponentCreatorFunc creator); - std::unique_ptr build(const NeuronIDE::Component& protoComp, const std::shared_ptr& owner); + std::unique_ptr build(const NeuronIDE::Component& protoComp, + const std::shared_ptr& owner); private: ComponentRegistry() = default; diff --git a/src/parser/Parser.cpp b/src/parser/Parser.cpp index de05e23..235dba1 100644 --- a/src/parser/Parser.cpp +++ b/src/parser/Parser.cpp @@ -61,11 +61,7 @@ std::shared_ptr Parser::buildSceneObject(const NeuronIDE::SceneObje return obj; } -<<<<<<< HEAD std::unique_ptr Parser::buildComponent(const NeuronIDE::Component& protoComp, const std::shared_ptr& owner) { -======= -std::unique_ptr Parser::buildComponent(const NeuronIDE::Component& protoComp, const std::shared_ptr& owner) { ->>>>>>> 9d8d705 (refactor: update Component class) return ComponentRegistry::instance().build(protoComp, owner); } \ No newline at end of file diff --git a/src/scene/components/ComponentRegistry.cpp b/src/scene/components/ComponentRegistry.cpp index ff05cd2..b3419fc 100644 --- a/src/scene/components/ComponentRegistry.cpp +++ b/src/scene/components/ComponentRegistry.cpp @@ -13,7 +13,8 @@ void ComponentRegistry::registerCreator(int typeId, ComponentCreatorFunc creator creators[typeId] = std::move(creator); } -std::unique_ptr ComponentRegistry::build(const NeuronIDE::Component& protoComp, const std::shared_ptr& owner) { +std::unique_ptr ComponentRegistry::build(const NeuronIDE::Component& protoComp, + const std::shared_ptr& owner) { auto activeCase = protoComp.component_type_case(); int typeId = static_cast(activeCase); From e5d33f1f19639e1331d6e9cb2771068367398fd9 Mon Sep 17 00:00:00 2001 From: Michal Date: Tue, 2 Jun 2026 01:33:18 +0200 Subject: [PATCH 3/6] feat: add render and update functions to Scene, SceneObject and Component --- include/scene/components/BlinkComponent.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/include/scene/components/BlinkComponent.hpp b/include/scene/components/BlinkComponent.hpp index 947bf51..b4814e9 100644 --- a/include/scene/components/BlinkComponent.hpp +++ b/include/scene/components/BlinkComponent.hpp @@ -16,6 +16,7 @@ class BlinkComponent : public Component { void setFrequency(double freq); void update(const Context& context) override; + void render(SDL_Renderer* renderer) override; static std::unique_ptr createBlinker(const NeuronIDE::Component& protoComp, const std::shared_ptr& owner); From 40de962fefc52cf41693603d1856f2fc4861ac9a Mon Sep 17 00:00:00 2001 From: Michal Date: Tue, 2 Jun 2026 13:03:56 +0200 Subject: [PATCH 4/6] feat: create renderer class --- include/data_structures/Context.hpp | 12 ++++++++ include/data_structures/EEGData.hpp | 11 +++++++ include/data_structures/Marker.hpp | 11 +++++++ include/renderer/Renderer.hpp | 28 ++++++++++++++++++ src/CMakeLists.txt | 1 + src/renderer/Renderer.cpp | 45 +++++++++++++++++++++++++++++ 6 files changed, 108 insertions(+) create mode 100644 include/data_structures/Context.hpp create mode 100644 include/data_structures/EEGData.hpp create mode 100644 include/data_structures/Marker.hpp create mode 100644 include/renderer/Renderer.hpp create mode 100644 src/renderer/Renderer.cpp diff --git a/include/data_structures/Context.hpp b/include/data_structures/Context.hpp new file mode 100644 index 0000000..1e10942 --- /dev/null +++ b/include/data_structures/Context.hpp @@ -0,0 +1,12 @@ +#ifndef CONTEXT_HPP +#define CONTEXT_HPP + +#include +#include + +struct Context { + double timestamp; + std::vector markers; +}; + +#endif // CONTEXT_HPP \ No newline at end of file diff --git a/include/data_structures/EEGData.hpp b/include/data_structures/EEGData.hpp new file mode 100644 index 0000000..58eb0a6 --- /dev/null +++ b/include/data_structures/EEGData.hpp @@ -0,0 +1,11 @@ +#ifndef EEGDATA_HPP +#define EEGDATA_HPP + +#include + +struct EEGData { + double timestamp; + std::vector channelValues; +}; + +#endif // EEGDATA_HPP \ No newline at end of file diff --git a/include/data_structures/Marker.hpp b/include/data_structures/Marker.hpp new file mode 100644 index 0000000..6933e2f --- /dev/null +++ b/include/data_structures/Marker.hpp @@ -0,0 +1,11 @@ +#ifndef MARKER_HPP +#define MARKER_HPP + +#include + +struct Marker { + std::string name; + double timestamp; +}; + +#endif // MARKER_HPP \ No newline at end of file diff --git a/include/renderer/Renderer.hpp b/include/renderer/Renderer.hpp new file mode 100644 index 0000000..67268c9 --- /dev/null +++ b/include/renderer/Renderer.hpp @@ -0,0 +1,28 @@ +#ifndef RENDERER_HPP +#define RENDERER_HPP + +#include +#include + +#include +#include + +class Scene; +struct Marker; + +class Renderer { + public: + Renderer() = default; + ~Renderer() = default; + + void render(const std::stop_token& stoken); + + private: + std::unique_ptr window; + std::shared_ptr sdlRenderer; + std::weak_ptr currentScene; + std::shared_ptr> markerQueue; + std::jthread renderThread; +}; + +#endif // RENDERER_HPP \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 62cd34d..2d94a45 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -7,6 +7,7 @@ add_library(runtime_core OBJECT scene/components/BlinkComponent.cpp scene/SceneObject.cpp scene/Scene.cpp + renderer/Renderer.cpp ${PROTO_SRCS} ${PROTO_HDRS} ) diff --git a/src/renderer/Renderer.cpp b/src/renderer/Renderer.cpp new file mode 100644 index 0000000..4b43e2e --- /dev/null +++ b/src/renderer/Renderer.cpp @@ -0,0 +1,45 @@ +#include "renderer/Renderer.hpp" + +#include "data_structures/Context.hpp" +#include "data_structures/Marker.hpp" +#include "lsl_cpp.h" +#include "scene/Scene.hpp" + +void Renderer::render(const std::stop_token& stoken) { + std::vector currentFrameMarkers; + auto lastTime = std::chrono::high_resolution_clock::now(); + + while (!stoken.stop_requested()) { + auto currentTime = std::chrono::high_resolution_clock::now(); + double deltaTime = std::chrono::duration(currentTime - lastTime).count(); + lastTime = currentTime; + + currentFrameMarkers.clear(); + Context ctx{deltaTime, currentFrameMarkers}; + + SDL_Event event; + while (SDL_PollEvent(&event) == 1) { + if (event.type == SDL_QUIT) { + return; + } + } + + if (auto scene = currentScene.lock()) { + scene->update(ctx); + } + + SDL_RenderClear(sdlRenderer.get()); + + if (auto scene = currentScene.lock()) { + scene->render(sdlRenderer.get()); + } + + SDL_RenderPresent(sdlRenderer.get()); + + double exactTime = lsl::local_clock(); + + for (const auto& markerName : currentFrameMarkers) { + markerQueue->enqueue(Marker{markerName, exactTime}); + } + } +} From e6d194c9325aab0b69620f627a3a5d135dd62892 Mon Sep 17 00:00:00 2001 From: Michal Date: Tue, 9 Jun 2026 10:37:14 +0200 Subject: [PATCH 5/6] tests: add renderer tests --- include/data_structures/Context.hpp | 2 +- include/renderer/Renderer.hpp | 10 ++- src/renderer/Renderer.cpp | 14 ++++ tests/unit_tests/RendererTest.cpp | 125 ++++++++++++++++++++++++++++ 4 files changed, 148 insertions(+), 3 deletions(-) create mode 100644 tests/unit_tests/RendererTest.cpp diff --git a/include/data_structures/Context.hpp b/include/data_structures/Context.hpp index 1e10942..0efb940 100644 --- a/include/data_structures/Context.hpp +++ b/include/data_structures/Context.hpp @@ -6,7 +6,7 @@ struct Context { double timestamp; - std::vector markers; + std::vector& markers; }; #endif // CONTEXT_HPP \ No newline at end of file diff --git a/include/renderer/Renderer.hpp b/include/renderer/Renderer.hpp index 67268c9..e2282e2 100644 --- a/include/renderer/Renderer.hpp +++ b/include/renderer/Renderer.hpp @@ -12,13 +12,19 @@ struct Marker; class Renderer { public: - Renderer() = default; + Renderer() = delete; + Renderer(std::shared_ptr scene, + std::shared_ptr sdlRenderer, + std::shared_ptr> markerQueue); ~Renderer() = default; void render(const std::stop_token& stoken); private: - std::unique_ptr window; + struct SDLWindowDeleter { + void operator()(SDL_Window* w) const; + }; + std::unique_ptr window; std::shared_ptr sdlRenderer; std::weak_ptr currentScene; std::shared_ptr> markerQueue; diff --git a/src/renderer/Renderer.cpp b/src/renderer/Renderer.cpp index 4b43e2e..1392e34 100644 --- a/src/renderer/Renderer.cpp +++ b/src/renderer/Renderer.cpp @@ -5,6 +5,20 @@ #include "lsl_cpp.h" #include "scene/Scene.hpp" +void Renderer::SDLWindowDeleter::operator()(SDL_Window* w) const { + if (w) { + SDL_DestroyWindow(w); + } +} + +Renderer::Renderer(std::shared_ptr scene, + std::shared_ptr sdlRenderer, + std::shared_ptr> markerQueue) + : window(nullptr, SDLWindowDeleter{}), + sdlRenderer(std::move(sdlRenderer)), + currentScene(std::move(scene)), + markerQueue(std::move(markerQueue)) {} + void Renderer::render(const std::stop_token& stoken) { std::vector currentFrameMarkers; auto lastTime = std::chrono::high_resolution_clock::now(); diff --git a/tests/unit_tests/RendererTest.cpp b/tests/unit_tests/RendererTest.cpp new file mode 100644 index 0000000..dbc39d7 --- /dev/null +++ b/tests/unit_tests/RendererTest.cpp @@ -0,0 +1,125 @@ +#include + +#include + +#include "data_structures/Marker.hpp" +#include "renderer/Renderer.hpp" +#include "scene/Scene.hpp" +#include "scene/SceneObject.hpp" +#include "scene/components/Component.hpp" +#include "data_structures/Context.hpp" + +#include +#include + +namespace { +class CustomComponent : public Component { + public: + CustomComponent(std::shared_ptr owner, + std::shared_ptr> updates, + std::shared_ptr> renders, + std::shared_ptr stopSource) + : Component(std::move(owner)), updates(std::move(updates)), renders(std::move(renders)), stopSource(std::move(stopSource)) {} + + void update(const Context& context) override { + (void)context; + (*updates)++; + + stopSource->request_stop(); + } + + void render(SDL_Renderer* renderer) override { + (void)renderer; + (*renders)++; + } + + private: + std::shared_ptr> updates; + std::shared_ptr> renders; + std::shared_ptr stopSource; +}; + +class MarkerComponent : public Component { + public: + MarkerComponent(std::shared_ptr owner, std::shared_ptr stopSource) + : Component(std::move(owner)), stopSource(std::move(stopSource)) {} + + void update(const Context& context) override { + context.markers.push_back("test_marker"); + stopSource->request_stop(); + } + + void render(SDL_Renderer* renderer) override { + (void)renderer; + } + + private: + std::shared_ptr stopSource; +}; + +} // namespace + +TEST(RendererTest, RenderLoop_WhenComponentAdded_CallsUpdateExactlyOnceBeforeStop) { + ASSERT_EQ(SDL_Init(SDL_INIT_EVENTS), 0); + + auto scene = std::make_shared(); + auto obj = std::make_shared("obj"); + + auto updates = std::make_shared>(0); + auto renders = std::make_shared>(0); + auto stop_source = std::make_shared(); + + obj->addComponent(std::make_unique(obj, updates, renders, stop_source)); + scene->addObject(obj); + + SDL_Surface* surface = SDL_CreateRGBSurfaceWithFormat(0, 10, 10, 32, SDL_PIXELFORMAT_RGBA32); + SDL_Renderer* sdlRenderer = SDL_CreateSoftwareRenderer(surface); + auto sharedRenderer = std::shared_ptr(sdlRenderer, [surface](SDL_Renderer* r) { + if (r) SDL_DestroyRenderer(r); + if (surface) SDL_FreeSurface(surface); + }); + + auto markerQueue = std::make_shared>(); + + Renderer renderer(scene, sharedRenderer, markerQueue); + renderer.render(stop_source->get_token()); + + EXPECT_EQ(*updates, 1); + EXPECT_EQ(*renders, 1); + + SDL_Quit(); +} + +TEST(RendererTest, RenderLoop_QueuesMarkersFromComponents) { + ASSERT_EQ(SDL_Init(SDL_INIT_EVENTS), 0); + + auto scene = std::make_shared(); + auto obj = std::make_shared("obj"); + auto stop_source = std::make_shared(); + + obj->addComponent(std::make_unique(obj, stop_source)); + scene->addObject(obj); + + SDL_Surface* surface = SDL_CreateRGBSurfaceWithFormat(0, 10, 10, 32, SDL_PIXELFORMAT_RGBA32); + SDL_Renderer* sdlRenderer = SDL_CreateSoftwareRenderer(surface); + auto sharedRenderer = std::shared_ptr(sdlRenderer, [surface](SDL_Renderer* r) { + if (r) SDL_DestroyRenderer(r); + if (surface) SDL_FreeSurface(surface); + }); + + auto markerQueue = std::make_shared>(); + + Renderer renderer(scene, sharedRenderer, markerQueue); + renderer.render(stop_source->get_token()); + + Marker m; + bool dequeued = markerQueue->try_dequeue(m); + EXPECT_TRUE(dequeued); + if (dequeued) { + EXPECT_EQ(m.name, "test_marker"); + // Ensure no other markers are left + EXPECT_FALSE(markerQueue->try_dequeue(m)); + } + + SDL_Quit(); +} \ No newline at end of file From 10ef5884caafea8db6dbe21de4c6480cd1c2e599 Mon Sep 17 00:00:00 2001 From: Michal Date: Tue, 9 Jun 2026 10:51:21 +0200 Subject: [PATCH 6/6] fix: format code and make changes suggested by clang-tidy --- include/data_structures/Context.hpp | 2 +- include/renderer/Renderer.hpp | 5 +-- src/renderer/Renderer.cpp | 11 +++-- tests/unit_tests/RendererTest.cpp | 66 ++++++++++++++++++----------- 4 files changed, 49 insertions(+), 35 deletions(-) diff --git a/include/data_structures/Context.hpp b/include/data_structures/Context.hpp index 0efb940..da103ff 100644 --- a/include/data_structures/Context.hpp +++ b/include/data_structures/Context.hpp @@ -5,7 +5,7 @@ #include struct Context { - double timestamp; + double timestamp; std::vector& markers; }; diff --git a/include/renderer/Renderer.hpp b/include/renderer/Renderer.hpp index e2282e2..267c810 100644 --- a/include/renderer/Renderer.hpp +++ b/include/renderer/Renderer.hpp @@ -13,8 +13,7 @@ struct Marker; class Renderer { public: Renderer() = delete; - Renderer(std::shared_ptr scene, - std::shared_ptr sdlRenderer, + Renderer(const std::shared_ptr& scene, std::shared_ptr sdlRenderer, std::shared_ptr> markerQueue); ~Renderer() = default; @@ -22,7 +21,7 @@ class Renderer { private: struct SDLWindowDeleter { - void operator()(SDL_Window* w) const; + void operator()(SDL_Window* window) const; }; std::unique_ptr window; std::shared_ptr sdlRenderer; diff --git a/src/renderer/Renderer.cpp b/src/renderer/Renderer.cpp index 1392e34..f57b239 100644 --- a/src/renderer/Renderer.cpp +++ b/src/renderer/Renderer.cpp @@ -5,18 +5,17 @@ #include "lsl_cpp.h" #include "scene/Scene.hpp" -void Renderer::SDLWindowDeleter::operator()(SDL_Window* w) const { - if (w) { - SDL_DestroyWindow(w); +void Renderer::SDLWindowDeleter::operator()(SDL_Window* window) const { + if (window) { + SDL_DestroyWindow(window); } } -Renderer::Renderer(std::shared_ptr scene, - std::shared_ptr sdlRenderer, +Renderer::Renderer(const std::shared_ptr& scene, std::shared_ptr sdlRenderer, std::shared_ptr> markerQueue) : window(nullptr, SDLWindowDeleter{}), sdlRenderer(std::move(sdlRenderer)), - currentScene(std::move(scene)), + currentScene(scene), markerQueue(std::move(markerQueue)) {} void Renderer::render(const std::stop_token& stoken) { diff --git a/tests/unit_tests/RendererTest.cpp b/tests/unit_tests/RendererTest.cpp index dbc39d7..25b6711 100644 --- a/tests/unit_tests/RendererTest.cpp +++ b/tests/unit_tests/RendererTest.cpp @@ -1,25 +1,31 @@ #include +#include +#include #include +#include "data_structures/Context.hpp" #include "data_structures/Marker.hpp" #include "renderer/Renderer.hpp" #include "scene/Scene.hpp" #include "scene/SceneObject.hpp" #include "scene/components/Component.hpp" -#include "data_structures/Context.hpp" - -#include -#include namespace { +constexpr int kDummySurfaceWidth = 10; +constexpr int kDummySurfaceHeight = 10; +constexpr int kDummySurfaceDepth = 32; +constexpr uint32_t kDummySurfaceFlags = 0; + class CustomComponent : public Component { public: - CustomComponent(std::shared_ptr owner, - std::shared_ptr> updates, + CustomComponent(std::shared_ptr owner, std::shared_ptr> updates, std::shared_ptr> renders, std::shared_ptr stopSource) - : Component(std::move(owner)), updates(std::move(updates)), renders(std::move(renders)), stopSource(std::move(stopSource)) {} + : Component(std::move(owner)), + updates(std::move(updates)), + renders(std::move(renders)), + stopSource(std::move(stopSource)) {} void update(const Context& context) override { (void)context; @@ -41,7 +47,8 @@ class CustomComponent : public Component { class MarkerComponent : public Component { public: - MarkerComponent(std::shared_ptr owner, std::shared_ptr stopSource) + MarkerComponent(std::shared_ptr owner, + std::shared_ptr stopSource) : Component(std::move(owner)), stopSource(std::move(stopSource)) {} void update(const Context& context) override { @@ -49,9 +56,7 @@ class MarkerComponent : public Component { stopSource->request_stop(); } - void render(SDL_Renderer* renderer) override { - (void)renderer; - } + void render(SDL_Renderer* renderer) override { (void)renderer; } private: std::shared_ptr stopSource; @@ -65,18 +70,24 @@ TEST(RendererTest, RenderLoop_WhenComponentAdded_CallsUpdateExactlyOnceBeforeSto auto scene = std::make_shared(); auto obj = std::make_shared("obj"); - auto updates = std::make_shared>(0); - auto renders = std::make_shared>(0); + auto updates = std::make_shared>(0); + auto renders = std::make_shared>(0); auto stop_source = std::make_shared(); - + obj->addComponent(std::make_unique(obj, updates, renders, stop_source)); scene->addObject(obj); - SDL_Surface* surface = SDL_CreateRGBSurfaceWithFormat(0, 10, 10, 32, SDL_PIXELFORMAT_RGBA32); + SDL_Surface* surface = + SDL_CreateRGBSurfaceWithFormat(kDummySurfaceFlags, kDummySurfaceWidth, kDummySurfaceHeight, + kDummySurfaceDepth, SDL_PIXELFORMAT_RGBA32); SDL_Renderer* sdlRenderer = SDL_CreateSoftwareRenderer(surface); auto sharedRenderer = std::shared_ptr(sdlRenderer, [surface](SDL_Renderer* r) { - if (r) SDL_DestroyRenderer(r); - if (surface) SDL_FreeSurface(surface); + if (r) { + SDL_DestroyRenderer(r); + } + if (surface) { + SDL_FreeSurface(surface); + } }); auto markerQueue = std::make_shared>(); @@ -93,18 +104,24 @@ TEST(RendererTest, RenderLoop_WhenComponentAdded_CallsUpdateExactlyOnceBeforeSto TEST(RendererTest, RenderLoop_QueuesMarkersFromComponents) { ASSERT_EQ(SDL_Init(SDL_INIT_EVENTS), 0); - auto scene = std::make_shared(); - auto obj = std::make_shared("obj"); + auto scene = std::make_shared(); + auto obj = std::make_shared("obj"); auto stop_source = std::make_shared(); - + obj->addComponent(std::make_unique(obj, stop_source)); scene->addObject(obj); - SDL_Surface* surface = SDL_CreateRGBSurfaceWithFormat(0, 10, 10, 32, SDL_PIXELFORMAT_RGBA32); + SDL_Surface* surface = + SDL_CreateRGBSurfaceWithFormat(kDummySurfaceFlags, kDummySurfaceWidth, kDummySurfaceHeight, + kDummySurfaceDepth, SDL_PIXELFORMAT_RGBA32); SDL_Renderer* sdlRenderer = SDL_CreateSoftwareRenderer(surface); auto sharedRenderer = std::shared_ptr(sdlRenderer, [surface](SDL_Renderer* r) { - if (r) SDL_DestroyRenderer(r); - if (surface) SDL_FreeSurface(surface); + if (r) { + SDL_DestroyRenderer(r); + } + if (surface) { + SDL_FreeSurface(surface); + } }); auto markerQueue = std::make_shared>(); @@ -113,11 +130,10 @@ TEST(RendererTest, RenderLoop_QueuesMarkersFromComponents) { renderer.render(stop_source->get_token()); Marker m; - bool dequeued = markerQueue->try_dequeue(m); + bool dequeued = markerQueue->try_dequeue(m); EXPECT_TRUE(dequeued); if (dequeued) { EXPECT_EQ(m.name, "test_marker"); - // Ensure no other markers are left EXPECT_FALSE(markerQueue->try_dequeue(m)); }