From ca878336da5cdd120a929e6ce84f565ce5365248 Mon Sep 17 00:00:00 2001 From: heavydemon21 Date: Mon, 11 Nov 2024 19:43:03 +0100 Subject: adjusted render a little and added a error img of the chosen img did not load. this prevents exceptions --- src/crepe/system/RenderSystem.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/crepe/system/RenderSystem.cpp b/src/crepe/system/RenderSystem.cpp index 10211a3..3a1def5 100644 --- a/src/crepe/system/RenderSystem.cpp +++ b/src/crepe/system/RenderSystem.cpp @@ -6,6 +6,7 @@ #include "../api/Transform.h" #include "../facade/SDLContext.h" #include "../util/log.h" +#include "api/ParticleEmitter.h" #include "RenderSystem.h" @@ -42,8 +43,7 @@ void RenderSystem::render_sprites() const { ComponentManager & mgr = ComponentManager::get_instance(); - std::vector> sprites - = mgr.get_components_by_type(); + auto sprites = mgr.get_components_by_type(); SDLContext & render = SDLContext::get_instance(); for (const Sprite & sprite : sprites) { -- cgit v1.2.3 From 3d97f7c60536bf14f314cc703883f74345aacd21 Mon Sep 17 00:00:00 2001 From: heavydemon21 Date: Mon, 11 Nov 2024 20:49:49 +0100 Subject: rendering particle --- src/crepe/api/Texture.cpp | 2 +- src/crepe/facade/SDLContext.cpp | 4 +-- src/crepe/facade/SDLContext.h | 7 +++-- src/crepe/system/RenderSystem.cpp | 28 +++++++++++++---- src/crepe/system/RenderSystem.h | 6 +++- src/example/CMakeLists.txt | 1 + src/example/rendering_particle.cpp | 61 ++++++++++++++++++++++++++++++++++++++ 7 files changed, 98 insertions(+), 11 deletions(-) create mode 100644 src/example/rendering_particle.cpp (limited to 'src') diff --git a/src/crepe/api/Texture.cpp b/src/crepe/api/Texture.cpp index 5ebd23d..8ce65c2 100644 --- a/src/crepe/api/Texture.cpp +++ b/src/crepe/api/Texture.cpp @@ -35,5 +35,5 @@ int Texture::get_width() const { } int Texture::get_height() const { if (this->texture == nullptr) return 0; - return SDLContext::get_instance().get_width(*this); + return SDLContext::get_instance().get_height(*this); } diff --git a/src/crepe/facade/SDLContext.cpp b/src/crepe/facade/SDLContext.cpp index e87a2c5..cc2e2f8 100644 --- a/src/crepe/facade/SDLContext.cpp +++ b/src/crepe/facade/SDLContext.cpp @@ -181,12 +181,12 @@ SDLContext::texture_from_path(const std::string & path) { return img_texture; } -int SDLContext::get_width(const Texture & ctx) const { +int SDLContext::get_width(const Texture & ctx) { int w; SDL_QueryTexture(ctx.texture.get(), NULL, NULL, &w, NULL); return w; } -int SDLContext::get_height(const Texture & ctx) const { +int SDLContext::get_height(const Texture & ctx) { int h; SDL_QueryTexture(ctx.texture.get(), NULL, NULL, NULL, &h); return h; diff --git a/src/crepe/facade/SDLContext.h b/src/crepe/facade/SDLContext.h index e358c21..7329b74 100644 --- a/src/crepe/facade/SDLContext.h +++ b/src/crepe/facade/SDLContext.h @@ -10,6 +10,7 @@ #include "../api/Sprite.h" #include "../api/Transform.h" #include "api/Camera.h" +#include "api/Vector2.h" // FIXME: this needs to be removed const int SCREEN_WIDTH = 640; @@ -97,14 +98,14 @@ private: * \param texture Reference to the Texture object. * \return Width of the texture as an integer. */ - int get_width(const Texture &) const; + int get_width(const Texture &) ; /** * \brief Gets the height of a texture. * \param texture Reference to the Texture object. * \return Height of the texture as an integer. */ - int get_height(const Texture &) const; + int get_height(const Texture &) ; private: //! Will use draw,clear_screen, present_screen, camera. @@ -119,6 +120,8 @@ private: void draw(const Sprite & sprite, const Transform & transform, const Camera & camera); + void draw_particle(const Vector2 & pos, const Camera & camera); + //! Clears the screen, preparing for a new frame. void clear_screen(); diff --git a/src/crepe/system/RenderSystem.cpp b/src/crepe/system/RenderSystem.cpp index 3a1def5..3de8330 100644 --- a/src/crepe/system/RenderSystem.cpp +++ b/src/crepe/system/RenderSystem.cpp @@ -1,3 +1,4 @@ +#include #include #include @@ -6,7 +7,9 @@ #include "../api/Transform.h" #include "../facade/SDLContext.h" #include "../util/log.h" +#include "Particle.h" #include "api/ParticleEmitter.h" +#include "api/Vector2.h" #include "RenderSystem.h" @@ -39,17 +42,32 @@ void RenderSystem::update_camera() { this->curr_cam = &cam; } } -void RenderSystem::render_sprites() const { + + +void RenderSystem::render_particle(const ParticleEmitter& em, Transform & tm){ + if (!em.active) return; + + SDLContext & render = SDLContext::get_instance(); + for (const Particle& p : em.data.particles) { + tm.position = p.position; + render.draw(em.data.sprite, tm , *curr_cam); + } +} +void RenderSystem::render_sprites() { ComponentManager & mgr = ComponentManager::get_instance(); - auto sprites = mgr.get_components_by_type(); + auto emitter = mgr.get_components_by_type(); SDLContext & render = SDLContext::get_instance(); - for (const Sprite & sprite : sprites) { + Transform test(1, Vector2{0,0},0,0); + + for (const ParticleEmitter & em : emitter) { auto transforms - = mgr.get_components_by_id(sprite.game_object_id); - render.draw(sprite, transforms[0], *curr_cam); + = mgr.get_components_by_id(em.game_object_id); + test.scale = transforms[0].get().scale; + test.rotation = transforms[0].get().rotation; + this->render_particle(em, test); } } diff --git a/src/crepe/system/RenderSystem.h b/src/crepe/system/RenderSystem.h index 70db21a..8dd8b7e 100644 --- a/src/crepe/system/RenderSystem.h +++ b/src/crepe/system/RenderSystem.h @@ -3,6 +3,8 @@ #include "api/Camera.h" #include "System.h" +#include "api/ParticleEmitter.h" +#include "api/Transform.h" namespace crepe { @@ -44,7 +46,9 @@ private: void update_camera(); //! Renders all active sprites to the screen. - void render_sprites() const; + void render_sprites() ; + + void render_particle(const ParticleEmitter& em, Transform & tm); /** * \todo Include color handling for sprites. diff --git a/src/example/CMakeLists.txt b/src/example/CMakeLists.txt index 722ffea..72dc172 100644 --- a/src/example/CMakeLists.txt +++ b/src/example/CMakeLists.txt @@ -29,4 +29,5 @@ add_example(db) add_example(ecs) add_example(scene_manager) add_example(particles) +add_example(rendering_particle) diff --git a/src/example/rendering_particle.cpp b/src/example/rendering_particle.cpp new file mode 100644 index 0000000..54a9c23 --- /dev/null +++ b/src/example/rendering_particle.cpp @@ -0,0 +1,61 @@ +#include "api/Camera.h" +#include "system/ParticleSystem.h" +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +using namespace crepe; +using namespace std; + +int main(int argc, char * argv[]) { + GameObject game_object(0, "", "", Vector2{0, 0}, 0, 0.1); + Color color(0, 0, 0, 0); + Sprite test_sprite = game_object.add_component( + make_shared("../asset/texture/img.png"), color, + FlipSettings{false, false}); + game_object.add_component(ParticleEmitter::Data{ + .position = {0, 0}, + .max_particles = 100, + .emission_rate = 0.5, + .min_speed = 1, + .max_speed = 1, + .min_angle = 0, + .max_angle = 0, + .begin_lifespan = 0, + .end_lifespan = 60, + .force_over_time = Vector2{0, 0}, + .boundary{ + .width = 1000, + .height = 1000, + .offset = Vector2{0, 0}, + .reset_on_exit = false, + }, + .sprite = test_sprite, + }); + game_object.add_component(Color::get_white()); + + auto & sys = crepe::RenderSystem::get_instance(); + auto sys_part = crepe::ParticleSystem(); + auto start = std::chrono::steady_clock::now(); + while (std::chrono::steady_clock::now() - start < std::chrono::seconds(5)) { + sys_part.update(); + sys.update(); + SDL_Delay(10 ); + } + + return 0; +} + -- cgit v1.2.3 From cf96d9639dbd18df6451a07fd7b623616e842c4a Mon Sep 17 00:00:00 2001 From: heavydemon21 Date: Mon, 11 Nov 2024 21:27:54 +0100 Subject: adjusted rendering and example --- src/crepe/system/RenderSystem.cpp | 1 + src/example/rendering_particle.cpp | 10 +++++----- 2 files changed, 6 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/crepe/system/RenderSystem.cpp b/src/crepe/system/RenderSystem.cpp index 3de8330..3fbd175 100644 --- a/src/crepe/system/RenderSystem.cpp +++ b/src/crepe/system/RenderSystem.cpp @@ -49,6 +49,7 @@ void RenderSystem::render_particle(const ParticleEmitter& em, Transform & tm){ SDLContext & render = SDLContext::get_instance(); for (const Particle& p : em.data.particles) { + if (!p.active) continue; tm.position = p.position; render.draw(em.data.sprite, tm , *curr_cam); } diff --git a/src/example/rendering_particle.cpp b/src/example/rendering_particle.cpp index 54a9c23..bd4ceb4 100644 --- a/src/example/rendering_particle.cpp +++ b/src/example/rendering_particle.cpp @@ -21,17 +21,17 @@ using namespace crepe; using namespace std; int main(int argc, char * argv[]) { - GameObject game_object(0, "", "", Vector2{0, 0}, 0, 0.1); + GameObject game_object(0, "", "", Vector2{100, 0}, 0, 0.1); Color color(0, 0, 0, 0); Sprite test_sprite = game_object.add_component( make_shared("../asset/texture/img.png"), color, FlipSettings{false, false}); game_object.add_component(ParticleEmitter::Data{ .position = {0, 0}, - .max_particles = 100, - .emission_rate = 0.5, - .min_speed = 1, - .max_speed = 1, + .max_particles = 10, + .emission_rate = 0.1, + .min_speed = 10, + .max_speed = 10, .min_angle = 0, .max_angle = 0, .begin_lifespan = 0, -- cgit v1.2.3 From 0d88ba90c55c0df97e418ce36c435955481b2850 Mon Sep 17 00:00:00 2001 From: heavydemon21 Date: Mon, 11 Nov 2024 21:37:08 +0100 Subject: adjusted renderingsystem --- src/crepe/system/RenderSystem.cpp | 2 +- src/example/rendering_particle.cpp | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/crepe/system/RenderSystem.cpp b/src/crepe/system/RenderSystem.cpp index 3fbd175..8bbf441 100644 --- a/src/crepe/system/RenderSystem.cpp +++ b/src/crepe/system/RenderSystem.cpp @@ -51,6 +51,7 @@ void RenderSystem::render_particle(const ParticleEmitter& em, Transform & tm){ for (const Particle& p : em.data.particles) { if (!p.active) continue; tm.position = p.position; + tm.rotation = p.angle; render.draw(em.data.sprite, tm , *curr_cam); } } @@ -67,7 +68,6 @@ void RenderSystem::render_sprites() { auto transforms = mgr.get_components_by_id(em.game_object_id); test.scale = transforms[0].get().scale; - test.rotation = transforms[0].get().rotation; this->render_particle(em, test); } } diff --git a/src/example/rendering_particle.cpp b/src/example/rendering_particle.cpp index bd4ceb4..dd08354 100644 --- a/src/example/rendering_particle.cpp +++ b/src/example/rendering_particle.cpp @@ -21,7 +21,7 @@ using namespace crepe; using namespace std; int main(int argc, char * argv[]) { - GameObject game_object(0, "", "", Vector2{100, 0}, 0, 0.1); + GameObject game_object(0, "", "", Vector2{100, 100}, 0, 0.1); Color color(0, 0, 0, 0); Sprite test_sprite = game_object.add_component( make_shared("../asset/texture/img.png"), color, @@ -29,11 +29,11 @@ int main(int argc, char * argv[]) { game_object.add_component(ParticleEmitter::Data{ .position = {0, 0}, .max_particles = 10, - .emission_rate = 0.1, - .min_speed = 10, - .max_speed = 10, - .min_angle = 0, - .max_angle = 0, + .emission_rate = 0.5, + .min_speed = 6, + .max_speed = 20, + .min_angle = -20, + .max_angle = 20, .begin_lifespan = 0, .end_lifespan = 60, .force_over_time = Vector2{0, 0}, -- cgit v1.2.3 From fabdc6e27bdb41042d7a530c5f2440ca5a330118 Mon Sep 17 00:00:00 2001 From: heavydemon21 Date: Tue, 12 Nov 2024 19:52:11 +0100 Subject: Adjusted rendering so that now a gameobject can have multiple sprites with particles and another texture --- src/crepe/system/RenderSystem.cpp | 65 ++++++++++++++++++++++++++------------- src/crepe/system/RenderSystem.h | 22 ++++++++----- src/example/rendering.cpp | 1 + 3 files changed, 60 insertions(+), 28 deletions(-) (limited to 'src') diff --git a/src/crepe/system/RenderSystem.cpp b/src/crepe/system/RenderSystem.cpp index 8bbf441..17a2337 100644 --- a/src/crepe/system/RenderSystem.cpp +++ b/src/crepe/system/RenderSystem.cpp @@ -7,10 +7,10 @@ #include "../api/Transform.h" #include "../facade/SDLContext.h" #include "../util/log.h" -#include "Particle.h" -#include "api/ParticleEmitter.h" -#include "api/Vector2.h" +#include "../api/ParticleEmitter.h" +#include "../api/Vector2.h" +#include "Particle.h" #include "RenderSystem.h" using namespace crepe; @@ -43,38 +43,61 @@ void RenderSystem::update_camera() { } } +bool RenderSystem::render_particle(const Sprite & sprite, + const Transform & tm) { -void RenderSystem::render_particle(const ParticleEmitter& em, Transform & tm){ - if (!em.active) return; - + ComponentManager & mgr = ComponentManager::get_instance(); SDLContext & render = SDLContext::get_instance(); - for (const Particle& p : em.data.particles) { - if (!p.active) continue; - tm.position = p.position; - tm.rotation = p.angle; - render.draw(em.data.sprite, tm , *curr_cam); + + auto emitters = mgr.get_components_by_id(sprite.game_object_id); + + bool rendering_particles = false; + + Transform tmp(0, Vector2{0, 0}, 0, 0); + tmp.scale = tm.scale; + for (const ParticleEmitter & em : emitters) { + if (!em.active) continue; + if (!(em.data.sprite.game_object_id == sprite.game_object_id)) continue; + + rendering_particles = true; + + for (const Particle & p : em.data.particles) { + if (!p.active) continue; + tmp.position = p.position; + tmp.rotation = p.angle; + render.draw(em.data.sprite, tmp, *curr_cam); + } } + return rendering_particles; } -void RenderSystem::render_sprites() { +void RenderSystem::render_normal(const Sprite & sprite, const Transform & tm) { ComponentManager & mgr = ComponentManager::get_instance(); + SDLContext & render = SDLContext::get_instance(); + + render.draw(sprite, tm, *curr_cam); +} - auto emitter = mgr.get_components_by_type(); +void RenderSystem::render() { - SDLContext & render = SDLContext::get_instance(); - Transform test(1, Vector2{0,0},0,0); + ComponentManager & mgr = ComponentManager::get_instance(); + + auto sprites = mgr.get_components_by_type(); + for (const Sprite & sprite : sprites) { + if (!sprite.active) continue; + auto transform = mgr.get_components_by_id(sprite.game_object_id); + + bool rendered_particles = this->render_particle(sprite, transform[0].get()); + + if (rendered_particles) continue; - for (const ParticleEmitter & em : emitter) { - auto transforms - = mgr.get_components_by_id(em.game_object_id); - test.scale = transforms[0].get().scale; - this->render_particle(em, test); + this->render_normal(sprite, transform[0].get()); } } void RenderSystem::update() { this->clear_screen(); this->update_camera(); - this->render_sprites(); + this->render(); this->present_screen(); } diff --git a/src/crepe/system/RenderSystem.h b/src/crepe/system/RenderSystem.h index 8dd8b7e..468f79b 100644 --- a/src/crepe/system/RenderSystem.h +++ b/src/crepe/system/RenderSystem.h @@ -1,10 +1,10 @@ #pragma once #include "api/Camera.h" +#include "api/Sprite.h" +#include "api/Transform.h" #include "System.h" -#include "api/ParticleEmitter.h" -#include "api/Transform.h" namespace crepe { @@ -45,14 +45,22 @@ private: //! Updates the active camera used for rendering. void update_camera(); - //! Renders all active sprites to the screen. - void render_sprites() ; - - void render_particle(const ParticleEmitter& em, Transform & tm); + //! Renders the whole screen + void render(); + + /** + * \brief Renders all the particles on the screen from a given sprite. + * + * \param sprite renders the particles with given texture + * \param tm the Transform component for scale + * \return true if particles have been rendered + */ + bool render_particle(const Sprite &, const Transform & tm); + + void render_normal(const Sprite &, const Transform & tm); /** * \todo Include color handling for sprites. - * \todo Implement particle emitter rendering with sprites. * \todo Add text rendering using SDL_ttf for text components. * \todo Implement a text component and a button component. * \todo Ensure each sprite is checked for active status before rendering. diff --git a/src/example/rendering.cpp b/src/example/rendering.cpp index e02f6a3..a7cb5d6 100644 --- a/src/example/rendering.cpp +++ b/src/example/rendering.cpp @@ -35,6 +35,7 @@ int main() { { Color color(0, 0, 0, 0); obj1.add_component(make_shared("../asset/texture/second.png"), color, FlipSettings{true, true}); + obj1.add_component(make_shared("../asset/texture/second.png"), color, FlipSettings{true, true}); } /* -- cgit v1.2.3 From 8524865e9a62974f77f63d70929000fc63c679d7 Mon Sep 17 00:00:00 2001 From: heavydemon21 Date: Tue, 12 Nov 2024 19:55:11 +0100 Subject: makefile --- src/makefile | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/makefile b/src/makefile index 356179e..21903a7 100644 --- a/src/makefile +++ b/src/makefile @@ -28,18 +28,18 @@ MAX += crepe/api/Metadata.cpp MAX += crepe/api/Metadata.h JARO += crepe/Particle.cpp JARO += crepe/Particle.h -TODO += crepe/Position.h -TODO += crepe/api/AssetManager.cpp -TODO += crepe/api/AssetManager.h -TODO += crepe/api/AssetManager.hpp +NIELS += crepe/Position.h +NIELS += crepe/api/AssetManager.cpp +NIELS += crepe/api/AssetManager.h +NIELS += crepe/api/AssetManager.hpp LOEK += crepe/api/AudioSource.cpp LOEK += crepe/api/AudioSource.h LOEK += crepe/api/BehaviorScript.cpp LOEK += crepe/api/BehaviorScript.h LOEK += crepe/api/BehaviorScript.hpp TODO += crepe/api/CircleCollider.h -TODO += crepe/api/Color.cpp -TODO += crepe/api/Color.h +NIELS += crepe/api/Color.cpp +NIELS += crepe/api/Color.h LOEK += crepe/api/Config.h MAX += crepe/api/GameObject.cpp MAX += crepe/api/GameObject.h @@ -53,14 +53,14 @@ JARO += crepe/api/Rigidbody.h LOEK += crepe/api/Script.cpp LOEK += crepe/api/Script.h LOEK += crepe/api/Script.hpp -TODO += crepe/api/Sprite.cpp -TODO += crepe/api/Sprite.h -TODO += crepe/api/Texture.cpp -TODO += crepe/api/Texture.h +NIELS += crepe/api/Sprite.cpp +NIELS += crepe/api/Sprite.h +NIELS += crepe/api/Texture.cpp +NIELS += crepe/api/Texture.h MAX += crepe/api/Transform.cpp MAX += crepe/api/Transform.h -TODO += crepe/facade/SDLContext.cpp -TODO += crepe/facade/SDLContext.h +NIELS += crepe/facade/SDLContext.cpp +NIELS += crepe/facade/SDLContext.h LOEK += crepe/facade/Sound.cpp LOEK += crepe/facade/Sound.h LOEK += crepe/facade/SoundContext.cpp @@ -71,8 +71,8 @@ JARO += crepe/system/ParticleSystem.cpp JARO += crepe/system/ParticleSystem.h JARO += crepe/system/PhysicsSystem.cpp JARO += crepe/system/PhysicsSystem.h -TODO += crepe/system/RenderSystem.cpp -TODO += crepe/system/RenderSystem.h +NIELS += crepe/system/RenderSystem.cpp +NIELS += crepe/system/RenderSystem.h LOEK += crepe/system/ScriptSystem.cpp LOEK += crepe/system/ScriptSystem.h LOEK += crepe/system/System.h @@ -82,21 +82,21 @@ LOEK += crepe/util/fmt.cpp LOEK += crepe/util/fmt.h LOEK += crepe/util/log.cpp LOEK += crepe/util/log.h -TODO += example/asset_manager.cpp +NIELS += example/asset_manager.cpp LOEK += example/audio_internal.cpp TODO += example/components_internal.cpp MAX += example/ecs.cpp LOEK += example/log.cpp JARO += example/particles.cpp JARO += example/physics.cpp -TODO += example/rendering.cpp +NIELS += example/rendering.cpp LOEK += example/script.cpp LOEK += test/audio.cpp LOEK += test/dummy.cpp JARO += test/PhysicsTest.cpp JARO += test/ParticleTest.cpp -FMT := $(JARO) #<<< CHANGE THIS TO YOUR NAME FOR STEP 2 +FMT := $(NIELS) #<<< CHANGE THIS TO YOUR NAME FOR STEP 2 format: FORCE clang-tidy -p build/compile_commands.json --fix-errors $(FMT) -- cgit v1.2.3 From 032f8560b91b76cad5f32a6a9ebfc0ac845ed69a Mon Sep 17 00:00:00 2001 From: heavydemon21 Date: Thu, 14 Nov 2024 10:37:57 +0100 Subject: forget a doxygen docs on a function --- src/crepe/system/RenderSystem.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src') diff --git a/src/crepe/system/RenderSystem.h b/src/crepe/system/RenderSystem.h index 468f79b..6a87eec 100644 --- a/src/crepe/system/RenderSystem.h +++ b/src/crepe/system/RenderSystem.h @@ -57,6 +57,12 @@ private: */ bool render_particle(const Sprite &, const Transform & tm); + /** + * \brief renders a sprite with a Transform component on the screen + * + * \param sprite the sprite component that holds all the data + * \param tm the Transform component that holds the position,rotation and scale + */ void render_normal(const Sprite &, const Transform & tm); /** -- cgit v1.2.3 From 21f5b66d0bcc13d903800adf3bb614e380ff8591 Mon Sep 17 00:00:00 2001 From: heavydemon21 Date: Thu, 14 Nov 2024 15:01:26 +0100 Subject: first part sorted still needing testing --- src/crepe/system/RenderSystem.cpp | 35 ++++++++++++++++++++++++++++++----- src/crepe/system/RenderSystem.h | 8 +++++++- 2 files changed, 37 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/crepe/system/RenderSystem.cpp b/src/crepe/system/RenderSystem.cpp index 10211a3..718036c 100644 --- a/src/crepe/system/RenderSystem.cpp +++ b/src/crepe/system/RenderSystem.cpp @@ -1,3 +1,5 @@ +#include +#include #include #include @@ -6,6 +8,7 @@ #include "../api/Transform.h" #include "../facade/SDLContext.h" #include "../util/log.h" +#include "Asset.h" #include "RenderSystem.h" @@ -29,7 +32,6 @@ void RenderSystem::present_screen() const { } void RenderSystem::update_camera() { ComponentManager & mgr = ComponentManager::get_instance(); - std::vector> cameras = mgr.get_components_by_type(); @@ -38,15 +40,38 @@ void RenderSystem::update_camera() { this->curr_cam = &cam; } } -void RenderSystem::render_sprites() const { + +std::vector> +RenderSystem::sort(std::vector> & objs) { + if (objs.empty()) return {}; + + std::vector> sorted_objs; + sorted_objs.insert(sorted_objs.end(), objs.begin(), objs.end()); + assert(sorted_objs.size() != objs.size()); + + std::sort(sorted_objs.begin(), sorted_objs.end(), + [](const std::reference_wrapper & a, + const std::reference_wrapper & b) { + const Sprite & sprite_a = a.get(); + const Sprite & sprite_b = b.get(); + if (sprite_a.sorting_in_layer == sprite_b.sorting_in_layer) { + return sprite_a.order_in_layer < sprite_b.order_in_layer; + } + return sprite_a.sorting_in_layer < sprite_b.sorting_in_layer; + }); + return sorted_objs; +} + +void RenderSystem::render_sprites() { ComponentManager & mgr = ComponentManager::get_instance(); - std::vector> sprites - = mgr.get_components_by_type(); + auto sprites = mgr.get_components_by_type(); + auto sorted_sprites = this->sort(sprites); + SDLContext & render = SDLContext::get_instance(); - for (const Sprite & sprite : sprites) { + for (const Sprite & sprite : sorted_sprites) { auto transforms = mgr.get_components_by_id(sprite.game_object_id); render.draw(sprite, transforms[0], *curr_cam); diff --git a/src/crepe/system/RenderSystem.h b/src/crepe/system/RenderSystem.h index 70db21a..a83633a 100644 --- a/src/crepe/system/RenderSystem.h +++ b/src/crepe/system/RenderSystem.h @@ -3,6 +3,9 @@ #include "api/Camera.h" #include "System.h" +#include "api/Sprite.h" +#include +#include namespace crepe { @@ -44,7 +47,10 @@ private: void update_camera(); //! Renders all active sprites to the screen. - void render_sprites() const; + void render_sprites() ; + + std::vector> + sort(std::vector> & objs); /** * \todo Include color handling for sprites. -- cgit v1.2.3 From e25aa67c4263b3a940ae9e92f2fcd31a4486f407 Mon Sep 17 00:00:00 2001 From: heavydemon21 Date: Thu, 14 Nov 2024 20:18:19 +0100 Subject: adjusted based on feedback of PR#31 --- src/crepe/facade/SDLContext.cpp | 33 +++++++++++---------------------- src/crepe/facade/SDLContext.h | 9 ++------- src/crepe/system/RenderSystem.cpp | 6 +++--- src/crepe/system/RenderSystem.h | 6 ++++++ 4 files changed, 22 insertions(+), 32 deletions(-) (limited to 'src') diff --git a/src/crepe/facade/SDLContext.cpp b/src/crepe/facade/SDLContext.cpp index cacf238..febbe4b 100644 --- a/src/crepe/facade/SDLContext.cpp +++ b/src/crepe/facade/SDLContext.cpp @@ -7,10 +7,9 @@ #include #include #include -#include #include +#include #include -#include #include "../api/Sprite.h" #include "../api/Texture.h" @@ -32,31 +31,23 @@ SDLContext::SDLContext() { // FIXME: read window defaults from config manager if (SDL_Init(SDL_INIT_VIDEO) < 0) { - // FIXME: throw exception - std::cerr << "SDL could not initialize! SDL_Error: " << SDL_GetError() - << std::endl; - return; + throw std::runtime_error("SDL could not initialize!"); } + SDL_Window * tmp_window = SDL_CreateWindow( "Crepe Game Engine", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, this->viewport.w, this->viewport.h, 0); if (!tmp_window) { - // FIXME: throw exception - std::cerr << "Window could not be created! SDL_Error: " - << SDL_GetError() << std::endl; - return; + throw std::runtime_error("Window could not be created!"); } + this->game_window = {tmp_window, [](SDL_Window * window) { SDL_DestroyWindow(window); }}; SDL_Renderer * tmp_renderer = SDL_CreateRenderer( this->game_window.get(), -1, SDL_RENDERER_ACCELERATED); if (!tmp_renderer) { - // FIXME: throw exception - std::cerr << "Renderer could not be created! SDL_Error: " - << SDL_GetError() << std::endl; - SDL_DestroyWindow(this->game_window.get()); - return; + throw std::runtime_error("Renderer could not be created!"); } this->game_renderer = {tmp_renderer, [](SDL_Renderer * renderer) { @@ -65,9 +56,7 @@ SDLContext::SDLContext() { int img_flags = IMG_INIT_PNG; if (!(IMG_Init(img_flags) & img_flags)) { - // FIXME: throw exception - std::cout << "SDL_image could not initialize! SDL_image Error: " - << IMG_GetError() << std::endl; + throw std::runtime_error("SDL_image could not initialize!"); } } @@ -145,8 +134,8 @@ void SDLContext::draw(const Sprite & sprite, const Transform & transform, void SDLContext::camera(const Camera & cam) { this->viewport.w = static_cast(cam.aspect_width); this->viewport.h = static_cast(cam.aspect_height); - this->viewport.x = static_cast(cam.x) - (SCREEN_WIDTH / 2); - this->viewport.y = static_cast(cam.y) - (SCREEN_HEIGHT / 2); + this->viewport.x = static_cast(cam.x) - (this->viewport.w / 2); + this->viewport.y = static_cast(cam.y) - (this->viewport.h / 2); SDL_SetRenderDrawColor(this->game_renderer.get(), cam.bg_color.r, cam.bg_color.g, cam.bg_color.b, cam.bg_color.a); @@ -181,12 +170,12 @@ SDLContext::texture_from_path(const std::string & path) { return img_texture; } -int SDLContext::get_width(const Texture & ctx) { +int SDLContext::get_width(const Texture & ctx) const { int w; SDL_QueryTexture(ctx.texture.get(), NULL, NULL, &w, NULL); return w; } -int SDLContext::get_height(const Texture & ctx) { +int SDLContext::get_height(const Texture & ctx) const { int h; SDL_QueryTexture(ctx.texture.get(), NULL, NULL, NULL, &h); return h; diff --git a/src/crepe/facade/SDLContext.h b/src/crepe/facade/SDLContext.h index c4392bd..0614036 100644 --- a/src/crepe/facade/SDLContext.h +++ b/src/crepe/facade/SDLContext.h @@ -10,11 +10,6 @@ #include "../api/Sprite.h" #include "../api/Transform.h" #include "api/Camera.h" -#include "api/Vector2.h" - -// FIXME: this needs to be removed -const int SCREEN_WIDTH = 640; -const int SCREEN_HEIGHT = 480; namespace crepe { @@ -109,14 +104,14 @@ private: * \param texture Reference to the Texture object. * \return Width of the texture as an integer. */ - int get_width(const Texture &) ; + int get_width(const Texture &) const; /** * \brief Gets the height of a texture. * \param texture Reference to the Texture object. * \return Height of the texture as an integer. */ - int get_height(const Texture &) ; + int get_height(const Texture &) const; private: //! Will use draw,clear_screen, present_screen, camera. diff --git a/src/crepe/system/RenderSystem.cpp b/src/crepe/system/RenderSystem.cpp index 17a2337..6ecd604 100644 --- a/src/crepe/system/RenderSystem.cpp +++ b/src/crepe/system/RenderSystem.cpp @@ -85,13 +85,13 @@ void RenderSystem::render() { auto sprites = mgr.get_components_by_type(); for (const Sprite & sprite : sprites) { if (!sprite.active) continue; - auto transform = mgr.get_components_by_id(sprite.game_object_id); + auto transform = mgr.get_components_by_id(sprite.game_object_id).front().get(); - bool rendered_particles = this->render_particle(sprite, transform[0].get()); + bool rendered_particles = this->render_particle(sprite, transform); if (rendered_particles) continue; - this->render_normal(sprite, transform[0].get()); + this->render_normal(sprite, transform); } } diff --git a/src/crepe/system/RenderSystem.h b/src/crepe/system/RenderSystem.h index 6a87eec..3d6286f 100644 --- a/src/crepe/system/RenderSystem.h +++ b/src/crepe/system/RenderSystem.h @@ -31,6 +31,12 @@ public: */ void update() override; + + RenderSystem(const RenderSystem &) = delete; + RenderSystem(RenderSystem &&) = delete; + RenderSystem & operator=(const RenderSystem &) = delete; + RenderSystem & operator=(RenderSystem &&) = delete; + private: // Private constructor to enforce singleton pattern. RenderSystem(); -- cgit v1.2.3 From ed1403aea4412bd479244eae8e2940190e71cd28 Mon Sep 17 00:00:00 2001 From: heavydemon21 Date: Fri, 15 Nov 2024 09:48:04 +0100 Subject: example --- src/example/rendering_particle.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/example/rendering_particle.cpp b/src/example/rendering_particle.cpp index dd08354..33013ef 100644 --- a/src/example/rendering_particle.cpp +++ b/src/example/rendering_particle.cpp @@ -22,14 +22,14 @@ using namespace std; int main(int argc, char * argv[]) { GameObject game_object(0, "", "", Vector2{100, 100}, 0, 0.1); - Color color(0, 0, 0, 0); + Color color(255, 255, 255, 255); Sprite test_sprite = game_object.add_component( make_shared("../asset/texture/img.png"), color, FlipSettings{false, false}); game_object.add_component(ParticleEmitter::Data{ .position = {0, 0}, .max_particles = 10, - .emission_rate = 0.5, + .emission_rate = 0.1, .min_speed = 6, .max_speed = 20, .min_angle = -20, -- cgit v1.2.3 From c9aac3ea385213b7b9a9a4e7e48e45e6a1268902 Mon Sep 17 00:00:00 2001 From: heavydemon21 Date: Mon, 18 Nov 2024 15:03:39 +0100 Subject: working sorting --- src/crepe/system/RenderSystem.cpp | 37 +++++++++++++++++++------------------ src/example/rendering.cpp | 25 +++++++++++++++++++++---- 2 files changed, 40 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/crepe/system/RenderSystem.cpp b/src/crepe/system/RenderSystem.cpp index aa9910b..ba804d4 100644 --- a/src/crepe/system/RenderSystem.cpp +++ b/src/crepe/system/RenderSystem.cpp @@ -1,13 +1,13 @@ #include #include #include +#include #include #include "../ComponentManager.h" #include "../api/Sprite.h" #include "../api/Transform.h" #include "../facade/SDLContext.h" -#include "../util/Log.h" #include "RenderSystem.h" @@ -27,38 +27,39 @@ void RenderSystem::update_camera() { } } +bool sorting_comparison(const Sprite & a, const Sprite & b) { + if (a.sorting_in_layer > b.sorting_in_layer) return true; + if (a.sorting_in_layer == b.sorting_in_layer) return a.order_in_layer > b.order_in_layer; + + return false; +} + std::vector> RenderSystem::sort(std::vector> & objs) { if (objs.empty()) return {}; - std::vector> sorted_objs; - sorted_objs.insert(sorted_objs.end(), objs.begin(), objs.end()); - assert(sorted_objs.size() != objs.size()); - - std::sort(sorted_objs.begin(), sorted_objs.end(), - [](const std::reference_wrapper & a, - const std::reference_wrapper & b) { - const Sprite & sprite_a = a.get(); - const Sprite & sprite_b = b.get(); - if (sprite_a.sorting_in_layer == sprite_b.sorting_in_layer) { - return sprite_a.order_in_layer < sprite_b.order_in_layer; - } - return sprite_a.sorting_in_layer < sprite_b.sorting_in_layer; - }); + std::vector> sorted_objs(objs); + std::sort(sorted_objs.begin(), sorted_objs.end(), sorting_comparison); + return sorted_objs; } void RenderSystem::render_sprites() { ComponentManager & mgr = this->component_manager; - ComponentManager & mgr = ComponentManager::get_instance(); - auto sprites = mgr.get_components_by_type(); + for (const Sprite & s : sprites) { + std::cout << s.game_object_id << " " << unsigned(s.sorting_in_layer) << " " + << unsigned(s.order_in_layer) << std::endl; + } + auto sorted_sprites = this->sort(sprites); - + SDLContext & render = SDLContext::get_instance(); for (const Sprite & sprite : sorted_sprites) { + std::cout << sprite.game_object_id << " " << unsigned(sprite.sorting_in_layer) << " " + << unsigned(sprite.order_in_layer) << std::endl; auto transforms = mgr.get_components_by_id(sprite.game_object_id); render.draw(sprite, transforms[0], *curr_cam); } diff --git a/src/example/rendering.cpp b/src/example/rendering.cpp index c9e62f1..ecd3f6a 100644 --- a/src/example/rendering.cpp +++ b/src/example/rendering.cpp @@ -30,14 +30,27 @@ int main() { // Normal adding components { Color color(0, 0, 0, 0); - obj.add_component(make_shared("../asset/texture/img.png"), color, - FlipSettings{false, false}); + Sprite & sprite + = obj.add_component(make_shared("../asset/texture/img.png"), + color, FlipSettings{false, false}); + sprite.sorting_in_layer = 2; + sprite.order_in_layer = 1; obj.add_component(Color::get_red()); } { Color color(0, 0, 0, 0); - obj1.add_component(make_shared("../asset/texture/second.png"), color, - FlipSettings{true, true}); + Sprite & sprite = obj1.add_component( + make_shared("../asset/texture/img.png"), color, FlipSettings{true, true}); + sprite.sorting_in_layer = 2; + sprite.order_in_layer = 2; + } + + { + Color color(0, 0, 0, 0); + Sprite & sprite = obj2.add_component( + make_shared("../asset/texture/img.png"), color, FlipSettings{true, true}); + sprite.sorting_in_layer = 1; + sprite.order_in_layer = 2; } /* @@ -48,8 +61,12 @@ int main() { } */ + sys.update(); + /* + auto start = std::chrono::steady_clock::now(); while (std::chrono::steady_clock::now() - start < std::chrono::seconds(5)) { sys.update(); } + */ } -- cgit v1.2.3 From bae2501c9e2604497db152d5e3df6a018cdd6858 Mon Sep 17 00:00:00 2001 From: heavydemon21 Date: Mon, 18 Nov 2024 15:04:36 +0100 Subject: removed iostream & printing --- src/crepe/system/RenderSystem.cpp | 9 --------- 1 file changed, 9 deletions(-) (limited to 'src') diff --git a/src/crepe/system/RenderSystem.cpp b/src/crepe/system/RenderSystem.cpp index ba804d4..bf5dade 100644 --- a/src/crepe/system/RenderSystem.cpp +++ b/src/crepe/system/RenderSystem.cpp @@ -1,7 +1,6 @@ #include #include #include -#include #include #include "../ComponentManager.h" @@ -48,18 +47,10 @@ void RenderSystem::render_sprites() { ComponentManager & mgr = this->component_manager; auto sprites = mgr.get_components_by_type(); - - for (const Sprite & s : sprites) { - std::cout << s.game_object_id << " " << unsigned(s.sorting_in_layer) << " " - << unsigned(s.order_in_layer) << std::endl; - } - auto sorted_sprites = this->sort(sprites); SDLContext & render = SDLContext::get_instance(); for (const Sprite & sprite : sorted_sprites) { - std::cout << sprite.game_object_id << " " << unsigned(sprite.sorting_in_layer) << " " - << unsigned(sprite.order_in_layer) << std::endl; auto transforms = mgr.get_components_by_id(sprite.game_object_id); render.draw(sprite, transforms[0], *curr_cam); } -- cgit v1.2.3 From 74fcf733c2bcdcbcbfc64d88270b12a39e9d91e0 Mon Sep 17 00:00:00 2001 From: heavydemon21 Date: Mon, 18 Nov 2024 15:18:20 +0100 Subject: merged master --- src/crepe/system/RenderSystem.cpp | 18 +++++++----------- src/crepe/system/RenderSystem.h | 2 +- 2 files changed, 8 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/crepe/system/RenderSystem.cpp b/src/crepe/system/RenderSystem.cpp index 23ab738..37320ed 100644 --- a/src/crepe/system/RenderSystem.cpp +++ b/src/crepe/system/RenderSystem.cpp @@ -6,11 +6,9 @@ #include "../api/Sprite.h" #include "../api/Transform.h" #include "../facade/SDLContext.h" -#include "../util/log.h" #include "../api/ParticleEmitter.h" #include "../api/Vector2.h" -#include "Particle.h" #include "RenderSystem.h" using namespace crepe; @@ -30,17 +28,15 @@ void RenderSystem::update_camera() { } bool RenderSystem::render_particle(const Sprite & sprite, - const Transform & tm) { + Transform tm) { - ComponentManager & mgr = ComponentManager::get_instance(); + ComponentManager & mgr = this->component_manager; SDLContext & render = SDLContext::get_instance(); auto emitters = mgr.get_components_by_id(sprite.game_object_id); bool rendering_particles = false; - Transform tmp(0, Vector2{0, 0}, 0, 0); - tmp.scale = tm.scale; for (const ParticleEmitter & em : emitters) { if (!em.active) continue; if (!(em.data.sprite.game_object_id == sprite.game_object_id)) continue; @@ -49,16 +45,16 @@ bool RenderSystem::render_particle(const Sprite & sprite, for (const Particle & p : em.data.particles) { if (!p.active) continue; - tmp.position = p.position; - tmp.rotation = p.angle; - render.draw(em.data.sprite, tmp, *curr_cam); + tm.position = p.position; + tm.rotation = p.angle; + render.draw(em.data.sprite, tm, *curr_cam); } } return rendering_particles; } void RenderSystem::render_normal(const Sprite & sprite, const Transform & tm) { - ComponentManager & mgr = ComponentManager::get_instance(); + ComponentManager & mgr = this->component_manager; SDLContext & render = SDLContext::get_instance(); render.draw(sprite, tm, *curr_cam); @@ -66,7 +62,7 @@ void RenderSystem::render_normal(const Sprite & sprite, const Transform & tm) { void RenderSystem::render() { - ComponentManager & mgr = ComponentManager::get_instance(); + ComponentManager & mgr = this->component_manager; auto sprites = mgr.get_components_by_type(); for (const Sprite & sprite : sprites) { diff --git a/src/crepe/system/RenderSystem.h b/src/crepe/system/RenderSystem.h index ad44716..c18b80b 100644 --- a/src/crepe/system/RenderSystem.h +++ b/src/crepe/system/RenderSystem.h @@ -51,7 +51,7 @@ private: * \param tm the Transform component for scale * \return true if particles have been rendered */ - bool render_particle(const Sprite &, const Transform & tm); + bool render_particle(const Sprite &, Transform tm); /** * \brief renders a sprite with a Transform component on the screen -- cgit v1.2.3 From 8d78727d6e7badca16ba7a1328643928a0039569 Mon Sep 17 00:00:00 2001 From: Loek Le Blansch Date: Mon, 18 Nov 2024 18:02:09 +0100 Subject: move utilities from loek/audio --- .crepe-root | 0 .gitmodules | 4 +++ lib/whereami/CMakeLists.txt | 38 +++++++++++++++++++++++ lib/whereami/lib | 1 + src/CMakeLists.txt | 2 ++ src/crepe/Asset.cpp | 16 ---------- src/crepe/Asset.h | 41 ------------------------- src/crepe/CMakeLists.txt | 2 -- src/crepe/api/Asset.cpp | 58 +++++++++++++++++++++++++++++++++++ src/crepe/api/Asset.h | 60 ++++++++++++++++++++++++++++++++++++ src/crepe/api/CMakeLists.txt | 2 ++ src/crepe/api/Config.h | 14 +++++++++ src/crepe/api/Texture.cpp | 2 +- src/crepe/facade/SDLContext.cpp | 2 +- src/crepe/facade/Sound.cpp | 2 +- src/crepe/facade/Sound.h | 2 +- src/crepe/system/System.h | 2 ++ src/crepe/util/CMakeLists.txt | 2 ++ src/crepe/util/OptionalRef.h | 41 +++++++++++++++++++++++++ src/crepe/util/OptionalRef.hpp | 67 +++++++++++++++++++++++++++++++++++++++++ src/example/audio_internal.cpp | 8 ++--- src/example/particles.cpp | 2 +- src/example/rendering.cpp | 10 +++--- src/test/AssetTest.cpp | 33 ++++++++++++++++++++ src/test/CMakeLists.txt | 2 ++ src/test/OptionalRefTest.cpp | 38 +++++++++++++++++++++++ 26 files changed, 378 insertions(+), 73 deletions(-) create mode 100644 .crepe-root create mode 100644 lib/whereami/CMakeLists.txt create mode 160000 lib/whereami/lib delete mode 100644 src/crepe/Asset.cpp delete mode 100644 src/crepe/Asset.h create mode 100644 src/crepe/api/Asset.cpp create mode 100644 src/crepe/api/Asset.h create mode 100644 src/crepe/util/OptionalRef.h create mode 100644 src/crepe/util/OptionalRef.hpp create mode 100644 src/test/AssetTest.cpp create mode 100644 src/test/OptionalRefTest.cpp (limited to 'src') diff --git a/.crepe-root b/.crepe-root new file mode 100644 index 0000000..e69de29 diff --git a/.gitmodules b/.gitmodules index 2f64601..bd6e7f7 100644 --- a/.gitmodules +++ b/.gitmodules @@ -22,3 +22,7 @@ path = lib/libdb url = https://github.com/berkeleydb/libdb shallow = true +[submodule "lib/whereami/whereami"] + path = lib/whereami/lib + url = https://github.com/gpakosz/whereami + shallow = true diff --git a/lib/whereami/CMakeLists.txt b/lib/whereami/CMakeLists.txt new file mode 100644 index 0000000..96d3a23 --- /dev/null +++ b/lib/whereami/CMakeLists.txt @@ -0,0 +1,38 @@ +cmake_minimum_required(VERSION 3.28) +set(CMAKE_C_STANDARD 11) +project(whereami C) + +include(CMakePackageConfigHelpers) + +add_library(whereami SHARED) + +target_include_directories(whereami PRIVATE SYSTEM lib/src) +target_sources(whereami PRIVATE lib/src/whereami.c) + +install( + TARGETS whereami + EXPORT whereamiTargets + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib + RUNTIME DESTINATION lib + INCLUDES DESTINATION include +) +install( + FILES lib/src/whereami.h + DESTINATION include +) +write_basic_package_version_file( + "${CMAKE_CURRENT_BINARY_DIR}/whereami-config-version.cmake" + VERSION 0.0.0 + COMPATIBILITY AnyNewerVersion +) +install( + FILES + "${CMAKE_CURRENT_BINARY_DIR}/whereami-config-version.cmake" + DESTINATION lib/cmake/whereami +) +install( + EXPORT whereamiTargets + FILE whereami-config.cmake + DESTINATION lib/cmake/whereami +) diff --git a/lib/whereami/lib b/lib/whereami/lib new file mode 160000 index 0000000..dcb52a0 --- /dev/null +++ b/lib/whereami/lib @@ -0,0 +1 @@ +Subproject commit dcb52a058dc14530ba9ae05e4339bd3ddfae0e0e diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 445a8b2..c3f29da 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -11,6 +11,7 @@ find_package(SDL2 REQUIRED) find_package(SDL2_image REQUIRED) find_package(SoLoud REQUIRED) find_package(GTest REQUIRED) +find_package(whereami REQUIRED) find_library(BERKELEY_DB db) add_library(crepe SHARED) @@ -25,6 +26,7 @@ target_link_libraries(crepe PUBLIC SDL2 PUBLIC SDL2_image PUBLIC ${BERKELEY_DB} + PUBLIC whereami ) add_subdirectory(crepe) diff --git a/src/crepe/Asset.cpp b/src/crepe/Asset.cpp deleted file mode 100644 index 9c41ecb..0000000 --- a/src/crepe/Asset.cpp +++ /dev/null @@ -1,16 +0,0 @@ -#include - -#include "Asset.h" - -using namespace crepe; -using namespace std; - -// FIXME: restore this -// src(std::filesystem::canonical(src)) -Asset::Asset(const std::string & src) : src(src) { - this->file = std::ifstream(this->src, std::ios::in | std::ios::binary); -} - -istream & Asset::get_stream() { return this->file; } - -const string & Asset::get_canonical() const { return this->src; } diff --git a/src/crepe/Asset.h b/src/crepe/Asset.h deleted file mode 100644 index 9051c5e..0000000 --- a/src/crepe/Asset.h +++ /dev/null @@ -1,41 +0,0 @@ -#pragma once - -#include -#include -#include - -namespace crepe { - -/** - * \brief Asset location helper - * - * This class is used to locate and canonicalize paths to game asset files, and should *always* - * be used when retrieving files from disk. - */ -class Asset { -public: - /** - * \param src Unique identifier to asset - */ - Asset(const std::string & src); - -public: - /** - * \brief Get an input stream to the contents of this asset - * \return Input stream with file contents - */ - std::istream & get_stream(); - /** - * \brief Get the canonical path to this asset - * \return Canonical path to this asset - */ - const std::string & get_canonical() const; - -private: - //! Canonical path to asset - const std::string src; - //! File handle (stream) - std::ifstream file; -}; - -} // namespace crepe diff --git a/src/crepe/CMakeLists.txt b/src/crepe/CMakeLists.txt index 3b05742..7e176e7 100644 --- a/src/crepe/CMakeLists.txt +++ b/src/crepe/CMakeLists.txt @@ -1,5 +1,4 @@ target_sources(crepe PUBLIC - Asset.cpp Particle.cpp ComponentManager.cpp Component.cpp @@ -7,7 +6,6 @@ target_sources(crepe PUBLIC ) target_sources(crepe PUBLIC FILE_SET HEADERS FILES - Asset.h ComponentManager.h ComponentManager.hpp Component.h diff --git a/src/crepe/api/Asset.cpp b/src/crepe/api/Asset.cpp new file mode 100644 index 0000000..5271cf7 --- /dev/null +++ b/src/crepe/api/Asset.cpp @@ -0,0 +1,58 @@ +#include +#include +#include + +#include "Asset.h" +#include "api/Config.h" + +using namespace crepe; +using namespace std; + +Asset::Asset(const string & src) : src(find_asset(src)) { } +Asset::Asset(const char * src) : src(find_asset(src)) { } + +const string & Asset::get_path() const noexcept { return this->src; } + +string Asset::find_asset(const string & src) const { + auto & cfg = Config::get_instance(); + auto & root_pattern = cfg.asset.root_pattern; + + // if root_pattern is empty, find_asset must return all paths as-is + if (root_pattern.empty()) return src; + + // absolute paths do not need to be resolved, only canonicalized + filesystem::path path = src; + if (path.is_absolute()) + return filesystem::canonical(path); + + // find directory matching root_pattern + filesystem::path root = this->whereami(); + while (1) { + if (filesystem::exists(root / root_pattern)) + break; + if (!root.has_parent_path()) + throw runtime_error(format("Asset: Cannot find root pattern ({})", root_pattern)); + root = root.parent_path(); + } + + // join path to root (base directory) and canonicalize + return filesystem::canonical(root / path); +} + +string Asset::whereami() const noexcept { + string path; + size_t path_length = wai_getExecutablePath(NULL, 0, NULL); + path.resize(path_length + 1); // wai writes null byte + wai_getExecutablePath(path.data(), path_length, NULL); + path.resize(path_length); + return path; +} + +bool Asset::operator==(const Asset & other) const noexcept { + return this->src == other.src; +} + +size_t std::hash::operator()(const Asset & asset) const noexcept { + return std::hash{}(asset.get_path()); +}; + diff --git a/src/crepe/api/Asset.h b/src/crepe/api/Asset.h new file mode 100644 index 0000000..05dccba --- /dev/null +++ b/src/crepe/api/Asset.h @@ -0,0 +1,60 @@ +#pragma once + +#include +#include + +namespace crepe { + +/** + * \brief Asset location helper + * + * This class is used to locate game asset files, and should *always* be used + * instead of reading file paths directly. + */ +class Asset { +public: + /** + * \param src Unique identifier to asset + */ + Asset(const std::string & src); + /** + * \param src Unique identifier to asset + */ + Asset(const char * src); + +public: + /** + * \brief Get the path to this asset + * \return path to this asset + */ + const std::string & get_path() const noexcept; + + /** + * \brief Comparison operator + * \param other Possibly different instance of \c Asset to test equality against + * \return True if \c this and \c other are equal + */ + bool operator == (const Asset & other) const noexcept; + +private: + //! path to asset + const std::string src; + +private: + std::string find_asset(const std::string & src) const; + /** + * \returns The path to the current executable + */ + std::string whereami() const noexcept; +}; + +} // namespace crepe + +namespace std { + +template<> struct hash { + size_t operator()(const crepe::Asset & asset) const noexcept; +}; + +} + diff --git a/src/crepe/api/CMakeLists.txt b/src/crepe/api/CMakeLists.txt index f9b370f..6557656 100644 --- a/src/crepe/api/CMakeLists.txt +++ b/src/crepe/api/CMakeLists.txt @@ -19,6 +19,7 @@ target_sources(crepe PUBLIC Animator.cpp LoopManager.cpp LoopTimer.cpp + Asset.cpp ) target_sources(crepe PUBLIC FILE_SET HEADERS FILES @@ -45,4 +46,5 @@ target_sources(crepe PUBLIC FILE_SET HEADERS FILES Animator.h LoopManager.h LoopTimer.h + Asset.h ) diff --git a/src/crepe/api/Config.h b/src/crepe/api/Config.h index 3ab877a..13eabd1 100644 --- a/src/crepe/api/Config.h +++ b/src/crepe/api/Config.h @@ -62,6 +62,20 @@ public: */ double gravity = 1; } physics; + + //! Asset loading options + struct { + /** + * \brief Pattern to match for Asset base directory + * + * All non-absolute paths resolved using \c Asset will be made relative to + * the first parent directory relative to the calling executable where + * appending this pattern results in a path that exists. If this string is + * empty, path resolution is disabled, and Asset will return all paths + * as-is. + */ + std::string root_pattern = ".crepe-root"; + } asset; }; } // namespace crepe diff --git a/src/crepe/api/Texture.cpp b/src/crepe/api/Texture.cpp index de0d0ea..6a1e4d8 100644 --- a/src/crepe/api/Texture.cpp +++ b/src/crepe/api/Texture.cpp @@ -26,7 +26,7 @@ Texture::~Texture() { void Texture::load(unique_ptr res) { SDLContext & ctx = SDLContext::get_instance(); - this->texture = std::move(ctx.texture_from_path(res->get_canonical())); + this->texture = std::move(ctx.texture_from_path(res->get_path())); } int Texture::get_width() const { diff --git a/src/crepe/facade/SDLContext.cpp b/src/crepe/facade/SDLContext.cpp index 83e91f8..f2daada 100644 --- a/src/crepe/facade/SDLContext.cpp +++ b/src/crepe/facade/SDLContext.cpp @@ -149,7 +149,7 @@ SDLContext::texture_from_path(const std::string & path) { SDL_Surface * tmp = IMG_Load(path.c_str()); if (tmp == nullptr) { - tmp = IMG_Load("../asset/texture/ERROR.png"); + tmp = IMG_Load("asset/texture/ERROR.png"); } std::unique_ptr> img_surface; diff --git a/src/crepe/facade/Sound.cpp b/src/crepe/facade/Sound.cpp index 7aa89a9..4d3abf5 100644 --- a/src/crepe/facade/Sound.cpp +++ b/src/crepe/facade/Sound.cpp @@ -16,7 +16,7 @@ Sound::Sound(const char * src) { this->load(make_unique(src)); } -void Sound::load(unique_ptr res) { this->sample.load(res->get_canonical().c_str()); } +void Sound::load(unique_ptr res) { this->sample.load(res->get_path().c_str()); } void Sound::play() { SoundContext & ctx = SoundContext::get_instance(); diff --git a/src/crepe/facade/Sound.h b/src/crepe/facade/Sound.h index 32b6478..4c68f32 100644 --- a/src/crepe/facade/Sound.h +++ b/src/crepe/facade/Sound.h @@ -4,7 +4,7 @@ #include #include -#include "../Asset.h" +#include "../api/Asset.h" namespace crepe { diff --git a/src/crepe/system/System.h b/src/crepe/system/System.h index 28ea20e..36f7edc 100644 --- a/src/crepe/system/System.h +++ b/src/crepe/system/System.h @@ -1,5 +1,7 @@ #pragma once +#include "../ComponentManager.h" + namespace crepe { class ComponentManager; diff --git a/src/crepe/util/CMakeLists.txt b/src/crepe/util/CMakeLists.txt index 4be738a..94ed906 100644 --- a/src/crepe/util/CMakeLists.txt +++ b/src/crepe/util/CMakeLists.txt @@ -9,5 +9,7 @@ target_sources(crepe PUBLIC FILE_SET HEADERS FILES Log.hpp Proxy.h Proxy.hpp + OptionalRef.h + OptionalRef.hpp ) diff --git a/src/crepe/util/OptionalRef.h b/src/crepe/util/OptionalRef.h new file mode 100644 index 0000000..1ad3a6d --- /dev/null +++ b/src/crepe/util/OptionalRef.h @@ -0,0 +1,41 @@ +#pragma once + +namespace crepe { + +/** + * \brief Optional reference utility + * + * This class doesn't need to know the full definition of \c T to be used. + * + * \tparam T Value type + */ +template +class OptionalRef { +public: + OptionalRef() = default; + OptionalRef(T &); + OptionalRef & operator=(T &); + explicit operator bool() const noexcept; + + void set(T &) noexcept; + T & get() const; + void clear() noexcept; + + OptionalRef(const OptionalRef &); + OptionalRef(OptionalRef &&); + OptionalRef & operator=(const OptionalRef &); + OptionalRef & operator=(OptionalRef &&); + +private: + /** + * \brief Reference to the value of type \c T + * + * \note This raw pointer is *not* managed, and only used as a reference! + */ + T * ref = nullptr; +}; + +} + +#include "OptionalRef.hpp" + diff --git a/src/crepe/util/OptionalRef.hpp b/src/crepe/util/OptionalRef.hpp new file mode 100644 index 0000000..7b201b0 --- /dev/null +++ b/src/crepe/util/OptionalRef.hpp @@ -0,0 +1,67 @@ +#pragma once + +#include + +#include "OptionalRef.h" + +namespace crepe { + +template +OptionalRef::OptionalRef(T & ref) { + this->set(ref); +} + +template +OptionalRef::OptionalRef(const OptionalRef & other) { + this->ref = other.ref; +} + +template +OptionalRef::OptionalRef(OptionalRef && other) { + this->ref = other.ref; + other.clear(); +} + +template +OptionalRef & OptionalRef::operator=(const OptionalRef & other) { + this->ref = other.ref; + return *this; +} + +template +OptionalRef & OptionalRef::operator=(OptionalRef && other) { + this->ref = other.ref; + other.clear(); + return *this; +} + +template +T & OptionalRef::get() const { + if (this->ref == nullptr) + throw std::runtime_error("OptionalRef: attempt to dereference nullptr"); + return *this->ref; +} + +template +void OptionalRef::set(T & ref) noexcept { + this->ref = &ref; +} + +template +void OptionalRef::clear() noexcept { + this->ref = nullptr; +} + +template +OptionalRef & OptionalRef::operator=(T & ref) { + this->set(ref); + return *this; +} + +template +OptionalRef::operator bool() const noexcept { + return this->ref != nullptr; +} + +} + diff --git a/src/example/audio_internal.cpp b/src/example/audio_internal.cpp index 661161a..1647f20 100644 --- a/src/example/audio_internal.cpp +++ b/src/example/audio_internal.cpp @@ -25,11 +25,11 @@ int _ = []() { int main() { // Load a background track (Ogg Vorbis) - auto bgm = Sound("../mwe/audio/bgm.ogg"); + auto bgm = Sound("mwe/audio/bgm.ogg"); // Load three short samples (WAV) - auto sfx1 = Sound("../mwe/audio/sfx1.wav"); - auto sfx2 = Sound("../mwe/audio/sfx2.wav"); - auto sfx3 = Sound("../mwe/audio/sfx3.wav"); + auto sfx1 = Sound("mwe/audio/sfx1.wav"); + auto sfx2 = Sound("mwe/audio/sfx2.wav"); + auto sfx3 = Sound("mwe/audio/sfx3.wav"); // Start the background track bgm.play(); diff --git a/src/example/particles.cpp b/src/example/particles.cpp index 3d5f676..d4638a2 100644 --- a/src/example/particles.cpp +++ b/src/example/particles.cpp @@ -18,7 +18,7 @@ int main(int argc, char * argv[]) { GameObject game_object = mgr.new_object("", "", Vector2{0, 0}, 0, 0); Color color(0, 0, 0, 0); Sprite test_sprite = game_object.add_component( - make_shared("../asset/texture/img.png"), color, FlipSettings{true, true}); + make_shared("asset/texture/img.png"), color, FlipSettings{true, true}); game_object.add_component(ParticleEmitter::Data{ .position = {0, 0}, .max_particles = 100, diff --git a/src/example/rendering.cpp b/src/example/rendering.cpp index c9e62f1..c813524 100644 --- a/src/example/rendering.cpp +++ b/src/example/rendering.cpp @@ -30,20 +30,20 @@ int main() { // Normal adding components { Color color(0, 0, 0, 0); - obj.add_component(make_shared("../asset/texture/img.png"), color, - FlipSettings{false, false}); + obj.add_component( + make_shared("asset/texture/img.png"), color, FlipSettings{false, false}); obj.add_component(Color::get_red()); } { Color color(0, 0, 0, 0); - obj1.add_component(make_shared("../asset/texture/second.png"), color, - FlipSettings{true, true}); + obj1.add_component( + make_shared("asset/texture/second.png"), color, FlipSettings{true, true}); } /* { Color color(0, 0, 0, 0); - auto img = mgr.cache("../asset/texture/second.png"); + auto img = mgr.cache("asset/texture/second.png"); obj2.add_component(img, color, FlipSettings{true, true}); } */ diff --git a/src/test/AssetTest.cpp b/src/test/AssetTest.cpp new file mode 100644 index 0000000..563a253 --- /dev/null +++ b/src/test/AssetTest.cpp @@ -0,0 +1,33 @@ +#include + +#include +#include + +using namespace std; +using namespace crepe; +using namespace testing; + +class AssetTest : public Test { +public: + Config & cfg = Config::get_instance(); + void SetUp() override { + this->cfg.asset.root_pattern = ".crepe-root"; + } +}; + +TEST_F(AssetTest, Existant) { + ASSERT_NO_THROW(Asset{"asset/texture/img.png"}); +} + +TEST_F(AssetTest, Nonexistant) { + ASSERT_ANY_THROW(Asset{"asset/nonexistant"}); +} + +TEST_F(AssetTest, Rootless) { + cfg.asset.root_pattern.clear(); + + string arbitrary = "\\/this is / /../passed through as-is"; + Asset asset{arbitrary}; + ASSERT_EQ(arbitrary, asset.get_path()); +} + diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt index 49c8151..f722082 100644 --- a/src/test/CMakeLists.txt +++ b/src/test/CMakeLists.txt @@ -3,5 +3,7 @@ target_sources(test_main PUBLIC PhysicsTest.cpp ScriptTest.cpp ParticleTest.cpp + AssetTest.cpp + OptionalRefTest.cpp ) diff --git a/src/test/OptionalRefTest.cpp b/src/test/OptionalRefTest.cpp new file mode 100644 index 0000000..219ccca --- /dev/null +++ b/src/test/OptionalRefTest.cpp @@ -0,0 +1,38 @@ +#include + +#include + +using namespace std; +using namespace crepe; +using namespace testing; + +TEST(OptionalRefTest, Explicit) { + string value = "foo"; + OptionalRef ref; + EXPECT_FALSE(ref); + ASSERT_THROW(ref.get(), runtime_error); + + ref.set(value); + EXPECT_TRUE(ref); + ASSERT_NO_THROW(ref.get()); + + ref.clear(); + EXPECT_FALSE(ref); + ASSERT_THROW(ref.get(), runtime_error); +} + +TEST(OptionalRefTest, Implicit) { + string value = "foo"; + OptionalRef ref = value; + EXPECT_TRUE(ref); + ASSERT_NO_THROW(ref.get()); + + ref.clear(); + EXPECT_FALSE(ref); + ASSERT_THROW(ref.get(), runtime_error); + + ref = value; + EXPECT_TRUE(ref); + ASSERT_NO_THROW(ref.get()); +} + -- cgit v1.2.3 From 9770b548c5619821d7b6ea7a017df2b5a6898d0a Mon Sep 17 00:00:00 2001 From: Loek Le Blansch Date: Mon, 18 Nov 2024 18:10:31 +0100 Subject: add doxygen comments --- src/crepe/api/Asset.h | 10 +++++++++- src/crepe/util/OptionalRef.h | 37 +++++++++++++++++++++++++++++++++++-- 2 files changed, 44 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/crepe/api/Asset.h b/src/crepe/api/Asset.h index 05dccba..685dd3a 100644 --- a/src/crepe/api/Asset.h +++ b/src/crepe/api/Asset.h @@ -1,7 +1,6 @@ #pragma once #include -#include namespace crepe { @@ -52,7 +51,16 @@ private: namespace std { +//! Hash helper struct template<> struct hash { + /** + * \brief Hash operator for crepe::Asset + * + * This function hashes a crepe::Asset instance, allowing it to be used as a key in an \c + * std::unordered_map. + * + * \returns Hash value + */ size_t operator()(const crepe::Asset & asset) const noexcept; }; diff --git a/src/crepe/util/OptionalRef.h b/src/crepe/util/OptionalRef.h index 1ad3a6d..8417a25 100644 --- a/src/crepe/util/OptionalRef.h +++ b/src/crepe/util/OptionalRef.h @@ -12,18 +12,51 @@ namespace crepe { template class OptionalRef { public: + //! Initialize empty (nonexistant) reference OptionalRef() = default; - OptionalRef(T &); - OptionalRef & operator=(T &); + //! Initialize reference with value + OptionalRef(T & ref); + /** + * \brief Assign new reference + * + * \param ref Reference to assign + * + * \return Reference to this (required for operator) + */ + OptionalRef & operator=(T & ref); + /** + * \brief Check if this reference is not empty + * + * \returns `true` if reference is set, or `false` if it is not + */ explicit operator bool() const noexcept; + /** + * \brief Assign new reference + * + * \param ref Reference to assign + */ void set(T &) noexcept; + /** + * \brief Retrieve this reference + * + * \returns Internal reference if it is set + * + * \throws std::runtime_error if this function is called while the reference it not set + */ T & get() const; + /** + * \brief Make this reference empty + */ void clear() noexcept; + //! Copy constructor OptionalRef(const OptionalRef &); + //! Move constructor OptionalRef(OptionalRef &&); + //! Copy assignment OptionalRef & operator=(const OptionalRef &); + //! Move assignment OptionalRef & operator=(OptionalRef &&); private: -- cgit v1.2.3 From 193e837fce92dcc169f995f670c9261f853ea1c3 Mon Sep 17 00:00:00 2001 From: heavydemon21 Date: Mon, 18 Nov 2024 20:25:31 +0100 Subject: adjusted so that all gets are auto --- src/crepe/system/RenderSystem.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src') diff --git a/src/crepe/system/RenderSystem.cpp b/src/crepe/system/RenderSystem.cpp index 37320ed..39e0e3f 100644 --- a/src/crepe/system/RenderSystem.cpp +++ b/src/crepe/system/RenderSystem.cpp @@ -1,5 +1,4 @@ #include -#include #include #include "../ComponentManager.h" @@ -19,7 +18,7 @@ void RenderSystem::present_screen() const { SDLContext::get_instance().present_s void RenderSystem::update_camera() { ComponentManager & mgr = this->component_manager; - std::vector> cameras = mgr.get_components_by_type(); + auto cameras = mgr.get_components_by_type(); for (Camera & cam : cameras) { SDLContext::get_instance().camera(cam); -- cgit v1.2.3 From 66bbea079bf1ae84c355349d337db468c18eac32 Mon Sep 17 00:00:00 2001 From: heavydemon21 Date: Mon, 18 Nov 2024 21:07:26 +0100 Subject: feedback from PR#38 implemented --- src/crepe/facade/SDLContext.h | 5 ----- src/crepe/system/RenderSystem.cpp | 5 ++--- src/crepe/system/RenderSystem.h | 10 ++++++---- 3 files changed, 8 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/crepe/facade/SDLContext.h b/src/crepe/facade/SDLContext.h index 007092b..d437bc4 100644 --- a/src/crepe/facade/SDLContext.h +++ b/src/crepe/facade/SDLContext.h @@ -21,8 +21,6 @@ namespace crepe { // typedef is unusable when crepe is packaged. Wouter will fix this later. typedef SDL_Keycode CREPE_KEYCODES; -class Texture; -class LoopManager; /** * \class SDLContext @@ -91,9 +89,6 @@ private: //! Will use the funtions: texture_from_path, get_width,get_height. friend class Texture; - //! Will use the funtions: texture_from_path, get_width,get_height. - friend class Animator; - /** * \brief Loads a texture from a file path. * \param path Path to the image file. diff --git a/src/crepe/system/RenderSystem.cpp b/src/crepe/system/RenderSystem.cpp index bf5dade..11c20f5 100644 --- a/src/crepe/system/RenderSystem.cpp +++ b/src/crepe/system/RenderSystem.cpp @@ -22,7 +22,7 @@ void RenderSystem::update_camera() { for (Camera & cam : cameras) { SDLContext::get_instance().camera(cam); - this->curr_cam = &cam; + this->curr_cam_ref = &cam; } } @@ -35,7 +35,6 @@ bool sorting_comparison(const Sprite & a, const Sprite & b) { std::vector> RenderSystem::sort(std::vector> & objs) { - if (objs.empty()) return {}; std::vector> sorted_objs(objs); std::sort(sorted_objs.begin(), sorted_objs.end(), sorting_comparison); @@ -52,7 +51,7 @@ void RenderSystem::render_sprites() { SDLContext & render = SDLContext::get_instance(); for (const Sprite & sprite : sorted_sprites) { auto transforms = mgr.get_components_by_id(sprite.game_object_id); - render.draw(sprite, transforms[0], *curr_cam); + render.draw(sprite, transforms[0], *this->curr_cam_ref); } } diff --git a/src/crepe/system/RenderSystem.h b/src/crepe/system/RenderSystem.h index 7661cbd..1176b06 100644 --- a/src/crepe/system/RenderSystem.h +++ b/src/crepe/system/RenderSystem.h @@ -1,12 +1,14 @@ #pragma once -#include "api/Camera.h" -#include "System.h" -#include "api/Sprite.h" #include #include +#include "api/Sprite.h" +#include "api/Camera.h" + +#include "System.h" + namespace crepe { /** @@ -54,7 +56,7 @@ private: private: //! Pointer to the current active camera for rendering - Camera * curr_cam = nullptr; + Camera * curr_cam_ref = nullptr; // TODO: needs a better solution }; -- cgit v1.2.3 From 9fb2e3a1d697f4961379980651e5434395e372bd Mon Sep 17 00:00:00 2001 From: heavydemon21 Date: Tue, 19 Nov 2024 11:48:07 +0100 Subject: unit tests --- src/crepe/api/Color.h | 4 +- src/crepe/system/RenderSystem.cpp | 7 +- src/test/CMakeLists.txt | 1 + src/test/rendering.cpp | 174 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 182 insertions(+), 4 deletions(-) create mode 100644 src/test/rendering.cpp (limited to 'src') diff --git a/src/crepe/api/Color.h b/src/crepe/api/Color.h index aa47bf4..c207ba7 100644 --- a/src/crepe/api/Color.h +++ b/src/crepe/api/Color.h @@ -21,13 +21,13 @@ public: static const Color & get_yellow(); static const Color & get_black(); -private: - // TODO: why are these private!? +public: uint8_t r; uint8_t g; uint8_t b; uint8_t a; +private: static Color white; static Color red; static Color green; diff --git a/src/crepe/system/RenderSystem.cpp b/src/crepe/system/RenderSystem.cpp index 11c20f5..82257c4 100644 --- a/src/crepe/system/RenderSystem.cpp +++ b/src/crepe/system/RenderSystem.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include "../ComponentManager.h" @@ -20,6 +21,8 @@ void RenderSystem::update_camera() { std::vector> cameras = mgr.get_components_by_type(); + if (cameras.size() == 0) throw std::runtime_error("No cameras in current scene"); + for (Camera & cam : cameras) { SDLContext::get_instance().camera(cam); this->curr_cam_ref = &cam; @@ -27,8 +30,8 @@ void RenderSystem::update_camera() { } bool sorting_comparison(const Sprite & a, const Sprite & b) { - if (a.sorting_in_layer > b.sorting_in_layer) return true; - if (a.sorting_in_layer == b.sorting_in_layer) return a.order_in_layer > b.order_in_layer; + if (a.sorting_in_layer < b.sorting_in_layer) return true; + if (a.sorting_in_layer == b.sorting_in_layer) return a.order_in_layer < b.order_in_layer; return false; } diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt index 49c8151..0969a52 100644 --- a/src/test/CMakeLists.txt +++ b/src/test/CMakeLists.txt @@ -3,5 +3,6 @@ target_sources(test_main PUBLIC PhysicsTest.cpp ScriptTest.cpp ParticleTest.cpp + rendering.cpp ) diff --git a/src/test/rendering.cpp b/src/test/rendering.cpp new file mode 100644 index 0000000..4c5fb1d --- /dev/null +++ b/src/test/rendering.cpp @@ -0,0 +1,174 @@ +#include "api/Camera.h" +#include +#include +#include +#include + +#define private public +#define protected public + +#include +#include +#include +#include +#include + +#include + +using namespace std; +using namespace crepe; +using namespace testing; + +class RenderSystemTest : public Test { +public: + ComponentManager mgr{}; + RenderSystem sys{mgr}; + GameObject entity1 = this->mgr.new_object("name"); + GameObject entity2 = this->mgr.new_object("name"); + GameObject entity3 = this->mgr.new_object("name"); + GameObject entity4 = this->mgr.new_object("name"); + + void SetUp() override { + auto & sprite1 + = entity1.add_component(make_shared("../asset/texture/img.png"), + Color(0, 0, 0, 0), FlipSettings{false, false}); + ASSERT_NE(sprite1.sprite_image.get(), nullptr); + sprite1.order_in_layer = 5; + sprite1.sorting_in_layer = 5; + EXPECT_EQ(sprite1.order_in_layer, 5); + EXPECT_EQ(sprite1.sorting_in_layer, 5); + auto & sprite2 + = entity2.add_component(make_shared("../asset/texture/img.png"), + Color(0, 0, 0, 0), FlipSettings{false, false}); + ASSERT_NE(sprite2.sprite_image.get(), nullptr); + sprite2.sorting_in_layer = 2; + sprite2.order_in_layer = 1; + + EXPECT_EQ(sprite2.sorting_in_layer, 2); + EXPECT_EQ(sprite2.order_in_layer, 1); + + auto & sprite3 + = entity3.add_component(make_shared("../asset/texture/img.png"), + Color(0, 0, 0, 0), FlipSettings{false, false}); + ASSERT_NE(sprite3.sprite_image.get(), nullptr); + sprite3.sorting_in_layer = 1; + sprite3.order_in_layer = 2; + + EXPECT_EQ(sprite3.sorting_in_layer, 1); + EXPECT_EQ(sprite3.order_in_layer, 2); + + auto & sprite4 + = entity4.add_component(make_shared("../asset/texture/img.png"), + Color(0, 0, 0, 0), FlipSettings{false, false}); + ASSERT_NE(sprite4.sprite_image.get(), nullptr); + sprite4.sorting_in_layer = 1; + sprite4.order_in_layer = 1; + EXPECT_EQ(sprite4.sorting_in_layer, 1); + EXPECT_EQ(sprite4.order_in_layer, 1); + } +}; + +TEST_F(RenderSystemTest, expected_throws) { + GameObject entity1 = this->mgr.new_object("NAME"); + + // no texture img + EXPECT_ANY_THROW({ + entity1.add_component(make_shared("NO_IMAGE"), Color(0, 0, 0, 0), + FlipSettings{false, false}); + }); + + // No camera + EXPECT_ANY_THROW({ this->sys.update(); }); +} + +TEST_F(RenderSystemTest, make_sprites) {} + +TEST_F(RenderSystemTest, sorting_sprites) { + vector> sprites = this->mgr.get_components_by_type(); + ASSERT_EQ(sprites.size(), 4); + + vector> sorted_sprites = this->sys.sort(sprites); + ASSERT_EQ(sorted_sprites.size(), 4); + + // Expected order after sorting: + // 1. sorting_in_layer: 1, order_in_layer: 1 (entity4) + // 2. sorting_in_layer: 1, order_in_layer: 2 (entity3) + // 3. sorting_in_layer: 2, order_in_layer: 1 (entity2) + // 4. sorting_in_layer: 5, order_in_layer: 5 (entity1) + + EXPECT_EQ(sorted_sprites[0].get().sorting_in_layer, 1); + EXPECT_EQ(sorted_sprites[0].get().order_in_layer, 1); + + EXPECT_EQ(sorted_sprites[1].get().sorting_in_layer, 1); + EXPECT_EQ(sorted_sprites[1].get().order_in_layer, 2); + + EXPECT_EQ(sorted_sprites[2].get().sorting_in_layer, 2); + EXPECT_EQ(sorted_sprites[2].get().order_in_layer, 1); + + EXPECT_EQ(sorted_sprites[3].get().sorting_in_layer, 5); + EXPECT_EQ(sorted_sprites[3].get().order_in_layer, 5); + + for (size_t i = 1; i < sorted_sprites.size(); ++i) { + const Sprite & prev = sorted_sprites[i - 1].get(); + const Sprite & curr = sorted_sprites[i].get(); + + if (prev.sorting_in_layer == curr.sorting_in_layer) { + EXPECT_LE(prev.order_in_layer, curr.order_in_layer); + } else { + EXPECT_LE(prev.sorting_in_layer, curr.sorting_in_layer); + } + } +} + +TEST_F(RenderSystemTest, Update) { + entity1.add_component(Color::get_white()); + { + vector> sprites = this->mgr.get_components_by_type(); + ASSERT_EQ(sprites.size(), 4); + + EXPECT_EQ(sprites[0].get().game_object_id, 0); + EXPECT_EQ(sprites[1].get().game_object_id, 1); + EXPECT_EQ(sprites[2].get().game_object_id, 2); + EXPECT_EQ(sprites[3].get().game_object_id, 3); + } + this->sys.update(); + { + vector> sprites = this->mgr.get_components_by_type(); + ASSERT_EQ(sprites.size(), 4); + + EXPECT_EQ(sprites[0].get().game_object_id, 0); + EXPECT_EQ(sprites[1].get().game_object_id, 1); + EXPECT_EQ(sprites[2].get().game_object_id, 2); + EXPECT_EQ(sprites[3].get().game_object_id, 3); + } +} + +TEST_F(RenderSystemTest, Camera) { + { + auto cameras = this->mgr.get_components_by_type(); + EXPECT_NE(cameras.size(), 1); + } + { + entity1.add_component(Color::get_white()); + auto cameras = this->mgr.get_components_by_type(); + EXPECT_EQ(cameras.size(), 1); + } + + //TODO improve with newer version +} +TEST_F(RenderSystemTest, Color) { + entity1.add_component(Color::get_white()); + auto & sprite = this->mgr.get_components_by_id(entity1.id).front().get(); + ASSERT_NE(sprite.sprite_image.get(), nullptr); + + sprite.color = Color::get_green(); + EXPECT_EQ(sprite.color.r, Color::get_green().r); + EXPECT_EQ(sprite.color.g, Color::get_green().g); + EXPECT_EQ(sprite.color.b, Color::get_green().b); + EXPECT_EQ(sprite.color.a, Color::get_green().a); + this->sys.update(); + EXPECT_EQ(sprite.color.r, Color::get_green().r); + EXPECT_EQ(sprite.color.g, Color::get_green().g); + EXPECT_EQ(sprite.color.b, Color::get_green().b); + EXPECT_EQ(sprite.color.a, Color::get_green().a); +} -- cgit v1.2.3 From 0476a8e9dbe7afb422862f7b1c15aaed7f3c416e Mon Sep 17 00:00:00 2001 From: Loek Le Blansch Date: Tue, 19 Nov 2024 12:11:11 +0100 Subject: add some more doxygen --- .editorconfig | 2 +- Doxyfile | 9 +- src/doc/feature/script.dox | 62 +++++++++++ src/doc/features.dox | 10 ++ src/doc/index.dox | 10 ++ src/doc/installing.dox | 9 ++ src/doc/layout.xml | 252 +++++++++++++++++++++++++++++++++++++++++++++ src/doc/style.css | 4 + 8 files changed, 356 insertions(+), 2 deletions(-) create mode 100644 src/doc/feature/script.dox create mode 100644 src/doc/features.dox create mode 100644 src/doc/index.dox create mode 100644 src/doc/installing.dox create mode 100644 src/doc/layout.xml create mode 100644 src/doc/style.css (limited to 'src') diff --git a/.editorconfig b/.editorconfig index 191871f..65f5034 100644 --- a/.editorconfig +++ b/.editorconfig @@ -10,5 +10,5 @@ max_line_length = 95 indent_style = space indent_size = 2 -[*.md] +[*.{md,dox}] max_line_length = 80 diff --git a/Doxyfile b/Doxyfile index 8ba90fc..9328b24 100644 --- a/Doxyfile +++ b/Doxyfile @@ -14,12 +14,19 @@ RECURSIVE = YES GENERATE_LATEX = NO +LAYOUT_FILE = src/doc/layout.xml +TAB_SIZE = 2 + +HTML_INDEX_NUM_ENTRIES = 2 +HTML_EXTRA_STYLESHEET = src/doc/style.css + USE_MDFILE_AS_MAINPAGE = ./readme.md -HTML_INDEX_NUM_ENTRIES = 1 # collapse trees by default REPEAT_BRIEF = NO INTERNAL_DOCS = YES EXTRACT_STATIC = YES +HIDE_UNDOC_NAMESPACES = YES +HIDE_UNDOC_CLASSES = YES QUIET = YES diff --git a/src/doc/feature/script.dox b/src/doc/feature/script.dox new file mode 100644 index 0000000..d25a63b --- /dev/null +++ b/src/doc/feature/script.dox @@ -0,0 +1,62 @@ +// vim:ft=doxygen +namespace crepe { +/** + +\defgroup feature_script Scripting +\ingroup feature +\brief User-defined scripts for game objects + +Scripts can be used to implement game behavior, and allow arbitrary code to run +as part of the game loop. Scripts are implemented as derivative classes of +Script, which are added to game objects using the BehaviorScript \ref Component +"component". + +\todo This section is incomplete: +- Utility functions to get components/events/etc inside script +- How to listen for events +- Extensions of script (keylistener) + +\see Script +\see BehaviorScript +\see GameObject + +\par Example + +First, define a class that inherits from Script. This class acts as an +interface, and has two functions (\ref Script::init "\c init()" and \ref +Script::update "\c update()"), which may be implemented (they are empty by +default). From now on, this derivative class will be referred to as a *concrete +script*. + +```cpp +#include +#include + +class MyScript : public crepe::Script { + void init() { + // called once + } + void update() { + // called on fixed update + } +}; +``` + +Concrete scripts can be instantiated and attached to \ref GameObject +"game objects" using the BehaviorScript \ref Component "component". + +```cpp +using namespace crepe; +GameObject obj = component_manager.new_object("name"); + +// create BehaviorScript instance +BehaviorScript & behavior_script = obj.add_component(); +// attach (and instantiate) MyScript to behavior_script +behavior_script.set_script(); + +// the above can also be done in a single call for convenience: +obj.add_component().set_script(); +``` + +*/ +} diff --git a/src/doc/features.dox b/src/doc/features.dox new file mode 100644 index 0000000..4786bed --- /dev/null +++ b/src/doc/features.dox @@ -0,0 +1,10 @@ +// vim:ft=doxygen +/** + +\defgroup feature Features +\brief Engine components + +This page lists engine features and contains usage instructions for each +feature. + +*/ diff --git a/src/doc/index.dox b/src/doc/index.dox new file mode 100644 index 0000000..5ec7889 --- /dev/null +++ b/src/doc/index.dox @@ -0,0 +1,10 @@ +// vim:ft=doxygen +/** + +\mainpage crêpe game engine + +Welcome to the documentation for the crêpe game engine. + +\see feature + +*/ diff --git a/src/doc/installing.dox b/src/doc/installing.dox new file mode 100644 index 0000000..48b27d7 --- /dev/null +++ b/src/doc/installing.dox @@ -0,0 +1,9 @@ +// vim:ft=doxygen +/** + +\defgroup install Installation +\brief Engine installation instructions + +\todo This entire page + +*/ diff --git a/src/doc/layout.xml b/src/doc/layout.xml new file mode 100644 index 0000000..2244fa7 --- /dev/null +++ b/src/doc/layout.xml @@ -0,0 +1,252 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/doc/style.css b/src/doc/style.css new file mode 100644 index 0000000..08bc9f5 --- /dev/null +++ b/src/doc/style.css @@ -0,0 +1,4 @@ +#titlearea, +address { + display: none; +} -- cgit v1.2.3 From 4d1c6f1831e0a95029ff7af4cf8097e837dc2a5d Mon Sep 17 00:00:00 2001 From: Loek Le Blansch Date: Tue, 19 Nov 2024 15:05:30 +0100 Subject: add RefVector --- src/crepe/types.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src') diff --git a/src/crepe/types.h b/src/crepe/types.h index 0d459e8..86730cc 100644 --- a/src/crepe/types.h +++ b/src/crepe/types.h @@ -1,9 +1,16 @@ #pragma once #include +#include +#include namespace crepe { +//! GameObject ID typedef uint32_t game_object_id_t; +//! vector of reference_wrapper +template +using RefVector = std::vector>; + } -- cgit v1.2.3 From 881e8f286a553f393af7c698652521b5c125b1f7 Mon Sep 17 00:00:00 2001 From: WBoerenkamps Date: Tue, 19 Nov 2024 15:17:20 +0100 Subject: added operator --- src/crepe/api/IMouseListener.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/crepe/api/IMouseListener.h b/src/crepe/api/IMouseListener.h index c315c35..921a760 100644 --- a/src/crepe/api/IMouseListener.h +++ b/src/crepe/api/IMouseListener.h @@ -19,8 +19,9 @@ public: */ IMouseListener(int channel); virtual ~IMouseListener(); - IMouseListener(const IMouseListener &) = delete; IMouseListener & operator=(const IMouseListener &) = delete; + IMouseListener(const IMouseListener &) = delete; + IMouseListener && operator=(const IMouseListener &&) = delete; IMouseListener(IMouseListener &&) = delete; /** -- cgit v1.2.3 From 85a15e4f43941b5d47fc4be2fee754f0a3d88d15 Mon Sep 17 00:00:00 2001 From: max-001 Date: Wed, 20 Nov 2024 10:41:01 +0100 Subject: Added ECS tests --- src/example/CMakeLists.txt | 2 - src/example/components_internal.cpp | 51 -------- src/example/ecs.cpp | 53 -------- src/test/CMakeLists.txt | 1 + src/test/ECSTest.cpp | 236 ++++++++++++++++++++++++++++++++++++ 5 files changed, 237 insertions(+), 106 deletions(-) delete mode 100644 src/example/components_internal.cpp delete mode 100644 src/example/ecs.cpp create mode 100644 src/test/ECSTest.cpp (limited to 'src') diff --git a/src/example/CMakeLists.txt b/src/example/CMakeLists.txt index 3a5b543..bbeec09 100644 --- a/src/example/CMakeLists.txt +++ b/src/example/CMakeLists.txt @@ -17,7 +17,6 @@ function(add_example target_name) endfunction() add_example(audio_internal) -# add_example(components_internal) add_example(script) add_example(log) add_example(rendering) @@ -26,7 +25,6 @@ add_example(physics) add_example(savemgr) add_example(proxy) add_example(db) -add_example(ecs) add_example(scene_manager) add_example(particles) add_example(gameloop) diff --git a/src/example/components_internal.cpp b/src/example/components_internal.cpp deleted file mode 100644 index 2a232a9..0000000 --- a/src/example/components_internal.cpp +++ /dev/null @@ -1,51 +0,0 @@ -/** \file - * - * Standalone example for usage of the internal ECS - */ - -#include -#include - -#include -#include - -#include -#include -#include - -#include - -using namespace crepe; -using namespace std; - -#define OBJ_COUNT 100000 - -int main() { - dbg_trace(); - - ComponentManager mgr{}; - - auto start_adding = chrono::high_resolution_clock::now(); - - for (int i = 0; i < OBJ_COUNT; ++i) { - GameObject obj = mgr.new_object("Name", "Tag"); - obj.add_component("test"); - obj.add_component(0, 0, i); - } - - auto stop_adding = chrono::high_resolution_clock::now(); - - auto sprites = mgr.get_components_by_type(); - for (auto sprite : sprites) { - assert(true); - } - - auto stop_looping = chrono::high_resolution_clock::now(); - - auto add_time = chrono::duration_cast(stop_adding - start_adding); - auto loop_time = chrono::duration_cast(stop_looping - stop_adding); - printf("add time: %ldus\n", add_time.count()); - printf("loop time: %ldus\n", loop_time.count()); - - return 0; -} diff --git a/src/example/ecs.cpp b/src/example/ecs.cpp deleted file mode 100644 index d5ba51b..0000000 --- a/src/example/ecs.cpp +++ /dev/null @@ -1,53 +0,0 @@ -#include - -#include -#include -#include -#include - -using namespace crepe; -using namespace std; - -int main() { - ComponentManager mgr{}; - - // Create a few GameObjects - try { - GameObject body = mgr.new_object("body", "person", Vector2{0, 0}, 0, 1); - GameObject right_leg = mgr.new_object("rightLeg", "person", Vector2{1, 1}, 0, 1); - GameObject left_leg = mgr.new_object("leftLeg", "person", Vector2{1, 1}, 0, 1); - GameObject right_foot = mgr.new_object("rightFoot", "person", Vector2{2, 2}, 0, 1); - GameObject left_foot = mgr.new_object("leftFoot", "person", Vector2{2, 2}, 0, 1); - - // Set the parent of each GameObject - right_foot.set_parent(right_leg); - left_foot.set_parent(left_leg); - right_leg.set_parent(body); - left_leg.set_parent(body); - - // Adding a second Transform component is not allowed and will invoke an exception - body.add_component(Vector2{10, 10}, 0, 1); - } catch (const exception & e) { - cerr << e.what() << endl; - } - - // Get the Metadata and Transform components of each GameObject - vector> metadata = mgr.get_components_by_type(); - vector> transform = mgr.get_components_by_type(); - - // Print the Metadata and Transform components - for (auto & m : metadata) { - cout << "Id: " << m.get().game_object_id << " Name: " << m.get().name - << " Tag: " << m.get().tag << " Parent: " << m.get().parent << " Children: "; - for (auto & c : m.get().children) { - cout << c << " "; - } - cout << endl; - } - for (auto & t : transform) { - cout << "Id: " << t.get().game_object_id << " Position: [" << t.get().position.x - << ", " << t.get().position.y << "]" << endl; - } - - return 0; -} diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt index 49c8151..0849b98 100644 --- a/src/test/CMakeLists.txt +++ b/src/test/CMakeLists.txt @@ -3,5 +3,6 @@ target_sources(test_main PUBLIC PhysicsTest.cpp ScriptTest.cpp ParticleTest.cpp + ECSTest.cpp ) diff --git a/src/test/ECSTest.cpp b/src/test/ECSTest.cpp new file mode 100644 index 0000000..a245879 --- /dev/null +++ b/src/test/ECSTest.cpp @@ -0,0 +1,236 @@ +#include +#include +#define protected public + +#include +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace crepe; + +class ECSTest : public ::testing::Test { +public: + ComponentManager mgr{}; +}; + +TEST_F(ECSTest, createGameObject) { + GameObject obj = mgr.new_object("body", "person", Vector2{0, 0}, 0, 1); + + vector> metadata = mgr.get_components_by_type(); + vector> transform = mgr.get_components_by_type(); + + EXPECT_EQ(metadata.size(), 1); + EXPECT_EQ(transform.size(), 1); + + EXPECT_EQ(metadata[0].get().name, "body"); + EXPECT_EQ(metadata[0].get().tag, "person"); + EXPECT_EQ(metadata[0].get().parent, -1); + EXPECT_EQ(metadata[0].get().children.size(), 0); + + EXPECT_EQ(transform[0].get().position.x, 0); + EXPECT_EQ(transform[0].get().position.y, 0); + EXPECT_EQ(transform[0].get().rotation, 0); + EXPECT_EQ(transform[0].get().scale, 1); +} + +TEST_F(ECSTest, deleteAllGameObjects) { + GameObject obj0 = mgr.new_object("body", "person", Vector2{0, 0}, 0, 1); + GameObject obj1 = mgr.new_object("body", "person", Vector2{0, 0}, 0, 1); + + mgr.delete_all_components(); + + vector> metadata = mgr.get_components_by_type(); + vector> transform = mgr.get_components_by_type(); + + EXPECT_EQ(metadata.size(), 0); + EXPECT_EQ(transform.size(), 0); + + GameObject obj2 = mgr.new_object("body2", "person2", Vector2{1, 0}, 5, 1); + + metadata = mgr.get_components_by_type(); + transform = mgr.get_components_by_type(); + + EXPECT_EQ(metadata.size(), 1); + EXPECT_EQ(transform.size(), 1); + + EXPECT_EQ(metadata[0].get().game_object_id, 0); + EXPECT_EQ(metadata[0].get().name, "body2"); + EXPECT_EQ(metadata[0].get().tag, "person2"); + EXPECT_EQ(metadata[0].get().parent, -1); + EXPECT_EQ(metadata[0].get().children.size(), 0); + + EXPECT_EQ(transform[0].get().game_object_id, 0); + EXPECT_EQ(transform[0].get().position.x, 1); + EXPECT_EQ(transform[0].get().position.y, 0); + EXPECT_EQ(transform[0].get().rotation, 5); + EXPECT_EQ(transform[0].get().scale, 1); +} + +TEST_F(ECSTest, deleteGameObject) { + GameObject obj0 = mgr.new_object("body", "person", Vector2{0, 0}, 0, 1); + GameObject obj1 = mgr.new_object("body", "person", Vector2{0, 0}, 0, 1); + + mgr.delete_all_components_of_id(0); + + vector> metadata = mgr.get_components_by_type(); + vector> transform = mgr.get_components_by_type(); + + EXPECT_EQ(metadata.size(), 1); + EXPECT_EQ(transform.size(), 1); + + EXPECT_EQ(metadata[0].get().game_object_id, 1); + EXPECT_EQ(metadata[0].get().name, "body"); + EXPECT_EQ(metadata[0].get().tag, "person"); + EXPECT_EQ(metadata[0].get().parent, -1); + EXPECT_EQ(metadata[0].get().children.size(), 0); + + EXPECT_EQ(transform[0].get().game_object_id, 1); + EXPECT_EQ(transform[0].get().position.x, 0); + EXPECT_EQ(transform[0].get().position.y, 0); + EXPECT_EQ(transform[0].get().rotation, 0); + EXPECT_EQ(transform[0].get().scale, 1); +} + +TEST_F(ECSTest, manyGameObjects) { + for(int i = 0; i < 5000; i++) { + GameObject obj = mgr.new_object("body", "person", Vector2{0, 0}, 0, i); + } + + vector> metadata = mgr.get_components_by_type(); + vector> transform = mgr.get_components_by_type(); + + EXPECT_EQ(metadata.size(), 5000); + EXPECT_EQ(transform.size(), 5000); + for(int i = 0; i < 5000; i++) { + EXPECT_EQ(metadata[i].get().game_object_id, i); + EXPECT_EQ(metadata[i].get().name, "body"); + EXPECT_EQ(metadata[i].get().tag, "person"); + EXPECT_EQ(metadata[i].get().parent, -1); + EXPECT_EQ(metadata[i].get().children.size(), 0); + + EXPECT_EQ(transform[i].get().game_object_id, i); + EXPECT_EQ(transform[i].get().position.x, 0); + EXPECT_EQ(transform[i].get().position.y, 0); + EXPECT_EQ(transform[i].get().rotation, 0); + EXPECT_EQ(transform[i].get().scale, i); + } + + mgr.delete_components(); + + metadata = mgr.get_components_by_type(); + transform = mgr.get_components_by_type(); + + EXPECT_EQ(metadata.size(), 0); + EXPECT_EQ(transform.size(), 5000); + + for(int i = 0; i < 10000 - 5000; i++) { + string tag = "person" + to_string(i); + GameObject obj = mgr.new_object("body", tag, Vector2{0, 0}, i, 0); + } + + metadata = mgr.get_components_by_type(); + transform = mgr.get_components_by_type(); + + EXPECT_EQ(metadata.size(), 10000 - 5000); + EXPECT_EQ(transform.size(), 10000); +} + +TEST_F(ECSTest, getComponentsByID) { + GameObject obj0 = mgr.new_object("body", "person", Vector2{0, 0}, 0, 1); + GameObject obj1 = mgr.new_object("body", "person", Vector2{0, 0}, 0, 1); + + vector> metadata = mgr.get_components_by_id(0); + vector> transform = mgr.get_components_by_id(1); + + EXPECT_EQ(metadata.size(), 1); + EXPECT_EQ(transform.size(), 1); + + EXPECT_EQ(metadata[0].get().game_object_id, 0); + EXPECT_EQ(metadata[0].get().name, "body"); + EXPECT_EQ(metadata[0].get().tag, "person"); + EXPECT_EQ(metadata[0].get().parent, -1); + EXPECT_EQ(metadata[0].get().children.size(), 0); + + EXPECT_EQ(transform[0].get().game_object_id, 1); + EXPECT_EQ(transform[0].get().position.x, 0); + EXPECT_EQ(transform[0].get().position.y, 0); + EXPECT_EQ(transform[0].get().rotation, 0); + EXPECT_EQ(transform[0].get().scale, 1); +} + +TEST_F(ECSTest, tooMuchComponents) { + try { + GameObject obj0 = mgr.new_object("body", "person", Vector2{0, 0}, 0, 1); + obj0.add_component(Vector2{10, 10}, 0, 1); + } catch (const exception & e) { + EXPECT_EQ(e.what(), string("Exceeded maximum number of instances for this component type")); + } + + try { + GameObject obj1 = mgr.new_object("body", "person", Vector2{0, 0}, 0, 1); + obj1.add_component("body", "person"); + } catch (const exception & e) { + EXPECT_EQ(e.what(), string("Exceeded maximum number of instances for this component type")); + } + + vector> metadata = mgr.get_components_by_type(); + + EXPECT_EQ(metadata.size(), 2); + EXPECT_EQ(metadata[0].get().name, "body"); + EXPECT_EQ(metadata[1].get().name, "body"); +} + +TEST_F(ECSTest, partentChild) { + { + GameObject body = mgr.new_object("body", "person", Vector2{0, 0}, 0, 1); + GameObject right_leg = mgr.new_object("rightLeg", "person", Vector2{1, 1}, 0, 1); + GameObject left_leg = mgr.new_object("leftLeg", "person", Vector2{1, 1}, 0, 1); + GameObject right_foot = mgr.new_object("rightFoot", "person", Vector2{2, 2}, 0, 1); + GameObject left_foot = mgr.new_object("leftFoot", "person", Vector2{2, 2}, 0, 1); + + // Set the parent of each GameObject + right_foot.set_parent(right_leg); + left_foot.set_parent(left_leg); + right_leg.set_parent(body); + left_leg.set_parent(body); + } + + // Get the Metadata and Transform components of each GameObject + vector> metadata = mgr.get_components_by_type(); + + // Check IDs + EXPECT_EQ(metadata[0].get().game_object_id, 0); + EXPECT_EQ(metadata[1].get().game_object_id, 1); + EXPECT_EQ(metadata[2].get().game_object_id, 2); + EXPECT_EQ(metadata[3].get().game_object_id, 3); + EXPECT_EQ(metadata[4].get().game_object_id, 4); + + // Check the parent-child relationships + EXPECT_EQ(metadata[0].get().name, "body"); + EXPECT_EQ(metadata[1].get().name, "rightLeg"); + EXPECT_EQ(metadata[2].get().name, "leftLeg"); + EXPECT_EQ(metadata[3].get().name, "rightFoot"); + EXPECT_EQ(metadata[4].get().name, "leftFoot"); + + EXPECT_EQ(metadata[0].get().parent, -1); + EXPECT_EQ(metadata[1].get().parent, 0); + EXPECT_EQ(metadata[2].get().parent, 0); + EXPECT_EQ(metadata[3].get().parent, 1); + EXPECT_EQ(metadata[4].get().parent, 2); + + EXPECT_EQ(metadata[0].get().children.size(), 2); + EXPECT_EQ(metadata[1].get().children.size(), 1); + EXPECT_EQ(metadata[2].get().children.size(), 1); + EXPECT_EQ(metadata[3].get().children.size(), 0); + EXPECT_EQ(metadata[4].get().children.size(), 0); + + EXPECT_EQ(metadata[0].get().children[0], 1); + EXPECT_EQ(metadata[0].get().children[1], 2); + EXPECT_EQ(metadata[1].get().children[0], 3); + EXPECT_EQ(metadata[2].get().children[0], 4); +} -- cgit v1.2.3 From e714303c486fb81851116710ba5d68e1b469df02 Mon Sep 17 00:00:00 2001 From: max-001 Date: Wed, 20 Nov 2024 10:59:34 +0100 Subject: Added SceneManager tests --- src/example/CMakeLists.txt | 1 - src/example/scene_manager.cpp | 79 --------------------------- src/test/CMakeLists.txt | 1 + src/test/ECSTest.cpp | 3 -- src/test/SceneManagerTest.cpp | 120 ++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 121 insertions(+), 83 deletions(-) delete mode 100644 src/example/scene_manager.cpp create mode 100644 src/test/SceneManagerTest.cpp (limited to 'src') diff --git a/src/example/CMakeLists.txt b/src/example/CMakeLists.txt index bbeec09..30432e5 100644 --- a/src/example/CMakeLists.txt +++ b/src/example/CMakeLists.txt @@ -25,7 +25,6 @@ add_example(physics) add_example(savemgr) add_example(proxy) add_example(db) -add_example(scene_manager) add_example(particles) add_example(gameloop) diff --git a/src/example/scene_manager.cpp b/src/example/scene_manager.cpp deleted file mode 100644 index accec7d..0000000 --- a/src/example/scene_manager.cpp +++ /dev/null @@ -1,79 +0,0 @@ -#include - -#include -#include -#include -#include -#include -#include - -using namespace crepe; -using namespace std; - -class ConcreteScene1 : public Scene { -public: - using Scene::Scene; - - void load_scene() { - auto & mgr = this->component_manager; - GameObject object1 = mgr.new_object("scene_1", "tag_scene_1", Vector2{0, 0}, 0, 1); - GameObject object2 = mgr.new_object("scene_1", "tag_scene_1", Vector2{1, 0}, 0, 1); - GameObject object3 = mgr.new_object("scene_1", "tag_scene_1", Vector2{2, 0}, 0, 1); - } -}; - -class ConcreteScene2 : public Scene { -public: - using Scene::Scene; - - void load_scene() { - auto & mgr = this->component_manager; - GameObject object1 = mgr.new_object("scene_2", "tag_scene_2", Vector2{0, 0}, 0, 1); - GameObject object2 = mgr.new_object("scene_2", "tag_scene_2", Vector2{0, 1}, 0, 1); - GameObject object3 = mgr.new_object("scene_2", "tag_scene_2", Vector2{0, 2}, 0, 1); - GameObject object4 = mgr.new_object("scene_2", "tag_scene_2", Vector2{0, 3}, 0, 1); - } -}; - -int main() { - ComponentManager component_mgr{}; - SceneManager scene_mgr{component_mgr}; - - // Add the scenes to the scene manager - scene_mgr.add_scene("scene1"); - scene_mgr.add_scene("scene2"); - - // There is no need to call set_next_scene() at the beginnen, because the first scene will be - // automatically set as the next scene - - // Load scene1 (the first scene added) - scene_mgr.load_next_scene(); - - // Get the Metadata components of each GameObject of Scene1 - vector> metadata - = component_mgr.get_components_by_type(); - - cout << "Metadata components of Scene1:" << endl; - // Print the Metadata - for (auto & m : metadata) { - cout << "Id: " << m.get().game_object_id << " Name: " << m.get().name - << " Tag: " << m.get().tag << endl; - } - - // Set scene2 as the next scene - scene_mgr.set_next_scene("scene2"); - // Load scene2 - scene_mgr.load_next_scene(); - - // Get the Metadata components of each GameObject of Scene2 - metadata = component_mgr.get_components_by_type(); - - cout << "Metadata components of Scene2:" << endl; - // Print the Metadata - for (auto & m : metadata) { - cout << "Id: " << m.get().game_object_id << " Name: " << m.get().name - << " Tag: " << m.get().tag << endl; - } - - return 0; -} diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt index 0849b98..d56d80f 100644 --- a/src/test/CMakeLists.txt +++ b/src/test/CMakeLists.txt @@ -4,5 +4,6 @@ target_sources(test_main PUBLIC ScriptTest.cpp ParticleTest.cpp ECSTest.cpp + SceneManagerTest.cpp ) diff --git a/src/test/ECSTest.cpp b/src/test/ECSTest.cpp index a245879..eaa2dbc 100644 --- a/src/test/ECSTest.cpp +++ b/src/test/ECSTest.cpp @@ -1,5 +1,3 @@ -#include -#include #define protected public #include @@ -7,7 +5,6 @@ #include #include #include -#include #include using namespace std; diff --git a/src/test/SceneManagerTest.cpp b/src/test/SceneManagerTest.cpp new file mode 100644 index 0000000..98b2a23 --- /dev/null +++ b/src/test/SceneManagerTest.cpp @@ -0,0 +1,120 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace crepe; + +class ConcreteScene1 : public Scene { +public: + using Scene::Scene; + + void load_scene() { + auto & mgr = this->component_manager; + GameObject object1 = mgr.new_object("scene_1", "tag_scene_1", Vector2{0, 0}, 0, 1); + GameObject object2 = mgr.new_object("scene_1", "tag_scene_1", Vector2{1, 0}, 0, 1); + GameObject object3 = mgr.new_object("scene_1", "tag_scene_1", Vector2{2, 0}, 0, 1); + } +}; + +class ConcreteScene2 : public Scene { +public: + using Scene::Scene; + + void load_scene() { + auto & mgr = this->component_manager; + GameObject object1 = mgr.new_object("scene_2", "tag_scene_2", Vector2{0, 0}, 0, 1); + GameObject object2 = mgr.new_object("scene_2", "tag_scene_2", Vector2{0, 1}, 0, 1); + GameObject object3 = mgr.new_object("scene_2", "tag_scene_2", Vector2{0, 2}, 0, 1); + GameObject object4 = mgr.new_object("scene_2", "tag_scene_2", Vector2{0, 3}, 0, 1); + } +}; + +class SceneManagerTest : public ::testing::Test { +public: + ComponentManager component_mgr{}; + SceneManager scene_mgr{component_mgr}; +}; + +TEST_F(SceneManagerTest, loadScene) { + scene_mgr.add_scene("scene1"); + scene_mgr.add_scene("scene2"); + + scene_mgr.load_next_scene(); + + vector> metadata = component_mgr.get_components_by_type(); + vector> transform = component_mgr.get_components_by_type(); + + EXPECT_EQ(metadata.size(), 3); + EXPECT_EQ(transform.size(), 3); + + EXPECT_EQ(metadata[0].get().game_object_id, 0); + EXPECT_EQ(metadata[0].get().name, "scene_1"); + EXPECT_EQ(metadata[0].get().tag, "tag_scene_1"); + EXPECT_EQ(metadata[0].get().parent, -1); + EXPECT_EQ(metadata[0].get().children.size(), 0); + EXPECT_EQ(transform[0].get().position.x, 0); + EXPECT_EQ(transform[0].get().position.y, 0); + + EXPECT_EQ(metadata[1].get().game_object_id, 1); + EXPECT_EQ(metadata[1].get().name, "scene_1"); + EXPECT_EQ(metadata[1].get().tag, "tag_scene_1"); + EXPECT_EQ(metadata[1].get().parent, -1); + EXPECT_EQ(metadata[1].get().children.size(), 0); + EXPECT_EQ(transform[1].get().position.x, 1); + EXPECT_EQ(transform[1].get().position.y, 0); + + EXPECT_EQ(metadata[2].get().game_object_id, 2); + EXPECT_EQ(metadata[2].get().name, "scene_1"); + EXPECT_EQ(metadata[2].get().tag, "tag_scene_1"); + EXPECT_EQ(metadata[2].get().parent, -1); + EXPECT_EQ(metadata[2].get().children.size(), 0); + EXPECT_EQ(transform[2].get().position.x, 2); + EXPECT_EQ(transform[2].get().position.y, 0); + + scene_mgr.set_next_scene("scene2"); + scene_mgr.load_next_scene(); + + metadata = component_mgr.get_components_by_type(); + transform = component_mgr.get_components_by_type(); + + EXPECT_EQ(metadata.size(), 4); + EXPECT_EQ(transform.size(), 4); + + EXPECT_EQ(metadata[0].get().game_object_id, 0); + EXPECT_EQ(metadata[0].get().name, "scene_2"); + EXPECT_EQ(metadata[0].get().tag, "tag_scene_2"); + EXPECT_EQ(metadata[0].get().parent, -1); + EXPECT_EQ(metadata[0].get().children.size(), 0); + EXPECT_EQ(transform[0].get().position.x, 0); + EXPECT_EQ(transform[0].get().position.y, 0); + + EXPECT_EQ(metadata[1].get().game_object_id, 1); + EXPECT_EQ(metadata[1].get().name, "scene_2"); + EXPECT_EQ(metadata[1].get().tag, "tag_scene_2"); + EXPECT_EQ(metadata[1].get().parent, -1); + EXPECT_EQ(metadata[1].get().children.size(), 0); + EXPECT_EQ(transform[1].get().position.x, 0); + EXPECT_EQ(transform[1].get().position.y, 1); + + EXPECT_EQ(metadata[2].get().game_object_id, 2); + EXPECT_EQ(metadata[2].get().name, "scene_2"); + EXPECT_EQ(metadata[2].get().tag, "tag_scene_2"); + EXPECT_EQ(metadata[2].get().parent, -1); + EXPECT_EQ(metadata[2].get().children.size(), 0); + EXPECT_EQ(transform[2].get().position.x, 0); + EXPECT_EQ(transform[2].get().position.y, 2); + + EXPECT_EQ(metadata[3].get().game_object_id, 3); + EXPECT_EQ(metadata[3].get().name, "scene_2"); + EXPECT_EQ(metadata[3].get().tag, "tag_scene_2"); + EXPECT_EQ(metadata[3].get().parent, -1); + EXPECT_EQ(metadata[3].get().children.size(), 0); + EXPECT_EQ(transform[3].get().position.x, 0); + EXPECT_EQ(transform[3].get().position.y, 3); +} -- cgit v1.2.3 From 52e84ca0a81210cd1dc61e096c228586649c9bfc Mon Sep 17 00:00:00 2001 From: heavydemon21 Date: Wed, 20 Nov 2024 11:35:25 +0100 Subject: updated adjsuted rendering based on feedback --- src/crepe/facade/SDLContext.cpp | 51 +++++++++++++++++++++++++++++--------- src/crepe/facade/SDLContext.h | 26 +++++++++++++++++-- src/crepe/system/RenderSystem.cpp | 8 +++--- src/crepe/system/RenderSystem.h | 3 ++- src/example/rendering_particle.cpp | 11 ++++---- 5 files changed, 74 insertions(+), 25 deletions(-) (limited to 'src') diff --git a/src/crepe/facade/SDLContext.cpp b/src/crepe/facade/SDLContext.cpp index 40189f6..8131df2 100644 --- a/src/crepe/facade/SDLContext.cpp +++ b/src/crepe/facade/SDLContext.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -15,6 +16,8 @@ #include "../api/Texture.h" #include "../api/Transform.h" #include "../util/Log.h" +#include "api/Camera.h" +#include "api/Vector2.h" #include "SDLContext.h" @@ -93,30 +96,54 @@ void SDLContext::handle_events(bool & running) { void SDLContext::clear_screen() { SDL_RenderClear(this->game_renderer.get()); } void SDLContext::present_screen() { SDL_RenderPresent(this->game_renderer.get()); } -void SDLContext::draw(const Sprite & sprite, const Transform & transform, const Camera & cam) { - - SDL_RendererFlip render_flip - = (SDL_RendererFlip) ((SDL_FLIP_HORIZONTAL * sprite.flip.flip_x) - | (SDL_FLIP_VERTICAL * sprite.flip.flip_y)); - - double adjusted_x = (transform.position.x - cam.x) * cam.zoom; - double adjusted_y = (transform.position.y - cam.y) * cam.zoom; - double adjusted_w = sprite.sprite_rect.w * transform.scale * cam.zoom; - double adjusted_h = sprite.sprite_rect.h * transform.scale * cam.zoom; - SDL_Rect srcrect = { +SDL_Rect SDLContext::get_src_rect(const Sprite & sprite) { + return SDL_Rect{ .x = sprite.sprite_rect.x, .y = sprite.sprite_rect.y, .w = sprite.sprite_rect.w, .h = sprite.sprite_rect.h, }; +} +SDL_Rect SDLContext::get_dst_rect(const Sprite & sprite, const Vector2 & pos, + const double & scale, const Camera & cam) { + + double adjusted_x = (pos.x - cam.x) * cam.zoom; + double adjusted_y = (pos.y - cam.y) * cam.zoom; + double adjusted_w = sprite.sprite_rect.w * scale * cam.zoom; + double adjusted_h = sprite.sprite_rect.h * scale * cam.zoom; - SDL_Rect dstrect = { + return SDL_Rect{ .x = static_cast(adjusted_x), .y = static_cast(adjusted_y), .w = static_cast(adjusted_w), .h = static_cast(adjusted_h), }; +} + +void SDLContext::draw_particle(const Sprite & sprite, const Vector2 & pos, + const double & angle, const double & scale, + const Camera & camera) { + + SDL_RendererFlip render_flip + = (SDL_RendererFlip) ((SDL_FLIP_HORIZONTAL * sprite.flip.flip_x) + | (SDL_FLIP_VERTICAL * sprite.flip.flip_y)); + + SDL_Rect srcrect = this->get_src_rect(sprite); + SDL_Rect dstrect = this->get_dst_rect(sprite, pos, scale, camera); + + SDL_RenderCopyEx(this->game_renderer.get(), sprite.sprite_image->texture.get(), &srcrect, + &dstrect, angle, NULL, render_flip); +} + +void SDLContext::draw(const Sprite & sprite, const Transform & transform, const Camera & cam) { + + SDL_RendererFlip render_flip + = (SDL_RendererFlip) ((SDL_FLIP_HORIZONTAL * sprite.flip.flip_x) + | (SDL_FLIP_VERTICAL * sprite.flip.flip_y)); + + SDL_Rect srcrect = this->get_src_rect(sprite); + SDL_Rect dstrect = this->get_dst_rect(sprite, transform.position, transform.scale, cam); SDL_RenderCopyEx(this->game_renderer.get(), sprite.sprite_image->texture.get(), &srcrect, &dstrect, transform.rotation, NULL, render_flip); diff --git a/src/crepe/facade/SDLContext.h b/src/crepe/facade/SDLContext.h index 78ac56b..fb09015 100644 --- a/src/crepe/facade/SDLContext.h +++ b/src/crepe/facade/SDLContext.h @@ -1,8 +1,10 @@ #pragma once #include +#include #include #include +#include #include #include #include @@ -10,6 +12,7 @@ #include "../api/Sprite.h" #include "../api/Transform.h" #include "api/Camera.h" +#include "api/Vector2.h" namespace crepe { @@ -122,8 +125,7 @@ private: * \param camera Reference to the Camera for view adjustments. */ void draw(const Sprite & sprite, const Transform & transform, const Camera & camera); - - void draw_particle(const Vector2 & pos, const Camera & camera); + void draw_particle(const Sprite & sprite, const Vector2 & pos, const double & angle, const double & scale, const Camera & camera); //! Clears the screen, preparing for a new frame. void clear_screen(); @@ -137,6 +139,26 @@ private: */ void camera(const Camera & camera); +private: + /** + * \brief calculates the sqaure size of the image + * + * \param sprite Reference to the sprite to calculate the rectangle + * \return sdl rectangle to draw a src image + */ + SDL_Rect get_src_rect(const Sprite & sprite); + /** + * \brief calculates the sqaure size of the image for an destination + * + * \param sprite Reference to the sprite to calculate the rectangle + * \param pos the pos in pixel positions + * \param scale the multiplier to increase of decrease for the specified sprite + * \param cam Reference to the current camera in the scene to calculate the position based + * on the camera + * \return sdl rectangle to draw a dst image to draw on the screen + */ + SDL_Rect get_dst_rect(const Sprite & sprite, const Vector2 & pos, const double & scale, const Camera & cam); + private: //! sdl Window std::unique_ptr> game_window; diff --git a/src/crepe/system/RenderSystem.cpp b/src/crepe/system/RenderSystem.cpp index 39e0e3f..1ae5ca7 100644 --- a/src/crepe/system/RenderSystem.cpp +++ b/src/crepe/system/RenderSystem.cpp @@ -27,7 +27,7 @@ void RenderSystem::update_camera() { } bool RenderSystem::render_particle(const Sprite & sprite, - Transform tm) { + const double & scale) { ComponentManager & mgr = this->component_manager; SDLContext & render = SDLContext::get_instance(); @@ -44,9 +44,7 @@ bool RenderSystem::render_particle(const Sprite & sprite, for (const Particle & p : em.data.particles) { if (!p.active) continue; - tm.position = p.position; - tm.rotation = p.angle; - render.draw(em.data.sprite, tm, *curr_cam); + render.draw_particle(sprite, p.position, p.angle, scale, *this->curr_cam); } } return rendering_particles; @@ -68,7 +66,7 @@ void RenderSystem::render() { if (!sprite.active) continue; auto transform = mgr.get_components_by_id(sprite.game_object_id).front().get(); - bool rendered_particles = this->render_particle(sprite, transform); + bool rendered_particles = this->render_particle(sprite, transform.scale); if (rendered_particles) continue; diff --git a/src/crepe/system/RenderSystem.h b/src/crepe/system/RenderSystem.h index c18b80b..6643084 100644 --- a/src/crepe/system/RenderSystem.h +++ b/src/crepe/system/RenderSystem.h @@ -5,6 +5,7 @@ #include "api/Transform.h" #include "System.h" +#include namespace crepe { @@ -51,7 +52,7 @@ private: * \param tm the Transform component for scale * \return true if particles have been rendered */ - bool render_particle(const Sprite &, Transform tm); + bool render_particle(const Sprite &, const double & scale); /** * \brief renders a sprite with a Transform component on the screen diff --git a/src/example/rendering_particle.cpp b/src/example/rendering_particle.cpp index 33013ef..71b50ba 100644 --- a/src/example/rendering_particle.cpp +++ b/src/example/rendering_particle.cpp @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include @@ -21,7 +20,11 @@ using namespace crepe; using namespace std; int main(int argc, char * argv[]) { - GameObject game_object(0, "", "", Vector2{100, 100}, 0, 0.1); + ComponentManager mgr; + GameObject game_object = mgr.new_object("", "", Vector2{100, 100}, 0, 0.1); + RenderSystem sys{mgr}; + ParticleSystem psys{mgr}; + Color color(255, 255, 255, 255); Sprite test_sprite = game_object.add_component( make_shared("../asset/texture/img.png"), color, @@ -47,11 +50,9 @@ int main(int argc, char * argv[]) { }); game_object.add_component(Color::get_white()); - auto & sys = crepe::RenderSystem::get_instance(); - auto sys_part = crepe::ParticleSystem(); auto start = std::chrono::steady_clock::now(); while (std::chrono::steady_clock::now() - start < std::chrono::seconds(5)) { - sys_part.update(); + psys.update(); sys.update(); SDL_Delay(10 ); } -- cgit v1.2.3 From e585e01b625fcdbc00709c1bbade1b542b1f6139 Mon Sep 17 00:00:00 2001 From: max-001 Date: Wed, 20 Nov 2024 11:42:23 +0100 Subject: Added Doxygen comments/explanation for GameObjects and Scenes --- src/crepe/api/Scene.h | 14 ++++++++++ src/crepe/api/SceneManager.h | 10 +++++++ src/doc/feature/gameobject.dox | 18 +++++++++++++ src/doc/feature/scene.dox | 60 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 102 insertions(+) create mode 100644 src/doc/feature/gameobject.dox create mode 100644 src/doc/feature/scene.dox (limited to 'src') diff --git a/src/crepe/api/Scene.h b/src/crepe/api/Scene.h index 0e516b6..6647135 100644 --- a/src/crepe/api/Scene.h +++ b/src/crepe/api/Scene.h @@ -7,19 +7,33 @@ namespace crepe { class SceneManager; class ComponentManager; +/** + * \brief Represents a Scene + * + * This class represents a Scene. The Scene class is only used as an interface for the game + * programmer. + */ class Scene { protected: + /** + * \param mgr Reference to the ComponentManager + * \param name Name of the scene + */ Scene(ComponentManager & mgr, const std::string & name); + //! SceneManager instances Scene friend class SceneManager; public: virtual ~Scene() = default; public: + //! Load the scene virtual void load_scene() = 0; + //! The scene name const std::string name; protected: + //! Reference to the ComponentManager ComponentManager & component_manager; }; diff --git a/src/crepe/api/SceneManager.h b/src/crepe/api/SceneManager.h index e854794..16d6004 100644 --- a/src/crepe/api/SceneManager.h +++ b/src/crepe/api/SceneManager.h @@ -10,8 +10,15 @@ namespace crepe { class ComponentManager; +/** + * \brief Manages scenes + * + * This class manages scenes. It can add new scenes and load them. It also manages the current scene + * and the next scene. + */ class SceneManager { public: + //! \param mgr Reference to the ComponentManager SceneManager(ComponentManager & mgr); public: @@ -35,8 +42,11 @@ public: void load_next_scene(); private: + //! Vector of scenes std::vector> scenes; + //! Next scene to load std::string next_scene; + //! Reference to the ComponentManager ComponentManager & component_manager; }; diff --git a/src/doc/feature/gameobject.dox b/src/doc/feature/gameobject.dox new file mode 100644 index 0000000..603c98d --- /dev/null +++ b/src/doc/feature/gameobject.dox @@ -0,0 +1,18 @@ +// vim:ft=doxygen +namespace crepe { +/** + +\defgroup feature_gameobject GameObjects +\ingroup feature +\brief GameObject to create a Scene + +GameObjects are the fundamental building blocks of a Scene. They represent entities +in the game world and can have various components attached to them to define their +behavior and properties. GameObjects can be created, and modified within the +Scene, allowing for a flexible and dynamic game environment. + +\see Component +\see Scene + +*/ +} diff --git a/src/doc/feature/scene.dox b/src/doc/feature/scene.dox new file mode 100644 index 0000000..50f5ebd --- /dev/null +++ b/src/doc/feature/scene.dox @@ -0,0 +1,60 @@ +// vim:ft=doxygen +namespace crepe { +/** + +\defgroup feature_scene Scenes +\ingroup feature +\brief User-defined scenes + +Scenes can be used to implement game environments, and allow arbitrary game objects to be organized +as part of the game structure. Scenes are implemented as derivative classes of Scene, which are +added to the game using the SceneManager. Scenes describe the start of a Scene and cannot modify +GameObject during runtime of a Scene (use Scripting for this purpose). + +\see SceneManager +\see GameObject +\see Script +\see Scene + +\par Example + +This example demonstrates how to define and add scenes to a scene manager in the `crepe` framework. +Two concrete scene classes, `ConcreteScene1` and `ConcreteScene2`, are derived from the base `Scene` class. +Each scene class overrides the `load_scene` method to create and initialize game objects specific to the scene. +Finally, the scenes are added to the scene manager. + +```cpp +using namespace crepe; + +class ConcreteScene1 : public Scene { +public: + using Scene::Scene; + + void load_scene() { + auto & mgr = this->component_manager; + GameObject object1 = mgr.new_object("scene_1", "tag_scene_1", Vector2{0, 0}, 0, 1); + GameObject object2 = mgr.new_object("scene_1", "tag_scene_1", Vector2{1, 0}, 0, 1); + GameObject object3 = mgr.new_object("scene_1", "tag_scene_1", Vector2{2, 0}, 0, 1); + } +}; + +class ConcreteScene2 : public Scene { +public: + using Scene::Scene; + + void load_scene() { + auto & mgr = this->component_manager; + GameObject object1 = mgr.new_object("scene_2", "tag_scene_2", Vector2{0, 0}, 0, 1); + GameObject object2 = mgr.new_object("scene_2", "tag_scene_2", Vector2{0, 1}, 0, 1); + GameObject object3 = mgr.new_object("scene_2", "tag_scene_2", Vector2{0, 2}, 0, 1); + GameObject object4 = mgr.new_object("scene_2", "tag_scene_2", Vector2{0, 3}, 0, 1); + } +}; + +// Add the scenes to the scene manager +scene_mgr.add_scene("scene1"); +scene_mgr.add_scene("scene2"); +``` + +*/ +} -- cgit v1.2.3 From 5121e95e5ba98ca5cadfb63b7603731dfb41a322 Mon Sep 17 00:00:00 2001 From: heavydemon21 Date: Wed, 20 Nov 2024 11:53:17 +0100 Subject: implemented feedback --- makefile | 2 +- mwe/events/include/event.h | 2 +- src/crepe/api/Sprite.h | 3 ++- src/crepe/facade/SDLContext.h | 1 - src/crepe/system/RenderSystem.cpp | 15 +++++++-------- src/crepe/system/RenderSystem.h | 20 +++++++++++--------- 6 files changed, 22 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/makefile b/makefile index dd7c587..32e68c0 100644 --- a/makefile +++ b/makefile @@ -6,5 +6,5 @@ doxygen: Doxyfile FORCE FMT += $(shell git ls-files '*.c' '*.cpp' '*.h' '*.hpp') format: FORCE clang-format -i $(FMT) - $(MAKE) -C src $@ + #$(MAKE) -C src $@ diff --git a/mwe/events/include/event.h b/mwe/events/include/event.h index ee1bf52..e1b220b 100644 --- a/mwe/events/include/event.h +++ b/mwe/events/include/event.h @@ -148,7 +148,7 @@ private: }; class ShutDownEvent : public Event { public: - ShutDownEvent() : Event("ShutDownEvent") {}; + ShutDownEvent() : Event("ShutDownEvent"){}; REGISTER_EVENT_TYPE(ShutDownEvent) diff --git a/src/crepe/api/Sprite.h b/src/crepe/api/Sprite.h index 0192793..74a55d4 100644 --- a/src/crepe/api/Sprite.h +++ b/src/crepe/api/Sprite.h @@ -2,8 +2,9 @@ #include +#include "../Component.h" + #include "Color.h" -#include "Component.h" #include "Texture.h" namespace crepe { diff --git a/src/crepe/facade/SDLContext.h b/src/crepe/facade/SDLContext.h index d437bc4..652a83e 100644 --- a/src/crepe/facade/SDLContext.h +++ b/src/crepe/facade/SDLContext.h @@ -21,7 +21,6 @@ namespace crepe { // typedef is unusable when crepe is packaged. Wouter will fix this later. typedef SDL_Keycode CREPE_KEYCODES; - /** * \class SDLContext * \brief Facade for the SDL library diff --git a/src/crepe/system/RenderSystem.cpp b/src/crepe/system/RenderSystem.cpp index 82257c4..96c5f27 100644 --- a/src/crepe/system/RenderSystem.cpp +++ b/src/crepe/system/RenderSystem.cpp @@ -12,10 +12,11 @@ #include "RenderSystem.h" using namespace crepe; +using namespace std; -void RenderSystem::clear_screen() const { SDLContext::get_instance().clear_screen(); } +void RenderSystem::clear_screen() { this->context.clear_screen(); } -void RenderSystem::present_screen() const { SDLContext::get_instance().present_screen(); } +void RenderSystem::present_screen() { this->context.present_screen(); } void RenderSystem::update_camera() { ComponentManager & mgr = this->component_manager; @@ -24,7 +25,7 @@ void RenderSystem::update_camera() { if (cameras.size() == 0) throw std::runtime_error("No cameras in current scene"); for (Camera & cam : cameras) { - SDLContext::get_instance().camera(cam); + this->context.camera(cam); this->curr_cam_ref = &cam; } } @@ -47,14 +48,12 @@ RenderSystem::sort(std::vector> & objs) { void RenderSystem::render_sprites() { ComponentManager & mgr = this->component_manager; + vector> sprites = mgr.get_components_by_type(); + vector> sorted_sprites = this->sort(sprites); - auto sprites = mgr.get_components_by_type(); - auto sorted_sprites = this->sort(sprites); - - SDLContext & render = SDLContext::get_instance(); for (const Sprite & sprite : sorted_sprites) { auto transforms = mgr.get_components_by_id(sprite.game_object_id); - render.draw(sprite, transforms[0], *this->curr_cam_ref); + this->context.draw(sprite, transforms[0], *this->curr_cam_ref); } } diff --git a/src/crepe/system/RenderSystem.h b/src/crepe/system/RenderSystem.h index 1176b06..8914b96 100644 --- a/src/crepe/system/RenderSystem.h +++ b/src/crepe/system/RenderSystem.h @@ -1,23 +1,23 @@ #pragma once - #include #include -#include "api/Sprite.h" -#include "api/Camera.h" +#include "facade/SDLContext.h" #include "System.h" namespace crepe { +class Camera; +class Sprite; + /** * \class RenderSystem * \brief Manages rendering operations for all game objects. * - * RenderSystem is responsible for rendering sprites, clearing and presenting the screen, and - * managing the active camera. It functions as a singleton, providing centralized rendering - * services for the application. + * RenderSystem is responsible for rendering, clearing and presenting the screen, and + * managing the active camera. */ class RenderSystem : public System { public: @@ -30,16 +30,16 @@ public: private: //! Clears the screen in preparation for rendering. - void clear_screen() const; + void clear_screen(); //! Presents the rendered frame to the display. - void present_screen() const; + void present_screen(); //! Updates the active camera used for rendering. void update_camera(); //! Renders all active sprites to the screen. - void render_sprites() ; + void render_sprites(); std::vector> sort(std::vector> & objs); @@ -58,6 +58,8 @@ private: //! Pointer to the current active camera for rendering Camera * curr_cam_ref = nullptr; // TODO: needs a better solution + + SDLContext & context = SDLContext::get_instance(); }; } // namespace crepe -- cgit v1.2.3 From d4dd3ceab2b95c26f3b07092a5c80f47eab18110 Mon Sep 17 00:00:00 2001 From: Loek Le Blansch Date: Wed, 20 Nov 2024 13:02:08 +0100 Subject: split format/lint --- makefile | 3 ++- src/makefile | 7 +++++-- 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/makefile b/makefile index dd7c587..c46e8a5 100644 --- a/makefile +++ b/makefile @@ -6,5 +6,6 @@ doxygen: Doxyfile FORCE FMT += $(shell git ls-files '*.c' '*.cpp' '*.h' '*.hpp') format: FORCE clang-format -i $(FMT) - $(MAKE) -C src $@ +lint: FORCE + $(MAKE) -C src $@ diff --git a/src/makefile b/src/makefile index 5f80204..a0e8f02 100644 --- a/src/makefile +++ b/src/makefile @@ -1,6 +1,9 @@ .PHONY: FORCE -FMT := $(shell git ls-files '*.c' '*.cpp' '*.h' '*.hpp') format: FORCE - clang-tidy -p build/compile_commands.json --fix-errors $(FMT) + $(MAKE) -C .. $@ + +LINT := $(shell git ls-files '*.c' '*.cpp' '*.h' '*.hpp') +lint: FORCE + clang-tidy -p build/compile_commands.json --fix-errors $(LINT) -- cgit v1.2.3 From 158022890cb9abd308a6a445588cc2fca8d84e67 Mon Sep 17 00:00:00 2001 From: heavydemon21 Date: Wed, 20 Nov 2024 13:25:44 +0100 Subject: implementing feedback --- src/crepe/facade/SDLContext.cpp | 3 ++- src/crepe/facade/SDLContext.h | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/crepe/facade/SDLContext.cpp b/src/crepe/facade/SDLContext.cpp index 8131df2..eacb10a 100644 --- a/src/crepe/facade/SDLContext.cpp +++ b/src/crepe/facade/SDLContext.cpp @@ -149,7 +149,7 @@ void SDLContext::draw(const Sprite & sprite, const Transform & transform, const &dstrect, transform.rotation, NULL, render_flip); } -void SDLContext::camera(const Camera & cam) { +void SDLContext::set_camera(const Camera & cam) { this->viewport.w = static_cast(cam.aspect_width); this->viewport.h = static_cast(cam.aspect_height); this->viewport.x = static_cast(cam.x) - (this->viewport.w / 2); @@ -167,6 +167,7 @@ SDLContext::texture_from_path(const std::string & path) { SDL_Surface * tmp = IMG_Load(path.c_str()); if (tmp == nullptr) { tmp = IMG_Load("../asset/texture/ERROR.png"); + if (tmp == nullptr) throw runtime_error("cannot load image"); } std::unique_ptr> img_surface; diff --git a/src/crepe/facade/SDLContext.h b/src/crepe/facade/SDLContext.h index fb09015..287ad5d 100644 --- a/src/crepe/facade/SDLContext.h +++ b/src/crepe/facade/SDLContext.h @@ -125,6 +125,7 @@ private: * \param camera Reference to the Camera for view adjustments. */ void draw(const Sprite & sprite, const Transform & transform, const Camera & camera); + void draw_particle(const Sprite & sprite, const Vector2 & pos, const double & angle, const double & scale, const Camera & camera); //! Clears the screen, preparing for a new frame. @@ -134,10 +135,10 @@ private: void present_screen(); /** - * \brief Sets the current camera for rendering. + * \brief sets the background of the camera (will be adjusted in future PR) * \param camera Reference to the Camera object. */ - void camera(const Camera & camera); + void set_camera(const Camera & camera); private: /** -- cgit v1.2.3 From c6d7623cc0bc17aa171bc5078f2f36c15be28683 Mon Sep 17 00:00:00 2001 From: heavydemon21 Date: Wed, 20 Nov 2024 13:39:44 +0100 Subject: implemented feedback from @lonkaars --- src/crepe/api/Color.cpp | 37 ++------- src/crepe/api/Color.h | 49 ++++------- src/crepe/system/RenderSystem.h | 6 ++ src/test/CMakeLists.txt | 2 +- src/test/RenderSystemTest.cpp | 174 ++++++++++++++++++++++++++++++++++++++++ src/test/rendering.cpp | 174 ---------------------------------------- 6 files changed, 203 insertions(+), 239 deletions(-) create mode 100644 src/test/RenderSystemTest.cpp delete mode 100644 src/test/rendering.cpp (limited to 'src') diff --git a/src/crepe/api/Color.cpp b/src/crepe/api/Color.cpp index 9e5f187..29bd77a 100644 --- a/src/crepe/api/Color.cpp +++ b/src/crepe/api/Color.cpp @@ -2,32 +2,11 @@ using namespace crepe; -Color Color::white = Color(255, 255, 255, 0); -Color Color::red = Color(255, 0, 0, 0); -Color Color::green = Color(0, 255, 0, 0); -Color Color::blue = Color(0, 0, 255, 0); -Color Color::black = Color(0, 0, 0, 0); -Color Color::cyan = Color(0, 255, 255, 0); -Color Color::yellow = Color(255, 255, 0, 0); -Color Color::magenta = Color(255, 0, 255, 0); - -Color::Color(uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha) { - this->a = alpha; - this->r = red; - this->g = green; - this->b = blue; -}; - -const Color & Color::get_white() { return Color::white; }; - -const Color & Color::get_red() { return Color::red; }; -const Color & Color::get_green() { return Color::green; }; -const Color & Color::get_blue() { return Color::blue; }; - -const Color & Color::get_black() { return Color::black; }; - -const Color & Color::get_cyan() { return Color::cyan; }; - -const Color & Color::get_yellow() { return Color::yellow; }; - -const Color & Color::get_magenta() { return Color::magenta; }; +const Color Color::WHITE{0xff, 0xff, 0xff}; +const Color Color::RED{0xff, 0x00, 0x00}; +const Color Color::GREEN{0x00, 0xff, 0x00}; +const Color Color::BLUE{0x00, 0x00, 0xff}; +const Color Color::BLACK{0x00, 0x00, 0x00}; +const Color Color::CYAN{0x00, 0xff, 0xff}; +const Color Color::YELLOW{0xff, 0xff, 0x00}; +const Color Color::MAGENTA{0xff, 0x00, 0xff}; diff --git a/src/crepe/api/Color.h b/src/crepe/api/Color.h index c207ba7..84edb5c 100644 --- a/src/crepe/api/Color.h +++ b/src/crepe/api/Color.h @@ -4,41 +4,20 @@ namespace crepe { -// TODO: make Color a struct w/o constructors/destructors -class Color { - - // FIXME: can't these colors be defined as a `static constexpr const Color` - // instead? - -public: - Color(uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha); - static const Color & get_white(); - static const Color & get_red(); - static const Color & get_green(); - static const Color & get_blue(); - static const Color & get_cyan(); - static const Color & get_magenta(); - static const Color & get_yellow(); - static const Color & get_black(); - -public: - uint8_t r; - uint8_t g; - uint8_t b; - uint8_t a; - -private: - static Color white; - static Color red; - static Color green; - static Color blue; - static Color cyan; - static Color magenta; - static Color yellow; - static Color black; - -private: - friend class SDLContext; +struct Color { + uint8_t r = 0x00; + uint8_t g = 0x00; + uint8_t b = 0x00; + uint8_t a = 0xff; + + static const Color WHITE; + static const Color RED; + static const Color GREEN; + static const Color BLUE; + static const Color CYAN; + static const Color MAGENTA; + static const Color YELLOW; + static const Color BLACK; }; } // namespace crepe diff --git a/src/crepe/system/RenderSystem.h b/src/crepe/system/RenderSystem.h index 8914b96..57b9c73 100644 --- a/src/crepe/system/RenderSystem.h +++ b/src/crepe/system/RenderSystem.h @@ -41,6 +41,12 @@ private: //! Renders all active sprites to the screen. void render_sprites(); + /** + * \brief sort a vector sprite objects with + * + * \param objs the vector that will do a sorting algorithm on + * \return returns a sorted reference vector + */ std::vector> sort(std::vector> & objs); diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt index 0969a52..1c93220 100644 --- a/src/test/CMakeLists.txt +++ b/src/test/CMakeLists.txt @@ -3,6 +3,6 @@ target_sources(test_main PUBLIC PhysicsTest.cpp ScriptTest.cpp ParticleTest.cpp - rendering.cpp + RenderSystemTest.cpp ) diff --git a/src/test/RenderSystemTest.cpp b/src/test/RenderSystemTest.cpp new file mode 100644 index 0000000..ac479d3 --- /dev/null +++ b/src/test/RenderSystemTest.cpp @@ -0,0 +1,174 @@ +#include "api/Camera.h" +#include +#include +#include +#include + +#define private public +#define protected public + +#include +#include +#include +#include +#include + +#include + +using namespace std; +using namespace crepe; +using namespace testing; + +class RenderSystemTest : public Test { +public: + ComponentManager mgr{}; + RenderSystem sys{mgr}; + GameObject entity1 = this->mgr.new_object("name"); + GameObject entity2 = this->mgr.new_object("name"); + GameObject entity3 = this->mgr.new_object("name"); + GameObject entity4 = this->mgr.new_object("name"); + + void SetUp() override { + auto & sprite1 + = entity1.add_component(make_shared("../asset/texture/img.png"), + Color(0, 0, 0, 0), FlipSettings{false, false}); + ASSERT_NE(sprite1.sprite_image.get(), nullptr); + sprite1.order_in_layer = 5; + sprite1.sorting_in_layer = 5; + EXPECT_EQ(sprite1.order_in_layer, 5); + EXPECT_EQ(sprite1.sorting_in_layer, 5); + auto & sprite2 + = entity2.add_component(make_shared("../asset/texture/img.png"), + Color(0, 0, 0, 0), FlipSettings{false, false}); + ASSERT_NE(sprite2.sprite_image.get(), nullptr); + sprite2.sorting_in_layer = 2; + sprite2.order_in_layer = 1; + + EXPECT_EQ(sprite2.sorting_in_layer, 2); + EXPECT_EQ(sprite2.order_in_layer, 1); + + auto & sprite3 + = entity3.add_component(make_shared("../asset/texture/img.png"), + Color(0, 0, 0, 0), FlipSettings{false, false}); + ASSERT_NE(sprite3.sprite_image.get(), nullptr); + sprite3.sorting_in_layer = 1; + sprite3.order_in_layer = 2; + + EXPECT_EQ(sprite3.sorting_in_layer, 1); + EXPECT_EQ(sprite3.order_in_layer, 2); + + auto & sprite4 + = entity4.add_component(make_shared("../asset/texture/img.png"), + Color(0, 0, 0, 0), FlipSettings{false, false}); + ASSERT_NE(sprite4.sprite_image.get(), nullptr); + sprite4.sorting_in_layer = 1; + sprite4.order_in_layer = 1; + EXPECT_EQ(sprite4.sorting_in_layer, 1); + EXPECT_EQ(sprite4.order_in_layer, 1); + } +}; + +TEST_F(RenderSystemTest, expected_throws) { + GameObject entity1 = this->mgr.new_object("NAME"); + + // no texture img + EXPECT_ANY_THROW({ + entity1.add_component(make_shared("NO_IMAGE"), Color(0, 0, 0, 0), + FlipSettings{false, false}); + }); + + // No camera + EXPECT_ANY_THROW({ this->sys.update(); }); +} + +TEST_F(RenderSystemTest, make_sprites) {} + +TEST_F(RenderSystemTest, sorting_sprites) { + vector> sprites = this->mgr.get_components_by_type(); + ASSERT_EQ(sprites.size(), 4); + + vector> sorted_sprites = this->sys.sort(sprites); + ASSERT_EQ(sorted_sprites.size(), 4); + + // Expected order after sorting: + // 1. sorting_in_layer: 1, order_in_layer: 1 (entity4) + // 2. sorting_in_layer: 1, order_in_layer: 2 (entity3) + // 3. sorting_in_layer: 2, order_in_layer: 1 (entity2) + // 4. sorting_in_layer: 5, order_in_layer: 5 (entity1) + + EXPECT_EQ(sorted_sprites[0].get().sorting_in_layer, 1); + EXPECT_EQ(sorted_sprites[0].get().order_in_layer, 1); + + EXPECT_EQ(sorted_sprites[1].get().sorting_in_layer, 1); + EXPECT_EQ(sorted_sprites[1].get().order_in_layer, 2); + + EXPECT_EQ(sorted_sprites[2].get().sorting_in_layer, 2); + EXPECT_EQ(sorted_sprites[2].get().order_in_layer, 1); + + EXPECT_EQ(sorted_sprites[3].get().sorting_in_layer, 5); + EXPECT_EQ(sorted_sprites[3].get().order_in_layer, 5); + + for (size_t i = 1; i < sorted_sprites.size(); ++i) { + const Sprite & prev = sorted_sprites[i - 1].get(); + const Sprite & curr = sorted_sprites[i].get(); + + if (prev.sorting_in_layer == curr.sorting_in_layer) { + EXPECT_LE(prev.order_in_layer, curr.order_in_layer); + } else { + EXPECT_LE(prev.sorting_in_layer, curr.sorting_in_layer); + } + } +} + +TEST_F(RenderSystemTest, Update) { + entity1.add_component(Color::WHITE); + { + vector> sprites = this->mgr.get_components_by_type(); + ASSERT_EQ(sprites.size(), 4); + + EXPECT_EQ(sprites[0].get().game_object_id, 0); + EXPECT_EQ(sprites[1].get().game_object_id, 1); + EXPECT_EQ(sprites[2].get().game_object_id, 2); + EXPECT_EQ(sprites[3].get().game_object_id, 3); + } + this->sys.update(); + { + vector> sprites = this->mgr.get_components_by_type(); + ASSERT_EQ(sprites.size(), 4); + + EXPECT_EQ(sprites[0].get().game_object_id, 0); + EXPECT_EQ(sprites[1].get().game_object_id, 1); + EXPECT_EQ(sprites[2].get().game_object_id, 2); + EXPECT_EQ(sprites[3].get().game_object_id, 3); + } +} + +TEST_F(RenderSystemTest, Camera) { + { + auto cameras = this->mgr.get_components_by_type(); + EXPECT_NE(cameras.size(), 1); + } + { + entity1.add_component(Color::WHITE); + auto cameras = this->mgr.get_components_by_type(); + EXPECT_EQ(cameras.size(), 1); + } + + //TODO improve with newer version +} +TEST_F(RenderSystemTest, Color) { + entity1.add_component(Color::WHITE); + auto & sprite = this->mgr.get_components_by_id(entity1.id).front().get(); + ASSERT_NE(sprite.sprite_image.get(), nullptr); + + sprite.color = Color::GREEN; + EXPECT_EQ(sprite.color.r, Color::GREEN.r); + EXPECT_EQ(sprite.color.g, Color::GREEN.g); + EXPECT_EQ(sprite.color.b, Color::GREEN.b); + EXPECT_EQ(sprite.color.a, Color::GREEN.a); + this->sys.update(); + EXPECT_EQ(sprite.color.r, Color::GREEN.r); + EXPECT_EQ(sprite.color.g, Color::GREEN.g); + EXPECT_EQ(sprite.color.b, Color::GREEN.b); + EXPECT_EQ(sprite.color.a, Color::GREEN.a); +} diff --git a/src/test/rendering.cpp b/src/test/rendering.cpp deleted file mode 100644 index 4c5fb1d..0000000 --- a/src/test/rendering.cpp +++ /dev/null @@ -1,174 +0,0 @@ -#include "api/Camera.h" -#include -#include -#include -#include - -#define private public -#define protected public - -#include -#include -#include -#include -#include - -#include - -using namespace std; -using namespace crepe; -using namespace testing; - -class RenderSystemTest : public Test { -public: - ComponentManager mgr{}; - RenderSystem sys{mgr}; - GameObject entity1 = this->mgr.new_object("name"); - GameObject entity2 = this->mgr.new_object("name"); - GameObject entity3 = this->mgr.new_object("name"); - GameObject entity4 = this->mgr.new_object("name"); - - void SetUp() override { - auto & sprite1 - = entity1.add_component(make_shared("../asset/texture/img.png"), - Color(0, 0, 0, 0), FlipSettings{false, false}); - ASSERT_NE(sprite1.sprite_image.get(), nullptr); - sprite1.order_in_layer = 5; - sprite1.sorting_in_layer = 5; - EXPECT_EQ(sprite1.order_in_layer, 5); - EXPECT_EQ(sprite1.sorting_in_layer, 5); - auto & sprite2 - = entity2.add_component(make_shared("../asset/texture/img.png"), - Color(0, 0, 0, 0), FlipSettings{false, false}); - ASSERT_NE(sprite2.sprite_image.get(), nullptr); - sprite2.sorting_in_layer = 2; - sprite2.order_in_layer = 1; - - EXPECT_EQ(sprite2.sorting_in_layer, 2); - EXPECT_EQ(sprite2.order_in_layer, 1); - - auto & sprite3 - = entity3.add_component(make_shared("../asset/texture/img.png"), - Color(0, 0, 0, 0), FlipSettings{false, false}); - ASSERT_NE(sprite3.sprite_image.get(), nullptr); - sprite3.sorting_in_layer = 1; - sprite3.order_in_layer = 2; - - EXPECT_EQ(sprite3.sorting_in_layer, 1); - EXPECT_EQ(sprite3.order_in_layer, 2); - - auto & sprite4 - = entity4.add_component(make_shared("../asset/texture/img.png"), - Color(0, 0, 0, 0), FlipSettings{false, false}); - ASSERT_NE(sprite4.sprite_image.get(), nullptr); - sprite4.sorting_in_layer = 1; - sprite4.order_in_layer = 1; - EXPECT_EQ(sprite4.sorting_in_layer, 1); - EXPECT_EQ(sprite4.order_in_layer, 1); - } -}; - -TEST_F(RenderSystemTest, expected_throws) { - GameObject entity1 = this->mgr.new_object("NAME"); - - // no texture img - EXPECT_ANY_THROW({ - entity1.add_component(make_shared("NO_IMAGE"), Color(0, 0, 0, 0), - FlipSettings{false, false}); - }); - - // No camera - EXPECT_ANY_THROW({ this->sys.update(); }); -} - -TEST_F(RenderSystemTest, make_sprites) {} - -TEST_F(RenderSystemTest, sorting_sprites) { - vector> sprites = this->mgr.get_components_by_type(); - ASSERT_EQ(sprites.size(), 4); - - vector> sorted_sprites = this->sys.sort(sprites); - ASSERT_EQ(sorted_sprites.size(), 4); - - // Expected order after sorting: - // 1. sorting_in_layer: 1, order_in_layer: 1 (entity4) - // 2. sorting_in_layer: 1, order_in_layer: 2 (entity3) - // 3. sorting_in_layer: 2, order_in_layer: 1 (entity2) - // 4. sorting_in_layer: 5, order_in_layer: 5 (entity1) - - EXPECT_EQ(sorted_sprites[0].get().sorting_in_layer, 1); - EXPECT_EQ(sorted_sprites[0].get().order_in_layer, 1); - - EXPECT_EQ(sorted_sprites[1].get().sorting_in_layer, 1); - EXPECT_EQ(sorted_sprites[1].get().order_in_layer, 2); - - EXPECT_EQ(sorted_sprites[2].get().sorting_in_layer, 2); - EXPECT_EQ(sorted_sprites[2].get().order_in_layer, 1); - - EXPECT_EQ(sorted_sprites[3].get().sorting_in_layer, 5); - EXPECT_EQ(sorted_sprites[3].get().order_in_layer, 5); - - for (size_t i = 1; i < sorted_sprites.size(); ++i) { - const Sprite & prev = sorted_sprites[i - 1].get(); - const Sprite & curr = sorted_sprites[i].get(); - - if (prev.sorting_in_layer == curr.sorting_in_layer) { - EXPECT_LE(prev.order_in_layer, curr.order_in_layer); - } else { - EXPECT_LE(prev.sorting_in_layer, curr.sorting_in_layer); - } - } -} - -TEST_F(RenderSystemTest, Update) { - entity1.add_component(Color::get_white()); - { - vector> sprites = this->mgr.get_components_by_type(); - ASSERT_EQ(sprites.size(), 4); - - EXPECT_EQ(sprites[0].get().game_object_id, 0); - EXPECT_EQ(sprites[1].get().game_object_id, 1); - EXPECT_EQ(sprites[2].get().game_object_id, 2); - EXPECT_EQ(sprites[3].get().game_object_id, 3); - } - this->sys.update(); - { - vector> sprites = this->mgr.get_components_by_type(); - ASSERT_EQ(sprites.size(), 4); - - EXPECT_EQ(sprites[0].get().game_object_id, 0); - EXPECT_EQ(sprites[1].get().game_object_id, 1); - EXPECT_EQ(sprites[2].get().game_object_id, 2); - EXPECT_EQ(sprites[3].get().game_object_id, 3); - } -} - -TEST_F(RenderSystemTest, Camera) { - { - auto cameras = this->mgr.get_components_by_type(); - EXPECT_NE(cameras.size(), 1); - } - { - entity1.add_component(Color::get_white()); - auto cameras = this->mgr.get_components_by_type(); - EXPECT_EQ(cameras.size(), 1); - } - - //TODO improve with newer version -} -TEST_F(RenderSystemTest, Color) { - entity1.add_component(Color::get_white()); - auto & sprite = this->mgr.get_components_by_id(entity1.id).front().get(); - ASSERT_NE(sprite.sprite_image.get(), nullptr); - - sprite.color = Color::get_green(); - EXPECT_EQ(sprite.color.r, Color::get_green().r); - EXPECT_EQ(sprite.color.g, Color::get_green().g); - EXPECT_EQ(sprite.color.b, Color::get_green().b); - EXPECT_EQ(sprite.color.a, Color::get_green().a); - this->sys.update(); - EXPECT_EQ(sprite.color.r, Color::get_green().r); - EXPECT_EQ(sprite.color.g, Color::get_green().g); - EXPECT_EQ(sprite.color.b, Color::get_green().b); - EXPECT_EQ(sprite.color.a, Color::get_green().a); -} -- cgit v1.2.3 From 02845c3d25130e9473604cb2eeee42a7a7a8eadf Mon Sep 17 00:00:00 2001 From: Loek Le Blansch Date: Wed, 20 Nov 2024 14:01:31 +0100 Subject: `make format` --- src/crepe/api/Asset.cpp | 15 +++++---------- src/crepe/api/Asset.h | 8 ++++---- src/crepe/types.h | 4 ++-- src/crepe/util/OptionalRef.h | 13 ++++++------- src/crepe/util/OptionalRef.hpp | 3 +-- src/example/rendering.cpp | 5 ++--- src/test/AssetTest.cpp | 13 +++---------- src/test/OptionalRefTest.cpp | 1 - 8 files changed, 23 insertions(+), 39 deletions(-) (limited to 'src') diff --git a/src/crepe/api/Asset.cpp b/src/crepe/api/Asset.cpp index 5271cf7..3fe3ceb 100644 --- a/src/crepe/api/Asset.cpp +++ b/src/crepe/api/Asset.cpp @@ -8,8 +8,8 @@ using namespace crepe; using namespace std; -Asset::Asset(const string & src) : src(find_asset(src)) { } -Asset::Asset(const char * src) : src(find_asset(src)) { } +Asset::Asset(const string & src) : src(find_asset(src)) {} +Asset::Asset(const char * src) : src(find_asset(src)) {} const string & Asset::get_path() const noexcept { return this->src; } @@ -22,14 +22,12 @@ string Asset::find_asset(const string & src) const { // absolute paths do not need to be resolved, only canonicalized filesystem::path path = src; - if (path.is_absolute()) - return filesystem::canonical(path); + if (path.is_absolute()) return filesystem::canonical(path); // find directory matching root_pattern filesystem::path root = this->whereami(); while (1) { - if (filesystem::exists(root / root_pattern)) - break; + if (filesystem::exists(root / root_pattern)) break; if (!root.has_parent_path()) throw runtime_error(format("Asset: Cannot find root pattern ({})", root_pattern)); root = root.parent_path(); @@ -48,11 +46,8 @@ string Asset::whereami() const noexcept { return path; } -bool Asset::operator==(const Asset & other) const noexcept { - return this->src == other.src; -} +bool Asset::operator==(const Asset & other) const noexcept { return this->src == other.src; } size_t std::hash::operator()(const Asset & asset) const noexcept { return std::hash{}(asset.get_path()); }; - diff --git a/src/crepe/api/Asset.h b/src/crepe/api/Asset.h index 685dd3a..77596ac 100644 --- a/src/crepe/api/Asset.h +++ b/src/crepe/api/Asset.h @@ -33,7 +33,7 @@ public: * \param other Possibly different instance of \c Asset to test equality against * \return True if \c this and \c other are equal */ - bool operator == (const Asset & other) const noexcept; + bool operator==(const Asset & other) const noexcept; private: //! path to asset @@ -52,7 +52,8 @@ private: namespace std { //! Hash helper struct -template<> struct hash { +template <> +struct hash { /** * \brief Hash operator for crepe::Asset * @@ -64,5 +65,4 @@ template<> struct hash { size_t operator()(const crepe::Asset & asset) const noexcept; }; -} - +} // namespace std diff --git a/src/crepe/types.h b/src/crepe/types.h index 86730cc..914c76c 100644 --- a/src/crepe/types.h +++ b/src/crepe/types.h @@ -1,8 +1,8 @@ #pragma once #include -#include #include +#include namespace crepe { @@ -13,4 +13,4 @@ typedef uint32_t game_object_id_t; template using RefVector = std::vector>; -} +} // namespace crepe diff --git a/src/crepe/util/OptionalRef.h b/src/crepe/util/OptionalRef.h index 8417a25..0a94ae5 100644 --- a/src/crepe/util/OptionalRef.h +++ b/src/crepe/util/OptionalRef.h @@ -23,7 +23,7 @@ public: * * \return Reference to this (required for operator) */ - OptionalRef & operator=(T & ref); + OptionalRef & operator=(T & ref); /** * \brief Check if this reference is not empty * @@ -51,13 +51,13 @@ public: void clear() noexcept; //! Copy constructor - OptionalRef(const OptionalRef &); + OptionalRef(const OptionalRef &); //! Move constructor - OptionalRef(OptionalRef &&); + OptionalRef(OptionalRef &&); //! Copy assignment - OptionalRef & operator=(const OptionalRef &); + OptionalRef & operator=(const OptionalRef &); //! Move assignment - OptionalRef & operator=(OptionalRef &&); + OptionalRef & operator=(OptionalRef &&); private: /** @@ -68,7 +68,6 @@ private: T * ref = nullptr; }; -} +} // namespace crepe #include "OptionalRef.hpp" - diff --git a/src/crepe/util/OptionalRef.hpp b/src/crepe/util/OptionalRef.hpp index 7b201b0..ee41f61 100644 --- a/src/crepe/util/OptionalRef.hpp +++ b/src/crepe/util/OptionalRef.hpp @@ -63,5 +63,4 @@ OptionalRef::operator bool() const noexcept { return this->ref != nullptr; } -} - +} // namespace crepe diff --git a/src/example/rendering.cpp b/src/example/rendering.cpp index 522ec0f..01794f8 100644 --- a/src/example/rendering.cpp +++ b/src/example/rendering.cpp @@ -30,9 +30,8 @@ int main() { // Normal adding components { Color color(0, 0, 0, 0); - Sprite & sprite - = obj.add_component(make_shared("asset/texture/img.png"), - color, FlipSettings{false, false}); + Sprite & sprite = obj.add_component( + make_shared("asset/texture/img.png"), color, FlipSettings{false, false}); sprite.sorting_in_layer = 2; sprite.order_in_layer = 1; obj.add_component(Color::RED); diff --git a/src/test/AssetTest.cpp b/src/test/AssetTest.cpp index 563a253..8aa7629 100644 --- a/src/test/AssetTest.cpp +++ b/src/test/AssetTest.cpp @@ -10,18 +10,12 @@ using namespace testing; class AssetTest : public Test { public: Config & cfg = Config::get_instance(); - void SetUp() override { - this->cfg.asset.root_pattern = ".crepe-root"; - } + void SetUp() override { this->cfg.asset.root_pattern = ".crepe-root"; } }; -TEST_F(AssetTest, Existant) { - ASSERT_NO_THROW(Asset{"asset/texture/img.png"}); -} +TEST_F(AssetTest, Existant) { ASSERT_NO_THROW(Asset{"asset/texture/img.png"}); } -TEST_F(AssetTest, Nonexistant) { - ASSERT_ANY_THROW(Asset{"asset/nonexistant"}); -} +TEST_F(AssetTest, Nonexistant) { ASSERT_ANY_THROW(Asset{"asset/nonexistant"}); } TEST_F(AssetTest, Rootless) { cfg.asset.root_pattern.clear(); @@ -30,4 +24,3 @@ TEST_F(AssetTest, Rootless) { Asset asset{arbitrary}; ASSERT_EQ(arbitrary, asset.get_path()); } - diff --git a/src/test/OptionalRefTest.cpp b/src/test/OptionalRefTest.cpp index 219ccca..2072d56 100644 --- a/src/test/OptionalRefTest.cpp +++ b/src/test/OptionalRefTest.cpp @@ -35,4 +35,3 @@ TEST(OptionalRefTest, Implicit) { EXPECT_TRUE(ref); ASSERT_NO_THROW(ref.get()); } - -- cgit v1.2.3 From 3344e0df01435be903e38ccbd3b9cee608d574e7 Mon Sep 17 00:00:00 2001 From: heavydemon21 Date: Wed, 20 Nov 2024 14:06:54 +0100 Subject: implemented feedback --- src/crepe/facade/SDLContext.cpp | 18 +++++++++--------- src/crepe/facade/SDLContext.h | 10 ++++++---- src/crepe/system/RenderSystem.cpp | 18 +++++++++--------- src/crepe/system/RenderSystem.h | 14 ++++---------- src/example/rendering_particle.cpp | 14 ++++++-------- 5 files changed, 34 insertions(+), 40 deletions(-) (limited to 'src') diff --git a/src/crepe/facade/SDLContext.cpp b/src/crepe/facade/SDLContext.cpp index eacb10a..daf0050 100644 --- a/src/crepe/facade/SDLContext.cpp +++ b/src/crepe/facade/SDLContext.cpp @@ -12,12 +12,12 @@ #include #include +#include "../api/Camera.h" #include "../api/Sprite.h" #include "../api/Texture.h" #include "../api/Transform.h" +#include "../api/Vector2.h" #include "../util/Log.h" -#include "api/Camera.h" -#include "api/Vector2.h" #include "SDLContext.h" @@ -96,8 +96,7 @@ void SDLContext::handle_events(bool & running) { void SDLContext::clear_screen() { SDL_RenderClear(this->game_renderer.get()); } void SDLContext::present_screen() { SDL_RenderPresent(this->game_renderer.get()); } - -SDL_Rect SDLContext::get_src_rect(const Sprite & sprite) { +SDL_Rect SDLContext::get_src_rect(const Sprite & sprite) const { return SDL_Rect{ .x = sprite.sprite_rect.x, .y = sprite.sprite_rect.y, @@ -106,7 +105,7 @@ SDL_Rect SDLContext::get_src_rect(const Sprite & sprite) { }; } SDL_Rect SDLContext::get_dst_rect(const Sprite & sprite, const Vector2 & pos, - const double & scale, const Camera & cam) { + const double & scale, const Camera & cam) const { double adjusted_x = (pos.x - cam.x) * cam.zoom; double adjusted_y = (pos.y - cam.y) * cam.zoom; @@ -123,20 +122,21 @@ SDL_Rect SDLContext::get_dst_rect(const Sprite & sprite, const Vector2 & pos, void SDLContext::draw_particle(const Sprite & sprite, const Vector2 & pos, const double & angle, const double & scale, - const Camera & camera) { + const Camera & camera) const { SDL_RendererFlip render_flip = (SDL_RendererFlip) ((SDL_FLIP_HORIZONTAL * sprite.flip.flip_x) - | (SDL_FLIP_VERTICAL * sprite.flip.flip_y)); + | (SDL_FLIP_VERTICAL * sprite.flip.flip_y)); SDL_Rect srcrect = this->get_src_rect(sprite); SDL_Rect dstrect = this->get_dst_rect(sprite, pos, scale, camera); SDL_RenderCopyEx(this->game_renderer.get(), sprite.sprite_image->texture.get(), &srcrect, - &dstrect, angle, NULL, render_flip); + &dstrect, angle, NULL, render_flip); } -void SDLContext::draw(const Sprite & sprite, const Transform & transform, const Camera & cam) { +void SDLContext::draw(const Sprite & sprite, const Transform & transform, + const Camera & cam) const { SDL_RendererFlip render_flip = (SDL_RendererFlip) ((SDL_FLIP_HORIZONTAL * sprite.flip.flip_x) diff --git a/src/crepe/facade/SDLContext.h b/src/crepe/facade/SDLContext.h index 287ad5d..718c40f 100644 --- a/src/crepe/facade/SDLContext.h +++ b/src/crepe/facade/SDLContext.h @@ -124,9 +124,10 @@ private: * \param transform Reference to the Transform for positioning. * \param camera Reference to the Camera for view adjustments. */ - void draw(const Sprite & sprite, const Transform & transform, const Camera & camera); + void draw(const Sprite & sprite, const Transform & transform, const Camera & camera) const; - void draw_particle(const Sprite & sprite, const Vector2 & pos, const double & angle, const double & scale, const Camera & camera); + void draw_particle(const Sprite & sprite, const Vector2 & pos, const double & angle, + const double & scale, const Camera & camera) const; //! Clears the screen, preparing for a new frame. void clear_screen(); @@ -147,7 +148,7 @@ private: * \param sprite Reference to the sprite to calculate the rectangle * \return sdl rectangle to draw a src image */ - SDL_Rect get_src_rect(const Sprite & sprite); + SDL_Rect get_src_rect(const Sprite & sprite) const; /** * \brief calculates the sqaure size of the image for an destination * @@ -158,7 +159,8 @@ private: * on the camera * \return sdl rectangle to draw a dst image to draw on the screen */ - SDL_Rect get_dst_rect(const Sprite & sprite, const Vector2 & pos, const double & scale, const Camera & cam); + SDL_Rect get_dst_rect(const Sprite & sprite, const Vector2 & pos, const double & scale, + const Camera & cam) const; private: //! sdl Window diff --git a/src/crepe/system/RenderSystem.cpp b/src/crepe/system/RenderSystem.cpp index 1ae5ca7..28bcf56 100644 --- a/src/crepe/system/RenderSystem.cpp +++ b/src/crepe/system/RenderSystem.cpp @@ -2,11 +2,11 @@ #include #include "../ComponentManager.h" +#include "../api/ParticleEmitter.h" #include "../api/Sprite.h" #include "../api/Transform.h" -#include "../facade/SDLContext.h" -#include "../api/ParticleEmitter.h" #include "../api/Vector2.h" +#include "../facade/SDLContext.h" #include "RenderSystem.h" @@ -21,13 +21,12 @@ void RenderSystem::update_camera() { auto cameras = mgr.get_components_by_type(); for (Camera & cam : cameras) { - SDLContext::get_instance().camera(cam); + SDLContext::get_instance().set_camera(cam); this->curr_cam = &cam; } } -bool RenderSystem::render_particle(const Sprite & sprite, - const double & scale) { +bool RenderSystem::render_particle(const Sprite & sprite, const double & scale) const { ComponentManager & mgr = this->component_manager; SDLContext & render = SDLContext::get_instance(); @@ -49,22 +48,23 @@ bool RenderSystem::render_particle(const Sprite & sprite, } return rendering_particles; } -void RenderSystem::render_normal(const Sprite & sprite, const Transform & tm) { +void RenderSystem::render_normal(const Sprite & sprite, const Transform & tm) const { ComponentManager & mgr = this->component_manager; SDLContext & render = SDLContext::get_instance(); - + render.draw(sprite, tm, *curr_cam); } -void RenderSystem::render() { +void RenderSystem::render() const { ComponentManager & mgr = this->component_manager; auto sprites = mgr.get_components_by_type(); for (const Sprite & sprite : sprites) { if (!sprite.active) continue; - auto transform = mgr.get_components_by_id(sprite.game_object_id).front().get(); + const Transform & transform + = mgr.get_components_by_id(sprite.game_object_id).front().get(); bool rendered_particles = this->render_particle(sprite, transform.scale); diff --git a/src/crepe/system/RenderSystem.h b/src/crepe/system/RenderSystem.h index 6643084..8841f72 100644 --- a/src/crepe/system/RenderSystem.h +++ b/src/crepe/system/RenderSystem.h @@ -25,13 +25,7 @@ public: * This method is called to perform all rendering operations for the current game frame. */ void update() override; - - - RenderSystem(const RenderSystem &) = delete; - RenderSystem(RenderSystem &&) = delete; - RenderSystem & operator=(const RenderSystem &) = delete; - RenderSystem & operator=(RenderSystem &&) = delete; - + private: //! Clears the screen in preparation for rendering. void clear_screen() const; @@ -43,7 +37,7 @@ private: void update_camera(); //! Renders the whole screen - void render(); + void render() const; /** * \brief Renders all the particles on the screen from a given sprite. @@ -52,7 +46,7 @@ private: * \param tm the Transform component for scale * \return true if particles have been rendered */ - bool render_particle(const Sprite &, const double & scale); + bool render_particle(const Sprite & sprite, const double & scale) const; /** * \brief renders a sprite with a Transform component on the screen @@ -60,7 +54,7 @@ private: * \param sprite the sprite component that holds all the data * \param tm the Transform component that holds the position,rotation and scale */ - void render_normal(const Sprite &, const Transform & tm); + void render_normal(const Sprite & sprite, const Transform & tm) const; /** * \todo Include color handling for sprites. diff --git a/src/example/rendering_particle.cpp b/src/example/rendering_particle.cpp index 71b50ba..3f71750 100644 --- a/src/example/rendering_particle.cpp +++ b/src/example/rendering_particle.cpp @@ -4,15 +4,15 @@ #include #include +#include #include #include #include +#include #include #include -#include -#include -#include #include +#include #include @@ -20,15 +20,14 @@ using namespace crepe; using namespace std; int main(int argc, char * argv[]) { - ComponentManager mgr; + ComponentManager mgr; GameObject game_object = mgr.new_object("", "", Vector2{100, 100}, 0, 0.1); RenderSystem sys{mgr}; ParticleSystem psys{mgr}; Color color(255, 255, 255, 255); Sprite test_sprite = game_object.add_component( - make_shared("../asset/texture/img.png"), color, - FlipSettings{false, false}); + make_shared("../asset/texture/img.png"), color, FlipSettings{false, false}); game_object.add_component(ParticleEmitter::Data{ .position = {0, 0}, .max_particles = 10, @@ -54,9 +53,8 @@ int main(int argc, char * argv[]) { while (std::chrono::steady_clock::now() - start < std::chrono::seconds(5)) { psys.update(); sys.update(); - SDL_Delay(10 ); + SDL_Delay(10); } return 0; } - -- cgit v1.2.3 From 22a7e9f3c40b4b6eb68a5343e4870e76c4bfcf63 Mon Sep 17 00:00:00 2001 From: Loek Le Blansch Date: Wed, 20 Nov 2024 14:24:08 +0100 Subject: process feedback on #39 --- readme.md | 7 +++++++ src/crepe/ComponentManager.h | 5 +++-- src/crepe/ComponentManager.hpp | 9 ++++----- src/crepe/api/Asset.cpp | 5 +++-- src/crepe/api/Asset.h | 16 ++++++++++++++++ src/crepe/system/System.h | 2 -- src/crepe/util/OptionalRef.h | 11 +---------- src/crepe/util/OptionalRef.hpp | 24 ------------------------ 8 files changed, 34 insertions(+), 45 deletions(-) (limited to 'src') diff --git a/readme.md b/readme.md index c83853d..d309b30 100644 --- a/readme.md +++ b/readme.md @@ -32,6 +32,7 @@ This project uses the following libraries |`SoLoud`|(latest git `master` version)| |Google Test (`GTest`)|1.15.2| |Berkeley DB (`libdb`)|5.3.21| +|Where Am I?|(latest git `master` version) > [!NOTE] > Most of these libraries are likely available from your package manager if you @@ -49,6 +50,11 @@ $ git submodule update --init --recursive --depth 1 Then, follow these steps for each library you want to install: +> [!IMPORTANT] +> A dollar sign prompt (`$`) indicates commands to be run as a regular user, +> while a hashtag (`#`) is used to denote commands that must be run with +> privileges (e.g. as root or using `sudo`). + 1. Change into the library folder (run **one** of these): ``` $ cd lib/googletest @@ -56,6 +62,7 @@ Then, follow these steps for each library you want to install: $ cd lib/soloud/contrib $ cd lib/sdl_image $ cd lib/sdl_ttf + $ cd lib/whereami ``` 2. Use CMake to configure the build, run the build and install (run **all** of these): diff --git a/src/crepe/ComponentManager.h b/src/crepe/ComponentManager.h index 2107453..0956d1e 100644 --- a/src/crepe/ComponentManager.h +++ b/src/crepe/ComponentManager.h @@ -8,6 +8,7 @@ #include "api/Vector2.h" #include "Component.h" +#include "types.h" namespace crepe { @@ -112,7 +113,7 @@ public: * \return A vector of all components of the specific type and id */ template - std::vector> get_components_by_id(game_object_id_t id) const; + RefVector get_components_by_id(game_object_id_t id) const; /** * \brief Get all components of a specific type * @@ -122,7 +123,7 @@ public: * \return A vector of all components of the specific type */ template - std::vector> get_components_by_type() const; + RefVector get_components_by_type() const; private: /** diff --git a/src/crepe/ComponentManager.hpp b/src/crepe/ComponentManager.hpp index be99cac..4d5eaf4 100644 --- a/src/crepe/ComponentManager.hpp +++ b/src/crepe/ComponentManager.hpp @@ -81,15 +81,14 @@ void ComponentManager::delete_components() { } template -std::vector> -ComponentManager::get_components_by_id(game_object_id_t id) const { +RefVector ComponentManager::get_components_by_id(game_object_id_t id) const { using namespace std; // Determine the type of T (this is used as the key of the unordered_map<>) type_index type = typeid(T); // Create an empty vector<> - vector> component_vector; + RefVector component_vector; if (this->components.find(type) == this->components.end()) return component_vector; @@ -114,14 +113,14 @@ ComponentManager::get_components_by_id(game_object_id_t id) const { } template -std::vector> ComponentManager::get_components_by_type() const { +RefVector ComponentManager::get_components_by_type() const { using namespace std; // Determine the type of T (this is used as the key of the unordered_map<>) type_index type = typeid(T); // Create an empty vector<> - vector> component_vector; + RefVector component_vector; // Find the type (in the unordered_map<>) if (this->components.find(type) == this->components.end()) return component_vector; diff --git a/src/crepe/api/Asset.cpp b/src/crepe/api/Asset.cpp index 3fe3ceb..e148367 100644 --- a/src/crepe/api/Asset.cpp +++ b/src/crepe/api/Asset.cpp @@ -2,9 +2,10 @@ #include #include -#include "Asset.h" #include "api/Config.h" +#include "Asset.h" + using namespace crepe; using namespace std; @@ -15,7 +16,7 @@ const string & Asset::get_path() const noexcept { return this->src; } string Asset::find_asset(const string & src) const { auto & cfg = Config::get_instance(); - auto & root_pattern = cfg.asset.root_pattern; + string & root_pattern = cfg.asset.root_pattern; // if root_pattern is empty, find_asset must return all paths as-is if (root_pattern.empty()) return src; diff --git a/src/crepe/api/Asset.h b/src/crepe/api/Asset.h index 77596ac..bfd0ac7 100644 --- a/src/crepe/api/Asset.h +++ b/src/crepe/api/Asset.h @@ -40,6 +40,22 @@ private: const std::string src; private: + /** + * \brief Locate asset path, or throw exception if it cannot be found + * + * This function resolves asset locations relative to crepe::Config::root_pattern if it is + * set and \p src is a relative path. If \p src is an absolute path, it is canonicalized. + * This function only returns if the file can be found. + * + * \param src Arbitrary path to resource file + * + * \returns \p src if crepe::Config::root_pattern is empty + * \returns Canonical path to \p src + * + * \throws std::runtime_error if root_pattern cannot be found + * \throws std::filesystem::filesystem_error if the resolved path does not exist + * \throws std::filesystem::filesystem_error if the path cannot be canonicalized + */ std::string find_asset(const std::string & src) const; /** * \returns The path to the current executable diff --git a/src/crepe/system/System.h b/src/crepe/system/System.h index 36f7edc..28ea20e 100644 --- a/src/crepe/system/System.h +++ b/src/crepe/system/System.h @@ -1,7 +1,5 @@ #pragma once -#include "../ComponentManager.h" - namespace crepe { class ComponentManager; diff --git a/src/crepe/util/OptionalRef.h b/src/crepe/util/OptionalRef.h index 0a94ae5..57f9635 100644 --- a/src/crepe/util/OptionalRef.h +++ b/src/crepe/util/OptionalRef.h @@ -36,7 +36,7 @@ public: * * \param ref Reference to assign */ - void set(T &) noexcept; + void set(T & ref) noexcept; /** * \brief Retrieve this reference * @@ -50,15 +50,6 @@ public: */ void clear() noexcept; - //! Copy constructor - OptionalRef(const OptionalRef &); - //! Move constructor - OptionalRef(OptionalRef &&); - //! Copy assignment - OptionalRef & operator=(const OptionalRef &); - //! Move assignment - OptionalRef & operator=(OptionalRef &&); - private: /** * \brief Reference to the value of type \c T diff --git a/src/crepe/util/OptionalRef.hpp b/src/crepe/util/OptionalRef.hpp index ee41f61..71e2a39 100644 --- a/src/crepe/util/OptionalRef.hpp +++ b/src/crepe/util/OptionalRef.hpp @@ -11,30 +11,6 @@ OptionalRef::OptionalRef(T & ref) { this->set(ref); } -template -OptionalRef::OptionalRef(const OptionalRef & other) { - this->ref = other.ref; -} - -template -OptionalRef::OptionalRef(OptionalRef && other) { - this->ref = other.ref; - other.clear(); -} - -template -OptionalRef & OptionalRef::operator=(const OptionalRef & other) { - this->ref = other.ref; - return *this; -} - -template -OptionalRef & OptionalRef::operator=(OptionalRef && other) { - this->ref = other.ref; - other.clear(); - return *this; -} - template T & OptionalRef::get() const { if (this->ref == nullptr) -- cgit v1.2.3 From d623b13dab63408cf5e99dbc453636f174bc6fe8 Mon Sep 17 00:00:00 2001 From: heavydemon21 Date: Wed, 20 Nov 2024 14:33:08 +0100 Subject: fixxed bug with particleemiiter and sprite in single component --- src/crepe/system/RenderSystem.cpp | 4 ++-- src/example/rendering_particle.cpp | 8 ++++++-- 2 files changed, 8 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/crepe/system/RenderSystem.cpp b/src/crepe/system/RenderSystem.cpp index 28bcf56..c137de1 100644 --- a/src/crepe/system/RenderSystem.cpp +++ b/src/crepe/system/RenderSystem.cpp @@ -36,10 +36,10 @@ bool RenderSystem::render_particle(const Sprite & sprite, const double & scale) bool rendering_particles = false; for (const ParticleEmitter & em : emitters) { + if (!(&em.data.sprite == &sprite)) continue; + rendering_particles = true; if (!em.active) continue; - if (!(em.data.sprite.game_object_id == sprite.game_object_id)) continue; - rendering_particles = true; for (const Particle & p : em.data.particles) { if (!p.active) continue; diff --git a/src/example/rendering_particle.cpp b/src/example/rendering_particle.cpp index 3f71750..bcf95b8 100644 --- a/src/example/rendering_particle.cpp +++ b/src/example/rendering_particle.cpp @@ -15,6 +15,7 @@ #include #include +#include using namespace crepe; using namespace std; @@ -26,10 +27,12 @@ int main(int argc, char * argv[]) { ParticleSystem psys{mgr}; Color color(255, 255, 255, 255); + game_object.add_component(make_shared("../asset/texture/img.png"), color, FlipSettings{false,false}); + Sprite test_sprite = game_object.add_component( make_shared("../asset/texture/img.png"), color, FlipSettings{false, false}); game_object.add_component(ParticleEmitter::Data{ - .position = {0, 0}, + .position = {100, 0}, .max_particles = 10, .emission_rate = 0.1, .min_speed = 6, @@ -46,9 +49,10 @@ int main(int argc, char * argv[]) { .reset_on_exit = false, }, .sprite = test_sprite, - }); + }).active = false; game_object.add_component(Color::get_white()); + auto start = std::chrono::steady_clock::now(); while (std::chrono::steady_clock::now() - start < std::chrono::seconds(5)) { psys.update(); -- cgit v1.2.3 From fb35ca64eee9afdd72f2cf8d279c4e745444baf9 Mon Sep 17 00:00:00 2001 From: Loek Le Blansch Date: Wed, 20 Nov 2024 14:51:26 +0100 Subject: `make format` --- src/test/ECSTest.cpp | 15 +++++++++------ src/test/SceneManagerTest.cpp | 10 ++++++---- 2 files changed, 15 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/test/ECSTest.cpp b/src/test/ECSTest.cpp index eaa2dbc..d5a5826 100644 --- a/src/test/ECSTest.cpp +++ b/src/test/ECSTest.cpp @@ -1,3 +1,5 @@ +#include + #define protected public #include @@ -5,7 +7,6 @@ #include #include #include -#include using namespace std; using namespace crepe; @@ -94,7 +95,7 @@ TEST_F(ECSTest, deleteGameObject) { } TEST_F(ECSTest, manyGameObjects) { - for(int i = 0; i < 5000; i++) { + for (int i = 0; i < 5000; i++) { GameObject obj = mgr.new_object("body", "person", Vector2{0, 0}, 0, i); } @@ -103,7 +104,7 @@ TEST_F(ECSTest, manyGameObjects) { EXPECT_EQ(metadata.size(), 5000); EXPECT_EQ(transform.size(), 5000); - for(int i = 0; i < 5000; i++) { + for (int i = 0; i < 5000; i++) { EXPECT_EQ(metadata[i].get().game_object_id, i); EXPECT_EQ(metadata[i].get().name, "body"); EXPECT_EQ(metadata[i].get().tag, "person"); @@ -125,7 +126,7 @@ TEST_F(ECSTest, manyGameObjects) { EXPECT_EQ(metadata.size(), 0); EXPECT_EQ(transform.size(), 5000); - for(int i = 0; i < 10000 - 5000; i++) { + for (int i = 0; i < 10000 - 5000; i++) { string tag = "person" + to_string(i); GameObject obj = mgr.new_object("body", tag, Vector2{0, 0}, i, 0); } @@ -165,14 +166,16 @@ TEST_F(ECSTest, tooMuchComponents) { GameObject obj0 = mgr.new_object("body", "person", Vector2{0, 0}, 0, 1); obj0.add_component(Vector2{10, 10}, 0, 1); } catch (const exception & e) { - EXPECT_EQ(e.what(), string("Exceeded maximum number of instances for this component type")); + EXPECT_EQ(e.what(), + string("Exceeded maximum number of instances for this component type")); } try { GameObject obj1 = mgr.new_object("body", "person", Vector2{0, 0}, 0, 1); obj1.add_component("body", "person"); } catch (const exception & e) { - EXPECT_EQ(e.what(), string("Exceeded maximum number of instances for this component type")); + EXPECT_EQ(e.what(), + string("Exceeded maximum number of instances for this component type")); } vector> metadata = mgr.get_components_by_type(); diff --git a/src/test/SceneManagerTest.cpp b/src/test/SceneManagerTest.cpp index 98b2a23..69e1171 100644 --- a/src/test/SceneManagerTest.cpp +++ b/src/test/SceneManagerTest.cpp @@ -1,10 +1,10 @@ #include #include #include -#include -#include #include #include +#include +#include #include using namespace std; @@ -47,8 +47,10 @@ TEST_F(SceneManagerTest, loadScene) { scene_mgr.load_next_scene(); - vector> metadata = component_mgr.get_components_by_type(); - vector> transform = component_mgr.get_components_by_type(); + vector> metadata + = component_mgr.get_components_by_type(); + vector> transform + = component_mgr.get_components_by_type(); EXPECT_EQ(metadata.size(), 3); EXPECT_EQ(transform.size(), 3); -- cgit v1.2.3 From e2c27d8c99a71e5d94ffe49027ec13afeb74b021 Mon Sep 17 00:00:00 2001 From: Loek Le Blansch Date: Wed, 20 Nov 2024 14:59:34 +0100 Subject: replace more vector> with RefVector --- src/crepe/api/GameObject.cpp | 6 ++---- src/crepe/api/Script.h | 2 +- src/crepe/api/Script.hpp | 5 ++--- src/crepe/system/AnimatorSystem.cpp | 5 +---- src/crepe/system/ParticleSystem.cpp | 3 +-- src/crepe/system/PhysicsSystem.cpp | 6 ++---- src/crepe/system/RenderSystem.cpp | 13 +++++-------- src/crepe/system/RenderSystem.h | 3 +-- src/crepe/system/ScriptSystem.cpp | 13 +++++-------- src/crepe/system/ScriptSystem.h | 6 +++--- 10 files changed, 23 insertions(+), 39 deletions(-) (limited to 'src') diff --git a/src/crepe/api/GameObject.cpp b/src/crepe/api/GameObject.cpp index 287e81d..4874426 100644 --- a/src/crepe/api/GameObject.cpp +++ b/src/crepe/api/GameObject.cpp @@ -23,12 +23,10 @@ void GameObject::set_parent(const GameObject & parent) { ComponentManager & mgr = this->component_manager; // Set parent on own Metadata component - vector> this_metadata - = mgr.get_components_by_id(this->id); + RefVector this_metadata = mgr.get_components_by_id(this->id); this_metadata.at(0).get().parent = parent.id; // Add own id to children list of parent's Metadata component - vector> parent_metadata - = mgr.get_components_by_id(parent.id); + RefVector parent_metadata = mgr.get_components_by_id(parent.id); parent_metadata.at(0).get().children.push_back(this->id); } diff --git a/src/crepe/api/Script.h b/src/crepe/api/Script.h index 2b70379..839d937 100644 --- a/src/crepe/api/Script.h +++ b/src/crepe/api/Script.h @@ -62,7 +62,7 @@ protected: * \returns List of component references */ template - std::vector> get_components() const; + RefVector get_components() const; protected: // NOTE: Script must have a constructor without arguments so the game programmer doesn't need diff --git a/src/crepe/api/Script.hpp b/src/crepe/api/Script.hpp index a064a90..a85d814 100644 --- a/src/crepe/api/Script.hpp +++ b/src/crepe/api/Script.hpp @@ -10,7 +10,7 @@ namespace crepe { template T & Script::get_component() const { using namespace std; - vector> all_components = this->get_components(); + RefVector all_components = this->get_components(); if (all_components.size() < 1) throw runtime_error( format("Script: no component found with type = {}", typeid(T).name())); @@ -19,9 +19,8 @@ T & Script::get_component() const { } template -std::vector> Script::get_components() const { +RefVector Script::get_components() const { auto & mgr = *this->component_manager_ref; - return mgr.get_components_by_id(this->game_object_id); } diff --git a/src/crepe/system/AnimatorSystem.cpp b/src/crepe/system/AnimatorSystem.cpp index 9d18873..676e485 100644 --- a/src/crepe/system/AnimatorSystem.cpp +++ b/src/crepe/system/AnimatorSystem.cpp @@ -1,6 +1,4 @@ #include -#include -#include #include "api/Animator.h" #include "facade/SDLContext.h" @@ -13,8 +11,7 @@ using namespace crepe; void AnimatorSystem::update() { ComponentManager & mgr = this->component_manager; - std::vector> animations - = mgr.get_components_by_type(); + RefVector animations = mgr.get_components_by_type(); uint64_t tick = SDLContext::get_instance().get_ticks(); for (Animator & a : animations) { diff --git a/src/crepe/system/ParticleSystem.cpp b/src/crepe/system/ParticleSystem.cpp index 7316309..fcf7522 100644 --- a/src/crepe/system/ParticleSystem.cpp +++ b/src/crepe/system/ParticleSystem.cpp @@ -14,8 +14,7 @@ using namespace crepe; void ParticleSystem::update() { // Get all emitters ComponentManager & mgr = this->component_manager; - std::vector> emitters - = mgr.get_components_by_type(); + RefVector emitters = mgr.get_components_by_type(); for (ParticleEmitter & emitter : emitters) { // Get transform linked to emitter diff --git a/src/crepe/system/PhysicsSystem.cpp b/src/crepe/system/PhysicsSystem.cpp index 4a7dbfb..bcde431 100644 --- a/src/crepe/system/PhysicsSystem.cpp +++ b/src/crepe/system/PhysicsSystem.cpp @@ -12,10 +12,8 @@ using namespace crepe; void PhysicsSystem::update() { ComponentManager & mgr = this->component_manager; - std::vector> rigidbodies - = mgr.get_components_by_type(); - std::vector> transforms - = mgr.get_components_by_type(); + RefVector rigidbodies = mgr.get_components_by_type(); + RefVector transforms = mgr.get_components_by_type(); double gravity = Config::get_instance().physics.gravity; for (Rigidbody & rigidbody : rigidbodies) { diff --git a/src/crepe/system/RenderSystem.cpp b/src/crepe/system/RenderSystem.cpp index 96c5f27..7ee03e5 100644 --- a/src/crepe/system/RenderSystem.cpp +++ b/src/crepe/system/RenderSystem.cpp @@ -1,6 +1,5 @@ #include #include -#include #include #include @@ -20,7 +19,7 @@ void RenderSystem::present_screen() { this->context.present_screen(); } void RenderSystem::update_camera() { ComponentManager & mgr = this->component_manager; - std::vector> cameras = mgr.get_components_by_type(); + RefVector cameras = mgr.get_components_by_type(); if (cameras.size() == 0) throw std::runtime_error("No cameras in current scene"); @@ -37,10 +36,8 @@ bool sorting_comparison(const Sprite & a, const Sprite & b) { return false; } -std::vector> -RenderSystem::sort(std::vector> & objs) { - - std::vector> sorted_objs(objs); +RefVector RenderSystem::sort(RefVector & objs) { + RefVector sorted_objs(objs); std::sort(sorted_objs.begin(), sorted_objs.end(), sorting_comparison); return sorted_objs; @@ -48,8 +45,8 @@ RenderSystem::sort(std::vector> & objs) { void RenderSystem::render_sprites() { ComponentManager & mgr = this->component_manager; - vector> sprites = mgr.get_components_by_type(); - vector> sorted_sprites = this->sort(sprites); + RefVector sprites = mgr.get_components_by_type(); + RefVector sorted_sprites = this->sort(sprites); for (const Sprite & sprite : sorted_sprites) { auto transforms = mgr.get_components_by_id(sprite.game_object_id); diff --git a/src/crepe/system/RenderSystem.h b/src/crepe/system/RenderSystem.h index 57b9c73..40978ae 100644 --- a/src/crepe/system/RenderSystem.h +++ b/src/crepe/system/RenderSystem.h @@ -47,8 +47,7 @@ private: * \param objs the vector that will do a sorting algorithm on * \return returns a sorted reference vector */ - std::vector> - sort(std::vector> & objs); + RefVector sort(RefVector & objs); /** * \todo Include color handling for sprites. diff --git a/src/crepe/system/ScriptSystem.cpp b/src/crepe/system/ScriptSystem.cpp index c4d724c..c33309c 100644 --- a/src/crepe/system/ScriptSystem.cpp +++ b/src/crepe/system/ScriptSystem.cpp @@ -1,6 +1,4 @@ -#include #include -#include #include "../ComponentManager.h" #include "../api/BehaviorScript.h" @@ -14,7 +12,7 @@ using namespace crepe; void ScriptSystem::update() { dbg_trace(); - forward_list> scripts = this->get_scripts(); + RefVector