From 770496ee9d0e45480c0e0f8951adb8eee247bfe1 Mon Sep 17 00:00:00 2001 From: Loek Le Blansch Date: Tue, 10 Dec 2024 19:50:26 +0100 Subject: big WIP --- src/test/AudioTest.cpp | 28 ++++++++++++++-------------- src/test/CMakeLists.txt | 1 + src/test/CollisionTest.cpp | 26 +++++++++++++------------- src/test/InputTest.cpp | 20 ++++++++++---------- src/test/ParticleTest.cpp | 18 +++++++++--------- src/test/PhysicsTest.cpp | 16 ++++++++-------- src/test/Profiling.cpp | 16 ++++++++-------- src/test/RenderSystemTest.cpp | 6 +++--- src/test/ReplayManagerTest.cpp | 36 ++++++++++++++++++++++++++++++++++++ src/test/ScriptEventTest.cpp | 2 +- src/test/ScriptTest.cpp | 8 ++++---- 11 files changed, 107 insertions(+), 70 deletions(-) create mode 100644 src/test/ReplayManagerTest.cpp (limited to 'src/test') diff --git a/src/test/AudioTest.cpp b/src/test/AudioTest.cpp index 48bba1b..415a12e 100644 --- a/src/test/AudioTest.cpp +++ b/src/test/AudioTest.cpp @@ -50,11 +50,11 @@ TEST_F(AudioTest, Default) { EXPECT_CALL(context, stop(_)).Times(0); EXPECT_CALL(context, set_volume(_, _)).Times(0); EXPECT_CALL(context, set_loop(_, _)).Times(0); - system.update(); + system.fixed_update(); } TEST_F(AudioTest, Play) { - system.update(); + system.fixed_update(); { InSequence seq; @@ -67,12 +67,12 @@ TEST_F(AudioTest, Play) { InSequence seq; EXPECT_CALL(context, play(_)).Times(1); - system.update(); + system.fixed_update(); } } TEST_F(AudioTest, Stop) { - system.update(); + system.fixed_update(); { InSequence seq; @@ -85,12 +85,12 @@ TEST_F(AudioTest, Stop) { InSequence seq; EXPECT_CALL(context, stop(_)).Times(1); - system.update(); + system.fixed_update(); } } TEST_F(AudioTest, Volume) { - system.update(); + system.fixed_update(); { InSequence seq; @@ -103,12 +103,12 @@ TEST_F(AudioTest, Volume) { InSequence seq; EXPECT_CALL(context, set_volume(_, component.volume)).Times(1); - system.update(); + system.fixed_update(); } } TEST_F(AudioTest, Looping) { - system.update(); + system.fixed_update(); { InSequence seq; @@ -121,33 +121,33 @@ TEST_F(AudioTest, Looping) { InSequence seq; EXPECT_CALL(context, set_loop(_, component.loop)).Times(1); - system.update(); + system.fixed_update(); } } TEST_F(AudioTest, StopOnDeactivate) { - system.update(); + system.fixed_update(); { InSequence seq; EXPECT_CALL(context, stop(_)).Times(1); component.active = false; - system.update(); + system.fixed_update(); } } TEST_F(AudioTest, PlayOnActive) { component.active = false; component.play_on_awake = true; - system.update(); + system.fixed_update(); { InSequence seq; EXPECT_CALL(context, play(_)).Times(1); component.active = true; - system.update(); + system.fixed_update(); } } @@ -157,5 +157,5 @@ TEST_F(AudioTest, PlayImmediately) { EXPECT_CALL(context, play(_)).Times(1); - system.update(); + system.fixed_update(); } diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt index ef7b5c6..a0bb56d 100644 --- a/src/test/CMakeLists.txt +++ b/src/test/CMakeLists.txt @@ -20,4 +20,5 @@ target_sources(test_main PUBLIC ScriptSceneTest.cpp Profiling.cpp ScriptECSTest.cpp + ReplayManagerTest.cpp ) diff --git a/src/test/CollisionTest.cpp b/src/test/CollisionTest.cpp index dd45eb6..0607128 100644 --- a/src/test/CollisionTest.cpp +++ b/src/test/CollisionTest.cpp @@ -106,7 +106,7 @@ public: ASSERT_NE(script_object2_ref, nullptr); // Ensure Script::init() is called on all BehaviorScript instances - script_sys.update(); + script_sys.fixed_update(); } }; @@ -121,7 +121,7 @@ TEST_F(CollisionTest, collision_example) { EXPECT_EQ(ev.info.this_collider.game_object_id, 2); }; EXPECT_FALSE(collision_happend); - collision_sys.update(); + collision_sys.fixed_update(); EXPECT_FALSE(collision_happend); } @@ -144,7 +144,7 @@ TEST_F(CollisionTest, collision_box_box_dynamic_both_no_velocity) { EXPECT_FALSE(collision_happend); Transform & tf = this->mgr.get_components_by_id(1).front().get(); tf.position = {50, 30}; - collision_sys.update(); + collision_sys.fixed_update(); EXPECT_TRUE(collision_happend); } @@ -169,7 +169,7 @@ TEST_F(CollisionTest, collision_box_box_dynamic_x_direction_no_velocity) { EXPECT_FALSE(collision_happend); Transform & tf = this->mgr.get_components_by_id(1).front().get(); tf.position = {45, 30}; - collision_sys.update(); + collision_sys.fixed_update(); EXPECT_TRUE(collision_happend); } @@ -194,7 +194,7 @@ TEST_F(CollisionTest, collision_box_box_dynamic_y_direction_no_velocity) { EXPECT_FALSE(collision_happend); Transform & tf = this->mgr.get_components_by_id(1).front().get(); tf.position = {50, 25}; - collision_sys.update(); + collision_sys.fixed_update(); EXPECT_TRUE(collision_happend); } @@ -221,7 +221,7 @@ TEST_F(CollisionTest, collision_box_box_dynamic_both) { rg1.data.linear_velocity = {10, 10}; Rigidbody & rg2 = this->mgr.get_components_by_id(2).front().get(); rg2.data.linear_velocity = {10, 10}; - collision_sys.update(); + collision_sys.fixed_update(); EXPECT_TRUE(collision_happend); } @@ -250,7 +250,7 @@ TEST_F(CollisionTest, collision_box_box_dynamic_x_direction) { rg1.data.linear_velocity = {10, 10}; Rigidbody & rg2 = this->mgr.get_components_by_id(2).front().get(); rg2.data.linear_velocity = {10, 10}; - collision_sys.update(); + collision_sys.fixed_update(); EXPECT_TRUE(collision_happend); } @@ -279,7 +279,7 @@ TEST_F(CollisionTest, collision_box_box_dynamic_y_direction) { rg1.data.linear_velocity = {10, 10}; Rigidbody & rg2 = this->mgr.get_components_by_id(2).front().get(); rg2.data.linear_velocity = {10, 10}; - collision_sys.update(); + collision_sys.fixed_update(); EXPECT_TRUE(collision_happend); } @@ -301,7 +301,7 @@ TEST_F(CollisionTest, collision_box_box_static_both) { tf.position = {50, 30}; Rigidbody & rg2 = this->mgr.get_components_by_id(2).front().get(); rg2.data.body_type = crepe::Rigidbody::BodyType::STATIC; - collision_sys.update(); + collision_sys.fixed_update(); EXPECT_TRUE(collision_happend); } @@ -326,7 +326,7 @@ TEST_F(CollisionTest, collision_box_box_static_x_direction) { rg1.data.linear_velocity = {10, 10}; Rigidbody & rg2 = this->mgr.get_components_by_id(2).front().get(); rg2.data.body_type = crepe::Rigidbody::BodyType::STATIC; - collision_sys.update(); + collision_sys.fixed_update(); EXPECT_TRUE(collision_happend); } @@ -351,7 +351,7 @@ TEST_F(CollisionTest, collision_box_box_static_y_direction) { rg1.data.linear_velocity = {10, 10}; Rigidbody & rg2 = this->mgr.get_components_by_id(2).front().get(); rg2.data.body_type = crepe::Rigidbody::BodyType::STATIC; - collision_sys.update(); + collision_sys.fixed_update(); EXPECT_TRUE(collision_happend); } @@ -381,10 +381,10 @@ TEST_F(CollisionTest, collision_box_box_static_multiple) { //todo check visually this->game_object1.add_component(vec2{-5, 0}, vec2{10, 10}); offset_value = 5; resolution = 10; - collision_sys.update(); + collision_sys.fixed_update(); offset_value = -5; resolution = 10; tf.position = {55, 30}; - collision_sys.update(); + collision_sys.fixed_update(); EXPECT_TRUE(collision_happend); } diff --git a/src/test/InputTest.cpp b/src/test/InputTest.cpp index 73eaab3..8c42c43 100644 --- a/src/test/InputTest.cpp +++ b/src/test/InputTest.cpp @@ -83,7 +83,7 @@ TEST_F(InputTest, MouseDown) { event.button.button = SDL_BUTTON_LEFT; SDL_PushEvent(&event); - input_system.update(); + input_system.fixed_update(); event_manager.dispatch_events(); EXPECT_TRUE(mouse_triggered); } @@ -111,7 +111,7 @@ TEST_F(InputTest, MouseUp) { event.button.button = SDL_BUTTON_LEFT; SDL_PushEvent(&event); - input_system.update(); + input_system.fixed_update(); event_manager.dispatch_events(); EXPECT_TRUE(function_triggered); } @@ -141,7 +141,7 @@ TEST_F(InputTest, MouseMove) { event.motion.yrel = 10; SDL_PushEvent(&event); - input_system.update(); + input_system.fixed_update(); event_manager.dispatch_events(); EXPECT_TRUE(function_triggered); } @@ -171,7 +171,7 @@ TEST_F(InputTest, KeyDown) { test_event.key.repeat = 1; // Set repeat flag SDL_PushEvent(&test_event); - input_system.update(); // Process the event + input_system.fixed_update(); // Process the event event_manager.dispatch_events(); // Dispatch events to handlers EXPECT_TRUE(function_triggered); // Check if the handler was triggered @@ -196,7 +196,7 @@ TEST_F(InputTest, KeyUp) { event.key.keysym.scancode = SDL_SCANCODE_B; SDL_PushEvent(&event); - input_system.update(); + input_system.fixed_update(); event_manager.dispatch_events(); EXPECT_TRUE(function_triggered); } @@ -217,7 +217,7 @@ TEST_F(InputTest, MouseClick) { event_manager.subscribe(on_mouse_click); this->simulate_mouse_click(250, 250, SDL_BUTTON_LEFT); - input_system.update(); + input_system.fixed_update(); event_manager.dispatch_events(); EXPECT_TRUE(on_click_triggered); } @@ -239,12 +239,12 @@ TEST_F(InputTest, testButtonClick) { button.is_pressed = false; button.is_toggle = false; this->simulate_mouse_click(999, 999, SDL_BUTTON_LEFT); - input_system.update(); + input_system.fixed_update(); event_manager.dispatch_events(); EXPECT_FALSE(button_clicked); this->simulate_mouse_click(250, 250, SDL_BUTTON_LEFT); - input_system.update(); + input_system.fixed_update(); event_manager.dispatch_events(); EXPECT_TRUE(button_clicked); } @@ -273,7 +273,7 @@ TEST_F(InputTest, testButtonHover) { event.motion.yrel = 10; SDL_PushEvent(&event); - input_system.update(); + input_system.fixed_update(); event_manager.dispatch_events(); EXPECT_FALSE(button.hover); @@ -287,7 +287,7 @@ TEST_F(InputTest, testButtonHover) { hover_event.motion.yrel = 10; SDL_PushEvent(&hover_event); - input_system.update(); + input_system.fixed_update(); event_manager.dispatch_events(); EXPECT_TRUE(button.hover); } diff --git a/src/test/ParticleTest.cpp b/src/test/ParticleTest.cpp index 1409c4f..c2a3c14 100644 --- a/src/test/ParticleTest.cpp +++ b/src/test/ParticleTest.cpp @@ -93,18 +93,18 @@ TEST_F(ParticlesTest, spawnParticle) { emitter.data.max_angle = 0.1; emitter.data.max_speed = 10; emitter.data.max_angle = 10; - particle_system.update(); + particle_system.frame_update(); //check if nothing happend EXPECT_EQ(emitter.data.particles[0].active, false); emitter.data.emission_rate = 1; //check particle spawnes - particle_system.update(); + particle_system.frame_update(); EXPECT_EQ(emitter.data.particles[0].active, true); - particle_system.update(); + particle_system.frame_update(); EXPECT_EQ(emitter.data.particles[1].active, true); - particle_system.update(); + particle_system.frame_update(); EXPECT_EQ(emitter.data.particles[2].active, true); - particle_system.update(); + particle_system.frame_update(); EXPECT_EQ(emitter.data.particles[3].active, true); for (auto & particle : emitter.data.particles) { @@ -138,7 +138,7 @@ TEST_F(ParticlesTest, moveParticleHorizontal) { emitter.data.max_angle = 0; emitter.data.emission_rate = 1; for (int a = 1; a < emitter.data.boundary.width / 2; a++) { - particle_system.update(); + particle_system.frame_update(); EXPECT_EQ(emitter.data.particles[0].position.x, a); } } @@ -156,7 +156,7 @@ TEST_F(ParticlesTest, moveParticleVertical) { emitter.data.max_angle = 90; emitter.data.emission_rate = 1; for (int a = 1; a < emitter.data.boundary.width / 2; a++) { - particle_system.update(); + particle_system.frame_update(); EXPECT_EQ(emitter.data.particles[0].position.y, a); } } @@ -175,7 +175,7 @@ TEST_F(ParticlesTest, boundaryParticleReset) { emitter.data.max_angle = 90; emitter.data.emission_rate = 1; for (int a = 0; a < emitter.data.boundary.width / 2 + 1; a++) { - particle_system.update(); + particle_system.frame_update(); } EXPECT_EQ(emitter.data.particles[0].active, false); } @@ -194,7 +194,7 @@ TEST_F(ParticlesTest, boundaryParticleStop) { emitter.data.max_angle = 90; emitter.data.emission_rate = 1; for (int a = 0; a < emitter.data.boundary.width / 2 + 1; a++) { - particle_system.update(); + particle_system.frame_update(); } const double TOLERANCE = 0.01; EXPECT_NEAR(emitter.data.particles[0].velocity.x, 0, TOLERANCE); diff --git a/src/test/PhysicsTest.cpp b/src/test/PhysicsTest.cpp index 43d2931..7bd7626 100644 --- a/src/test/PhysicsTest.cpp +++ b/src/test/PhysicsTest.cpp @@ -54,10 +54,10 @@ TEST_F(PhysicsTest, gravity) { ASSERT_FALSE(transforms.empty()); EXPECT_EQ(transform.position.y, 0); - system.update(); + system.fixed_update(); EXPECT_EQ(transform.position.y, 1); - system.update(); + system.fixed_update(); EXPECT_EQ(transform.position.y, 3); } @@ -70,14 +70,14 @@ TEST_F(PhysicsTest, max_velocity) { rigidbody.add_force_linear({100, 100}); rigidbody.add_force_angular(100); - system.update(); + system.fixed_update(); EXPECT_EQ(rigidbody.data.linear_velocity.y, 10); EXPECT_EQ(rigidbody.data.linear_velocity.x, 10); EXPECT_EQ(rigidbody.data.angular_velocity, 10); rigidbody.add_force_linear({-100, -100}); rigidbody.add_force_angular(-100); - system.update(); + system.fixed_update(); EXPECT_EQ(rigidbody.data.linear_velocity.y, -10); EXPECT_EQ(rigidbody.data.linear_velocity.x, -10); EXPECT_EQ(rigidbody.data.angular_velocity, -10); @@ -95,7 +95,7 @@ TEST_F(PhysicsTest, movement) { rigidbody.add_force_linear({1, 1}); rigidbody.add_force_angular(1); - system.update(); + system.fixed_update(); EXPECT_EQ(transform.position.x, 1); EXPECT_EQ(transform.position.y, 1); EXPECT_EQ(transform.rotation, 1); @@ -108,7 +108,7 @@ TEST_F(PhysicsTest, movement) { rigidbody.data.linear_velocity_coefficient.x = 0.5; rigidbody.data.linear_velocity_coefficient.y = 0.5; rigidbody.data.angular_velocity_coefficient = 0.5; - system.update(); + system.fixed_update(); EXPECT_EQ(rigidbody.data.linear_velocity.x, 0.5); EXPECT_EQ(rigidbody.data.linear_velocity.y, 0.5); EXPECT_EQ(rigidbody.data.angular_velocity, 0.5); @@ -117,10 +117,10 @@ TEST_F(PhysicsTest, movement) { rigidbody.data.angular_velocity_coefficient = 0; rigidbody.data.max_angular_velocity = 1000; rigidbody.data.angular_velocity = 360; - system.update(); + system.fixed_update(); EXPECT_EQ(transform.rotation, 1); rigidbody.data.angular_velocity = -360; - system.update(); + system.fixed_update(); EXPECT_EQ(transform.rotation, 1); } diff --git a/src/test/Profiling.cpp b/src/test/Profiling.cpp index c753bca..3f48ced 100644 --- a/src/test/Profiling.cpp +++ b/src/test/Profiling.cpp @@ -36,7 +36,7 @@ class TestScript : public Script { subscribe( [this](const CollisionEvent & ev) -> bool { return this->oncollision(ev); }); } - void update() { + void fixed_update() { // Retrieve component from the same GameObject this script is on } }; @@ -77,9 +77,9 @@ public: }); // initialize systems here: //calls init - script_sys.update(); + script_sys.fixed_update(); //creates window - render_sys.update(); + render_sys.frame_update(); } // Helper function to time an update call and store its duration @@ -97,12 +97,12 @@ public: // Run and profile all systems, return the total time in milliseconds std::chrono::microseconds run_all_systems() { std::chrono::microseconds total_microseconds = 0us; - total_microseconds += time_function("PhysicsSystem", [&]() { physics_sys.update(); }); + total_microseconds += time_function("PhysicsSystem", [&]() { physics_sys.fixed_update(); }); total_microseconds - += time_function("CollisionSystem", [&]() { collision_sys.update(); }); + += time_function("CollisionSystem", [&]() { collision_sys.fixed_update(); }); total_microseconds - += time_function("ParticleSystem", [&]() { particle_sys.update(); }); - total_microseconds += time_function("RenderSystem", [&]() { render_sys.update(); }); + += time_function("ParticleSystem", [&]() { particle_sys.fixed_update(); }); + total_microseconds += time_function("RenderSystem", [&]() { render_sys.frame_update(); }); return total_microseconds; } @@ -227,7 +227,7 @@ TEST_F(DISABLED_ProfilingTest, Profiling_3) { .sprite = test_sprite, }); } - render_sys.update(); + render_sys.frame_update(); this->game_object_count++; this->total_time = 0us; diff --git a/src/test/RenderSystemTest.cpp b/src/test/RenderSystemTest.cpp index 205f534..b2c54b9 100644 --- a/src/test/RenderSystemTest.cpp +++ b/src/test/RenderSystemTest.cpp @@ -99,7 +99,7 @@ TEST_F(RenderSystemTest, expected_throws) { }); // No camera - EXPECT_ANY_THROW({ this->sys.update(); }); + EXPECT_ANY_THROW({ this->sys.frame_update(); }); } TEST_F(RenderSystemTest, make_sprites) {} @@ -153,7 +153,7 @@ TEST_F(RenderSystemTest, Update) { EXPECT_EQ(sprites[2].get().game_object_id, 2); EXPECT_EQ(sprites[3].get().game_object_id, 3); } - this->sys.update(); + this->sys.frame_update(); { vector> sprites = this->mgr.get_components_by_type(); ASSERT_EQ(sprites.size(), 4); @@ -192,7 +192,7 @@ TEST_F(RenderSystemTest, Color) { EXPECT_EQ(sprite.data.color.g, Color::GREEN.g); EXPECT_EQ(sprite.data.color.b, Color::GREEN.b); EXPECT_EQ(sprite.data.color.a, Color::GREEN.a); - this->sys.update(); + this->sys.frame_update(); EXPECT_EQ(sprite.data.color.r, Color::GREEN.r); EXPECT_EQ(sprite.data.color.g, Color::GREEN.g); EXPECT_EQ(sprite.data.color.b, Color::GREEN.b); diff --git a/src/test/ReplayManagerTest.cpp b/src/test/ReplayManagerTest.cpp new file mode 100644 index 0000000..aa5a766 --- /dev/null +++ b/src/test/ReplayManagerTest.cpp @@ -0,0 +1,36 @@ +#include + +#include +#include +#include +#include +#include + +using namespace std; +using namespace crepe; +using namespace testing; + +class ReplayManagerTest : public Test { + Mediator mediator; +public: + ComponentManager component_manager{mediator}; + ReplayManager replay_manager{mediator}; + ReplaySystem replay_system{mediator}; + + GameObject entity = component_manager.new_object("foo"); + Transform & entity_transform = component_manager.get_components_by_id(entity.id).back(); + Metadata & entity_metadata = component_manager.get_components_by_id(entity.id).back(); +}; + +TEST_F(ReplayManagerTest, Default) { + // replay_manager.record_start(); + + // replay_system.fixed_update(); + // entity_transform.position += {1, 1}; + // replay_system.fixed_update(); + // entity_transform.position += {1, 1}; + // replay_system.fixed_update(); + + // recording_t recording = replay_manager.record_end(); +} + diff --git a/src/test/ScriptEventTest.cpp b/src/test/ScriptEventTest.cpp index c1b4028..479e3f5 100644 --- a/src/test/ScriptEventTest.cpp +++ b/src/test/ScriptEventTest.cpp @@ -37,7 +37,7 @@ TEST_F(ScriptEventTest, Default) { return true; }); - system.update(); + system.fixed_update(); behaviorscript.active = false; EXPECT_EQ(0, event_count); diff --git a/src/test/ScriptTest.cpp b/src/test/ScriptTest.cpp index acdae70..ccf5060 100644 --- a/src/test/ScriptTest.cpp +++ b/src/test/ScriptTest.cpp @@ -39,7 +39,7 @@ TEST_F(ScriptTest, UpdateOnce) { EXPECT_CALL(script, init()).Times(1); EXPECT_CALL(script, update()).Times(1); - system.update(); + system.fixed_update(); } { @@ -47,7 +47,7 @@ TEST_F(ScriptTest, UpdateOnce) { EXPECT_CALL(script, init()).Times(0); EXPECT_CALL(script, update()).Times(1); - system.update(); + system.fixed_update(); } } @@ -61,7 +61,7 @@ TEST_F(ScriptTest, UpdateInactive) { EXPECT_CALL(script, init()).Times(0); EXPECT_CALL(script, update()).Times(0); behaviorscript.active = false; - system.update(); + system.fixed_update(); } { @@ -70,6 +70,6 @@ TEST_F(ScriptTest, UpdateInactive) { EXPECT_CALL(script, init()).Times(1); EXPECT_CALL(script, update()).Times(1); behaviorscript.active = true; - system.update(); + system.fixed_update(); } } -- cgit v1.2.3 From 359ad8db97305856f4cfdade1cd1dada78a7a635 Mon Sep 17 00:00:00 2001 From: Loek Le Blansch Date: Wed, 11 Dec 2024 21:04:30 +0100 Subject: more replay system WIP --- src/crepe/Component.cpp | 9 +++++ src/crepe/Component.h | 13 ++++--- src/crepe/api/GameObject.cpp | 10 ++--- src/crepe/api/GameObject.h | 13 +++++-- src/crepe/api/LoopManager.cpp | 2 + src/crepe/api/Transform.cpp | 10 +++++ src/crepe/api/Transform.h | 7 ++++ src/crepe/manager/ComponentManager.cpp | 26 +++++++++++++ src/crepe/manager/ComponentManager.h | 9 ++++- src/crepe/manager/Mediator.h | 2 + src/crepe/manager/ReplayManager.cpp | 25 ++++++------ src/crepe/manager/ReplayManager.h | 24 ++++++++---- src/crepe/system/ReplaySystem.cpp | 70 ++++++++++++++++++++++++++++++++++ src/crepe/system/ReplaySystem.h | 11 ++++++ src/test/ECSTest.cpp | 14 +++++++ 15 files changed, 209 insertions(+), 36 deletions(-) (limited to 'src/test') diff --git a/src/crepe/Component.cpp b/src/crepe/Component.cpp index 141e1a8..8086492 100644 --- a/src/crepe/Component.cpp +++ b/src/crepe/Component.cpp @@ -1,6 +1,7 @@ #include "Component.h" using namespace crepe; +using namespace std; Component::Component(game_object_id_t id) : game_object_id(id) {} @@ -8,3 +9,11 @@ Component & Component::operator=(const Component &) { return *this; } +unique_ptr Component::save() const { + return unique_ptr(new Component(*this)); +} + +void Component::restore(const Component & snapshot) { + *this = snapshot; +} + diff --git a/src/crepe/Component.h b/src/crepe/Component.h index 47c5c34..fc0268c 100644 --- a/src/crepe/Component.h +++ b/src/crepe/Component.h @@ -1,5 +1,7 @@ #pragma once +#include + #include "types.h" namespace crepe { @@ -32,15 +34,16 @@ protected: //! Only ComponentManager can create components friend class ComponentManager; - // create snapshot - Component(const Component &) = default; - // restore snapshot - virtual Component & operator=(const Component &); - // components are never moved Component(Component &&) = delete; virtual Component & operator=(Component &&) = delete; +protected: + virtual std::unique_ptr save() const; + Component(const Component &) = default; + virtual void restore(const Component & snapshot); + virtual Component & operator=(const Component &); + public: virtual ~Component() = default; diff --git a/src/crepe/api/GameObject.cpp b/src/crepe/api/GameObject.cpp index ea9c425..68b074e 100644 --- a/src/crepe/api/GameObject.cpp +++ b/src/crepe/api/GameObject.cpp @@ -11,13 +11,9 @@ GameObject::GameObject(Mediator & mediator, game_object_id_t id, const std::string & name, const std::string & tag, const vec2 & position, double rotation, double scale) : id(id), - mediator(mediator) { - - // Add Transform and Metadata components - ComponentManager & mgr = this->mediator.component_manager; - mgr.add_component(this->id, position, rotation, scale); - mgr.add_component(this->id, name, tag); -} + mediator(mediator), + transform(mediator.component_manager->add_component(this->id, position, rotation, scale)), + metadata(mediator.component_manager->add_component(this->id, name, tag)) { } void GameObject::set_parent(const GameObject & parent) { ComponentManager & mgr = this->mediator.component_manager; diff --git a/src/crepe/api/GameObject.h b/src/crepe/api/GameObject.h index a311c21..6203f81 100644 --- a/src/crepe/api/GameObject.h +++ b/src/crepe/api/GameObject.h @@ -7,6 +7,8 @@ namespace crepe { class Mediator; +class Transform; +class Metadata; /** * \brief Represents a GameObject @@ -34,6 +36,13 @@ private: //! ComponentManager instances GameObject friend class ComponentManager; +public: + //! The id of the GameObject + const game_object_id_t id; + + Transform & transform; + Metadata & metadata; + public: /** * \brief Set the parent of this GameObject @@ -68,10 +77,6 @@ public: */ void set_persistent(bool persistent = true); -public: - //! The id of the GameObject - const game_object_id_t id; - protected: Mediator & mediator; }; diff --git a/src/crepe/api/LoopManager.cpp b/src/crepe/api/LoopManager.cpp index 3511bca..2855455 100644 --- a/src/crepe/api/LoopManager.cpp +++ b/src/crepe/api/LoopManager.cpp @@ -25,6 +25,8 @@ LoopManager::LoopManager() { this->load_system(); this->load_system(); this->load_system(); + + this->mediator.loop_manager = *this; } void LoopManager::start() { diff --git a/src/crepe/api/Transform.cpp b/src/crepe/api/Transform.cpp index a85b792..5fc886b 100644 --- a/src/crepe/api/Transform.cpp +++ b/src/crepe/api/Transform.cpp @@ -3,6 +3,7 @@ #include "Transform.h" using namespace crepe; +using namespace std; Transform::Transform(game_object_id_t id, const vec2 & point, double rotation, double scale) : Component(id), @@ -11,3 +12,12 @@ Transform::Transform(game_object_id_t id, const vec2 & point, double rotation, d scale(scale) { dbg_trace(); } + +unique_ptr Transform::save() const { + return unique_ptr{new Transform(*this)}; +} + +void Transform::restore(const Component & snapshot) { + *this = static_cast(snapshot); +} + diff --git a/src/crepe/api/Transform.h b/src/crepe/api/Transform.h index 7ee6d65..bbd23e0 100644 --- a/src/crepe/api/Transform.h +++ b/src/crepe/api/Transform.h @@ -35,6 +35,13 @@ protected: virtual int get_instances_max() const { return 1; } //! ComponentManager instantiates all components friend class ComponentManager; + +protected: + virtual std::unique_ptr save() const; + Transform(const Transform &) = default; + virtual void restore(const Component & snapshot); + virtual Transform & operator=(const Transform &) = default; + }; } // namespace crepe diff --git a/src/crepe/manager/ComponentManager.cpp b/src/crepe/manager/ComponentManager.cpp index 24ba0d7..5f5c050 100644 --- a/src/crepe/manager/ComponentManager.cpp +++ b/src/crepe/manager/ComponentManager.cpp @@ -72,3 +72,29 @@ set ComponentManager::get_objects_by_tag(const string & tag) c return this->get_objects_by_predicate( [tag](const Metadata & data) { return data.tag == tag; }); } + +ComponentManager::Snapshot ComponentManager::save() { + Snapshot snapshot{}; + for (const auto & [type, by_id_index] : this->components) { + for (game_object_id_t id = 0; id < by_id_index.size(); id++) { + const auto & components = by_id_index[id]; + for (size_t index = 0; index < components.size(); index++) { + const Component & component = *components[index]; + snapshot.components.push_back(SnapshotComponent{ + .type = type, + .id = id, + .index = index, + .component = component.save(), + }); + } + } + } + return snapshot; +} + +void ComponentManager::restore(const Snapshot & snapshot) { + for (const SnapshotComponent & info : snapshot.components) { + this->components[info.type][info.id][info.index]->restore(*info.component); + } +} + diff --git a/src/crepe/manager/ComponentManager.h b/src/crepe/manager/ComponentManager.h index dd7c154..457a196 100644 --- a/src/crepe/manager/ComponentManager.h +++ b/src/crepe/manager/ComponentManager.h @@ -143,10 +143,15 @@ public: RefVector get_components_by_tag(const std::string & tag) const; struct SnapshotComponent { - Component component; + std::type_index type; + game_object_id_t id; + size_t index; + std::unique_ptr component; }; struct Snapshot { - + // TODO: some kind of hash code that ensures components exist in all the same places as + // this snapshot + std::vector components; }; Snapshot save(); void restore(const Snapshot &); diff --git a/src/crepe/manager/Mediator.h b/src/crepe/manager/Mediator.h index eef4432..f5864e7 100644 --- a/src/crepe/manager/Mediator.h +++ b/src/crepe/manager/Mediator.h @@ -14,6 +14,7 @@ class ResourceManager; class SDLContext; class LoopTimer; class ReplayManager; +class LoopManager; /** * Struct to pass references to classes that would otherwise need to be singletons down to @@ -36,6 +37,7 @@ struct Mediator { OptionalRef resource_manager; OptionalRef timer; OptionalRef replay_manager; + OptionalRef loop_manager; }; } // namespace crepe diff --git a/src/crepe/manager/ReplayManager.cpp b/src/crepe/manager/ReplayManager.cpp index 82c2275..81ff114 100644 --- a/src/crepe/manager/ReplayManager.cpp +++ b/src/crepe/manager/ReplayManager.cpp @@ -1,4 +1,4 @@ -#include "../util/Log.h" +#include #include "ReplayManager.h" #include "Manager.h" @@ -11,26 +11,29 @@ ReplayManager::ReplayManager(Mediator & mediator) : Manager(mediator) { } void ReplayManager::record_start() { - if (this->recording) this->release(this->current_recording); - this->current_recording++; - this->recording = true; + if (this->state == RECORDING) this->release(this->id); + this->id++; + this->memory[this->id] = make_unique(); + this->recording = *this->memory.at(this->id); + this->state = RECORDING; } recording_t ReplayManager::record_end() { - this->recording = false; - return this->current_recording; + this->state = IDLE; + return this->id; } void ReplayManager::play(recording_t handle) { if (!this->memory.contains(handle)) throw out_of_range(format("ReplayManager: no recording for handle {}", handle)); - Recording & recording = *this->memory.at(handle); - - dbg_log("TODO: magic"); + this->recording = *this->memory.at(handle); + this->recording->frame = 0; + this->state = PLAYING; } void ReplayManager::release(recording_t handle) { - dbg_log("release"); - + if (!this->memory.contains(handle)) + return; + this->memory.erase(handle); } diff --git a/src/crepe/manager/ReplayManager.h b/src/crepe/manager/ReplayManager.h index c50196c..672d093 100644 --- a/src/crepe/manager/ReplayManager.h +++ b/src/crepe/manager/ReplayManager.h @@ -1,13 +1,14 @@ #pragma once +#include + #include "Manager.h" #include "ComponentManager.h" -#include +#include "util/OptionalRef.h" namespace crepe { class ReplaySystem; -class Memento; typedef size_t recording_t; @@ -20,11 +21,20 @@ protected: void record_frame(); private: - typedef std::vector Recording; - - bool recording = false; - recording_t current_recording = -1; - + struct Recording { + size_t frame = 0; + std::vector frames; + }; + + enum State { + IDLE, + RECORDING, + PLAYING, + }; + + State state = IDLE; + OptionalRef recording; + recording_t id = -1; std::unordered_map> memory; public: diff --git a/src/crepe/system/ReplaySystem.cpp b/src/crepe/system/ReplaySystem.cpp index 3aabb58..85595a2 100644 --- a/src/crepe/system/ReplaySystem.cpp +++ b/src/crepe/system/ReplaySystem.cpp @@ -1,7 +1,77 @@ +#include "system/ScriptSystem.h" + +#include "../manager/ReplayManager.h" + #include "ReplaySystem.h" +#include "../api/LoopManager.h" + using namespace crepe; +using namespace std; void ReplaySystem::fixed_update() { + ReplayManager & replay = this->mediator.replay_manager; + + switch (replay.state) { + case ReplayManager::IDLE: break; + case ReplayManager::RECORDING: { + this->update_recording(); + break; + } + case ReplayManager::PLAYING: { + this->update_playing(); + break; + } + } + + this->last_state = replay.state; +} + +void ReplaySystem::update_recording() { + ReplayManager & replay = this->mediator.replay_manager; + ComponentManager & components = this->mediator.component_manager; + + ReplayManager::Recording & recording = replay.recording; + recording.frames.push_back(components.save()); + recording.frame++; +} + +void ReplaySystem::update_playing() { + ReplayManager & replay = this->mediator.replay_manager; + + if (this->last_state != ReplayManager::PLAYING) { + this->playback_begin(); + } + + ReplayManager::Recording & recording = replay.recording; + + if (recording.frames.size() == recording.frame) { + this->playback_end(); + return; + } + + ComponentManager & components = this->mediator.component_manager; + ComponentManager::Snapshot & frame = recording.frames.at(recording.frame); + + components.restore(frame); + recording.frame++; +} + +void ReplaySystem::playback_begin() { + LoopManager & loop_manager = this->mediator.loop_manager; + // TODO: store system active state + // TODO: disable most systems + // TODO: store components snapshot +} + +void ReplaySystem::playback_end() { + ReplayManager & replay = this->mediator.replay_manager; + + replay.state = ReplayManager::IDLE; + + LoopManager & loop_manager = this->mediator.loop_manager; + + // TODO: restore system active state snapshot + // TODO: restore components snapshot } diff --git a/src/crepe/system/ReplaySystem.h b/src/crepe/system/ReplaySystem.h index 15ef3fc..fb40176 100644 --- a/src/crepe/system/ReplaySystem.h +++ b/src/crepe/system/ReplaySystem.h @@ -1,5 +1,7 @@ #pragma once +#include "../manager/ReplayManager.h" + #include "System.h" namespace crepe { @@ -9,6 +11,15 @@ public: using System::System; void fixed_update() override; + +private: + ReplayManager::State last_state = ReplayManager::IDLE; + void update_recording(); + void update_playing(); + + std::unordered_map system_active_snapshot; + void playback_begin(); + void playback_end(); }; } diff --git a/src/test/ECSTest.cpp b/src/test/ECSTest.cpp index af2b7b0..8f86a91 100644 --- a/src/test/ECSTest.cpp +++ b/src/test/ECSTest.cpp @@ -466,3 +466,17 @@ TEST_F(ECSTest, ComponentsByTag) { EXPECT_EQ(objects.size(), 3); } } + +TEST_F(ECSTest, Snapshot) { + GameObject foo = mgr.new_object("foo"); + + foo.transform.position = {1, 1}; + + ComponentManager::Snapshot snapshot = mgr.save(); + + foo.transform.position = {0, 0}; + + mgr.restore(snapshot); + + EXPECT_EQ(foo.transform.position, (vec2{1, 1})); +} -- cgit v1.2.3 From 1d1c256eea43a3d0685919ed2997e10990ef639f Mon Sep 17 00:00:00 2001 From: Loek Le Blansch Date: Thu, 12 Dec 2024 22:45:30 +0100 Subject: `make format` --- src/crepe/Component.cpp | 5 +---- src/crepe/api/Engine.cpp | 7 ++++--- src/crepe/api/Engine.h | 5 ++--- src/crepe/api/GameObject.cpp | 11 ++++++----- src/crepe/api/GameObject.h | 5 ++--- src/crepe/api/ParticleEmitter.cpp | 1 - src/crepe/api/Script.cpp | 1 - src/crepe/api/Script.h | 10 ++++++---- src/crepe/api/Script.hpp | 3 ++- src/crepe/api/Transform.cpp | 1 - src/crepe/manager/ComponentManager.cpp | 1 - src/crepe/manager/ReplayManager.cpp | 10 +++------- src/crepe/manager/ReplayManager.h | 5 +++-- src/crepe/manager/SystemManager.cpp | 5 ++--- src/crepe/manager/SystemManager.h | 2 +- src/crepe/manager/SystemManager.hpp | 7 ++++--- src/crepe/system/EventSystem.cpp | 3 +-- src/crepe/system/EventSystem.h | 3 +-- src/crepe/system/ReplaySystem.cpp | 6 +++--- src/crepe/system/ReplaySystem.h | 3 +-- src/crepe/system/ScriptSystem.cpp | 2 +- src/crepe/util/Log.cpp | 2 +- src/crepe/util/dbg.h | 1 - src/example/replay.cpp | 27 ++++++++++++--------------- src/test/Profiling.cpp | 6 ++++-- src/test/ReplayManagerTest.cpp | 14 ++++++++------ 26 files changed, 68 insertions(+), 78 deletions(-) (limited to 'src/test') diff --git a/src/crepe/Component.cpp b/src/crepe/Component.cpp index 1aed507..ae76e65 100644 --- a/src/crepe/Component.cpp +++ b/src/crepe/Component.cpp @@ -14,7 +14,4 @@ unique_ptr Component::save() const { return unique_ptr(new Component(*this)); } -void Component::restore(const Component & snapshot) { - *this = snapshot; -} - +void Component::restore(const Component & snapshot) { *this = snapshot; } diff --git a/src/crepe/api/Engine.cpp b/src/crepe/api/Engine.cpp index e8b7fd6..bbb4494 100644 --- a/src/crepe/api/Engine.cpp +++ b/src/crepe/api/Engine.cpp @@ -46,7 +46,8 @@ void Engine::loop() { try { systems.fixed_update(); } catch (const exception & e) { - Log::logf(Log::Level::WARNING, "Uncaught exception in fixed update function: {}\n", e.what()); + Log::logf(Log::Level::WARNING, + "Uncaught exception in fixed update function: {}\n", e.what()); } timer.advance_fixed_elapsed_time(); } @@ -54,9 +55,9 @@ void Engine::loop() { try { systems.frame_update(); } catch (const exception & e) { - Log::logf(Log::Level::WARNING, "Uncaught exception in frame update function: {}\n", e.what()); + Log::logf(Log::Level::WARNING, "Uncaught exception in frame update function: {}\n", + e.what()); } timer.enforce_frame_rate(); } } - diff --git a/src/crepe/api/Engine.h b/src/crepe/api/Engine.h index efe7853..3145723 100644 --- a/src/crepe/api/Engine.h +++ b/src/crepe/api/Engine.h @@ -2,14 +2,13 @@ #include "../facade/SDLContext.h" #include "../manager/ComponentManager.h" +#include "../manager/EventManager.h" +#include "../manager/LoopTimerManager.h" #include "../manager/ReplayManager.h" #include "../manager/ResourceManager.h" -#include "../manager/ResourceManager.h" #include "../manager/SaveManager.h" #include "../manager/SceneManager.h" #include "../manager/SystemManager.h" -#include "../manager/LoopTimerManager.h" -#include "../manager/EventManager.h" namespace crepe { diff --git a/src/crepe/api/GameObject.cpp b/src/crepe/api/GameObject.cpp index 68b074e..9b94cad 100644 --- a/src/crepe/api/GameObject.cpp +++ b/src/crepe/api/GameObject.cpp @@ -7,13 +7,14 @@ using namespace crepe; using namespace std; -GameObject::GameObject(Mediator & mediator, game_object_id_t id, - const std::string & name, const std::string & tag, - const vec2 & position, double rotation, double scale) +GameObject::GameObject(Mediator & mediator, game_object_id_t id, const std::string & name, + const std::string & tag, const vec2 & position, double rotation, + double scale) : id(id), mediator(mediator), - transform(mediator.component_manager->add_component(this->id, position, rotation, scale)), - metadata(mediator.component_manager->add_component(this->id, name, tag)) { } + transform(mediator.component_manager->add_component(this->id, position, + rotation, scale)), + metadata(mediator.component_manager->add_component(this->id, name, tag)) {} void GameObject::set_parent(const GameObject & parent) { ComponentManager & mgr = this->mediator.component_manager; diff --git a/src/crepe/api/GameObject.h b/src/crepe/api/GameObject.h index 0dabed1..572ce3a 100644 --- a/src/crepe/api/GameObject.h +++ b/src/crepe/api/GameObject.h @@ -30,9 +30,8 @@ private: * \param rotation The rotation of the GameObject * \param scale The scale of the GameObject */ - GameObject(Mediator & mediator, game_object_id_t id, - const std::string & name, const std::string & tag, const vec2 & position, - double rotation, double scale); + GameObject(Mediator & mediator, game_object_id_t id, const std::string & name, + const std::string & tag, const vec2 & position, double rotation, double scale); //! ComponentManager instances GameObject friend class ComponentManager; diff --git a/src/crepe/api/ParticleEmitter.cpp b/src/crepe/api/ParticleEmitter.cpp index fd69e26..a9c5cf6 100644 --- a/src/crepe/api/ParticleEmitter.cpp +++ b/src/crepe/api/ParticleEmitter.cpp @@ -23,4 +23,3 @@ ParticleEmitter & ParticleEmitter::operator=(const ParticleEmitter & other) { data.particles = other.data.particles; return *this; } - diff --git a/src/crepe/api/Script.cpp b/src/crepe/api/Script.cpp index 8b95cc9..34e7908 100644 --- a/src/crepe/api/Script.cpp +++ b/src/crepe/api/Script.cpp @@ -45,4 +45,3 @@ void Script::replay::release(recording_t recording) { ReplayManager & mgr = this->mediator->replay_manager; return mgr.release(recording); } - diff --git a/src/crepe/api/Script.h b/src/crepe/api/Script.h index 18a029b..6536fa4 100644 --- a/src/crepe/api/Script.h +++ b/src/crepe/api/Script.h @@ -2,13 +2,13 @@ #include -#include "../manager/ReplayManager.h" #include "../manager/EventManager.h" #include "../manager/Mediator.h" +#include "../manager/ReplayManager.h" #include "../system/CollisionSystem.h" #include "../types.h" -#include "../util/OptionalRef.h" #include "../util/Log.h" +#include "../util/OptionalRef.h" namespace crepe { @@ -115,10 +115,12 @@ protected: void subscribe(const EventHandler & callback); //! \copydoc EventManager::trigger_event template - void trigger_event(const EventType & event = {}, event_channel_t channel = EventManager::CHANNEL_ALL); + void trigger_event(const EventType & event = {}, + event_channel_t channel = EventManager::CHANNEL_ALL); //! \copydoc EventManager::queue_event template - void queue_event(const EventType & event = {}, event_channel_t channel = EventManager::CHANNEL_ALL); + void queue_event(const EventType & event = {}, + event_channel_t channel = EventManager::CHANNEL_ALL); //! \} /** diff --git a/src/crepe/api/Script.hpp b/src/crepe/api/Script.hpp index b42a6df..4462a41 100644 --- a/src/crepe/api/Script.hpp +++ b/src/crepe/api/Script.hpp @@ -48,7 +48,8 @@ void Script::subscribe_internal(const EventHandler & callback, try { ReplayManager & replay = this->mediator->replay_manager; if (replay.get_state() == ReplayManager::PLAYING) return false; - } catch (const std::runtime_error &) {} + } catch (const std::runtime_error &) { + } // call user-provided callback return callback(data); diff --git a/src/crepe/api/Transform.cpp b/src/crepe/api/Transform.cpp index 32b44e1..fcfce14 100644 --- a/src/crepe/api/Transform.cpp +++ b/src/crepe/api/Transform.cpp @@ -20,4 +20,3 @@ unique_ptr Transform::save() const { void Transform::restore(const Component & snapshot) { *this = static_cast(snapshot); } - diff --git a/src/crepe/manager/ComponentManager.cpp b/src/crepe/manager/ComponentManager.cpp index bc104d3..745ddae 100644 --- a/src/crepe/manager/ComponentManager.cpp +++ b/src/crepe/manager/ComponentManager.cpp @@ -97,4 +97,3 @@ void ComponentManager::restore(const Snapshot & snapshot) { this->components[info.type][info.id][info.index]->restore(*info.component); } } - diff --git a/src/crepe/manager/ReplayManager.cpp b/src/crepe/manager/ReplayManager.cpp index db6acb0..090a94e 100644 --- a/src/crepe/manager/ReplayManager.cpp +++ b/src/crepe/manager/ReplayManager.cpp @@ -1,7 +1,7 @@ #include -#include "ReplayManager.h" #include "Manager.h" +#include "ReplayManager.h" using namespace crepe; using namespace std; @@ -32,8 +32,7 @@ void ReplayManager::play(recording_t handle) { } void ReplayManager::release(recording_t handle) { - if (!this->memory.contains(handle)) - return; + if (!this->memory.contains(handle)) return; this->memory.erase(handle); } @@ -68,7 +67,4 @@ bool ReplayManager::frame_step() { return true; } -ReplayManager::State ReplayManager::get_state() const { - return this->state; -} - +ReplayManager::State ReplayManager::get_state() const { return this->state; } diff --git a/src/crepe/manager/ReplayManager.h b/src/crepe/manager/ReplayManager.h index d3af879..ab15b27 100644 --- a/src/crepe/manager/ReplayManager.h +++ b/src/crepe/manager/ReplayManager.h @@ -2,8 +2,8 @@ #include -#include "Manager.h" #include "ComponentManager.h" +#include "Manager.h" #include "util/OptionalRef.h" namespace crepe { @@ -19,6 +19,7 @@ typedef size_t recording_t; */ class ReplayManager : public Manager { // TODO: Delete recordings at end of scene + public: ReplayManager(Mediator & mediator); @@ -40,7 +41,7 @@ public: * \param handle Handle to recording (as returned by \c record_end()) */ void release(recording_t handle); - + public: //! Internal state enum State { diff --git a/src/crepe/manager/SystemManager.cpp b/src/crepe/manager/SystemManager.cpp index f67e786..5ada30f 100644 --- a/src/crepe/manager/SystemManager.cpp +++ b/src/crepe/manager/SystemManager.cpp @@ -2,13 +2,13 @@ #include "../system/AnimatorSystem.h" #include "../system/AudioSystem.h" #include "../system/CollisionSystem.h" +#include "../system/EventSystem.h" #include "../system/InputSystem.h" #include "../system/ParticleSystem.h" #include "../system/PhysicsSystem.h" #include "../system/RenderSystem.h" -#include "../system/ScriptSystem.h" -#include "../system/EventSystem.h" #include "../system/ReplaySystem.h" +#include "../system/ScriptSystem.h" #include "SystemManager.h" @@ -64,4 +64,3 @@ void SystemManager::disable_all() { system->active = false; } } - diff --git a/src/crepe/manager/SystemManager.h b/src/crepe/manager/SystemManager.h index a47961b..50acf77 100644 --- a/src/crepe/manager/SystemManager.h +++ b/src/crepe/manager/SystemManager.h @@ -1,8 +1,8 @@ #pragma once +#include #include #include -#include #include "../system/System.h" diff --git a/src/crepe/manager/SystemManager.hpp b/src/crepe/manager/SystemManager.hpp index 46ada5f..3d26e4c 100644 --- a/src/crepe/manager/SystemManager.hpp +++ b/src/crepe/manager/SystemManager.hpp @@ -1,8 +1,8 @@ #pragma once -#include #include #include +#include #include "SystemManager.h" @@ -11,7 +11,8 @@ namespace crepe { template T & SystemManager::get_system() { using namespace std; - static_assert(is_base_of::value, "get_system must recieve a derivative class of System"); + static_assert(is_base_of::value, + "get_system must recieve a derivative class of System"); const type_info & type = typeid(T); if (!this->systems.contains(type)) @@ -28,7 +29,7 @@ template void SystemManager::load_system() { using namespace std; static_assert(is_base_of::value, - "load_system must recieve a derivative class of System"); + "load_system must recieve a derivative class of System"); const type_info & type = typeid(T); if (this->systems.contains(type)) diff --git a/src/crepe/system/EventSystem.cpp b/src/crepe/system/EventSystem.cpp index 5475798..7e168ab 100644 --- a/src/crepe/system/EventSystem.cpp +++ b/src/crepe/system/EventSystem.cpp @@ -1,5 +1,5 @@ -#include "../manager/EventManager.h" #include "EventSystem.h" +#include "../manager/EventManager.h" using namespace crepe; @@ -7,4 +7,3 @@ void EventSystem::fixed_update() { EventManager & ev = this->mediator.event_manager; ev.dispatch_events(); } - diff --git a/src/crepe/system/EventSystem.h b/src/crepe/system/EventSystem.h index ff3ca4e..0ae48d2 100644 --- a/src/crepe/system/EventSystem.h +++ b/src/crepe/system/EventSystem.h @@ -18,5 +18,4 @@ public: void fixed_update() override; }; -} - +} // namespace crepe diff --git a/src/crepe/system/ReplaySystem.cpp b/src/crepe/system/ReplaySystem.cpp index 2b2e4ab..efc3be4 100644 --- a/src/crepe/system/ReplaySystem.cpp +++ b/src/crepe/system/ReplaySystem.cpp @@ -1,9 +1,9 @@ #include "../manager/ReplayManager.h" #include "../manager/SystemManager.h" +#include "EventSystem.h" #include "RenderSystem.h" #include "ReplaySystem.h" -#include "EventSystem.h" using namespace crepe; using namespace std; @@ -15,7 +15,8 @@ void ReplaySystem::fixed_update() { this->last_state = state; switch (state) { - case ReplayManager::IDLE: break; + case ReplayManager::IDLE: + break; case ReplayManager::RECORDING: { replay.frame_record(); break; @@ -51,4 +52,3 @@ void ReplaySystem::playback_end() { components.restore(this->playback.components); systems.restore(this->playback.systems); } - diff --git a/src/crepe/system/ReplaySystem.h b/src/crepe/system/ReplaySystem.h index 8ba60d5..bbc8d76 100644 --- a/src/crepe/system/ReplaySystem.h +++ b/src/crepe/system/ReplaySystem.h @@ -41,5 +41,4 @@ private: void playback_end(); }; -} - +} // namespace crepe diff --git a/src/crepe/system/ScriptSystem.cpp b/src/crepe/system/ScriptSystem.cpp index 11da618..0d10011 100644 --- a/src/crepe/system/ScriptSystem.cpp +++ b/src/crepe/system/ScriptSystem.cpp @@ -1,7 +1,7 @@ -#include "../util/dbg.h" #include "../api/BehaviorScript.h" #include "../api/Script.h" #include "../manager/ComponentManager.h" +#include "../util/dbg.h" #include "ScriptSystem.h" diff --git a/src/crepe/util/Log.cpp b/src/crepe/util/Log.cpp index e11a8d9..ce25a1d 100644 --- a/src/crepe/util/Log.cpp +++ b/src/crepe/util/Log.cpp @@ -3,8 +3,8 @@ #include "../api/Config.h" -#include "LogColor.h" #include "Log.h" +#include "LogColor.h" using namespace crepe; using namespace std; diff --git a/src/crepe/util/dbg.h b/src/crepe/util/dbg.h index 500e959..c7283ee 100644 --- a/src/crepe/util/dbg.h +++ b/src/crepe/util/dbg.h @@ -16,4 +16,3 @@ #define dbg_log(str) _crepe_logf_here(crepe::Log::Level::DEBUG, ": {}", str) #define dbg_trace() _crepe_logf_here(crepe::Log::Level::TRACE, "", "") // NOLINTEND - diff --git a/src/example/replay.cpp b/src/example/replay.cpp index 130c0d3..82fd478 100644 --- a/src/example/replay.cpp +++ b/src/example/replay.cpp @@ -1,6 +1,6 @@ +#include #include #include -#include using namespace crepe; using namespace std; @@ -9,13 +9,11 @@ class AnimationScript : public Script { Transform * transform; float t = 0; - void init() { - transform = &get_component(); - } + void init() { transform = &get_component(); } void update() { t += 0.05; - transform->position = { sin(t), cos(t) }; + transform->position = {sin(t), cos(t)}; } }; @@ -25,7 +23,8 @@ class Timeline : public Script { void update() { switch (i++) { - default: break; + default: + break; case 10: logf("record start"); replay.record_start(); @@ -56,17 +55,15 @@ public: ComponentManager & mgr = mediator.component_manager; GameObject cam = mgr.new_object("cam"); - cam.add_component(ivec2{640,480},vec2{3,3}, Camera::Data{ - .bg_color = Color::WHITE, - }); + cam.add_component(ivec2{640, 480}, vec2{3, 3}, + Camera::Data{ + .bg_color = Color::WHITE, + }); GameObject square = mgr.new_object("square"); - square.add_component( - Asset{"asset/texture/square.png"}, - Sprite::Data{ - .size = { 0.5, 0.5 }, - } - ); + square.add_component(Asset{"asset/texture/square.png"}, Sprite::Data{ + .size = {0.5, 0.5}, + }); square.add_component().set_script(); GameObject scapegoat = mgr.new_object(""); diff --git a/src/test/Profiling.cpp b/src/test/Profiling.cpp index eccfd89..f5ae4b1 100644 --- a/src/test/Profiling.cpp +++ b/src/test/Profiling.cpp @@ -102,12 +102,14 @@ public: // Run and profile all systems, return the total time in milliseconds std::chrono::microseconds run_all_systems() { std::chrono::microseconds total_microseconds = 0us; - total_microseconds += time_function("PhysicsSystem", [&]() { physics_sys.fixed_update(); }); + total_microseconds + += time_function("PhysicsSystem", [&]() { physics_sys.fixed_update(); }); total_microseconds += time_function("CollisionSystem", [&]() { collision_sys.fixed_update(); }); total_microseconds += time_function("ParticleSystem", [&]() { particle_sys.fixed_update(); }); - total_microseconds += time_function("RenderSystem", [&]() { render_sys.frame_update(); }); + total_microseconds + += time_function("RenderSystem", [&]() { render_sys.frame_update(); }); return total_microseconds; } diff --git a/src/test/ReplayManagerTest.cpp b/src/test/ReplayManagerTest.cpp index aa5a766..5ee4b40 100644 --- a/src/test/ReplayManagerTest.cpp +++ b/src/test/ReplayManagerTest.cpp @@ -1,10 +1,10 @@ #include -#include -#include +#include #include #include -#include +#include +#include using namespace std; using namespace crepe; @@ -12,14 +12,17 @@ using namespace testing; class ReplayManagerTest : public Test { Mediator mediator; + public: ComponentManager component_manager{mediator}; ReplayManager replay_manager{mediator}; ReplaySystem replay_system{mediator}; GameObject entity = component_manager.new_object("foo"); - Transform & entity_transform = component_manager.get_components_by_id(entity.id).back(); - Metadata & entity_metadata = component_manager.get_components_by_id(entity.id).back(); + Transform & entity_transform + = component_manager.get_components_by_id(entity.id).back(); + Metadata & entity_metadata + = component_manager.get_components_by_id(entity.id).back(); }; TEST_F(ReplayManagerTest, Default) { @@ -33,4 +36,3 @@ TEST_F(ReplayManagerTest, Default) { // recording_t recording = replay_manager.record_end(); } - -- cgit v1.2.3 From 3a23e41255af0de3c5c7f5d9df981c8b205e291f Mon Sep 17 00:00:00 2001 From: Loek Le Blansch Date: Fri, 13 Dec 2024 17:42:34 +0100 Subject: add timer functionality to script --- src/crepe/api/Script.cpp | 2 ++ src/crepe/api/Script.h | 12 ++++++++++++ src/crepe/system/ScriptSystem.cpp | 5 ++++- src/test/CollisionTest.cpp | 1 + src/test/ScriptTest.h | 1 + 5 files changed, 20 insertions(+), 1 deletion(-) (limited to 'src/test') diff --git a/src/crepe/api/Script.cpp b/src/crepe/api/Script.cpp index 753a9e3..50edea0 100644 --- a/src/crepe/api/Script.cpp +++ b/src/crepe/api/Script.cpp @@ -25,3 +25,5 @@ void Script::set_next_scene(const string & name) { } SaveManager & Script::get_save_manager() const { return this->mediator->save_manager; } + +LoopTimerManager & Script::get_loop_timer() const { return this->mediator->loop_timer; } diff --git a/src/crepe/api/Script.h b/src/crepe/api/Script.h index 668e5d1..3569b4a 100644 --- a/src/crepe/api/Script.h +++ b/src/crepe/api/Script.h @@ -2,6 +2,7 @@ #include +#include "../manager/LoopTimerManager.h" #include "../manager/EventManager.h" #include "../manager/Mediator.h" #include "../system/CollisionSystem.h" @@ -46,9 +47,17 @@ protected: /** * \brief Script update function (empty by default) * + * \param delta_time Time since last fixed update + * * This function is called during the ScriptSystem::update() routine if the \c BehaviorScript * component holding this script instance is active. */ + virtual void update(duration_t delta_time) { return this->update(); } + /** + * \brief Fallback script update function (empty by default) + * + * Allows the game programmer to ignore parameters passed to \c update() + */ virtual void update() {} //! \} @@ -135,6 +144,9 @@ protected: //! Retrieve SaveManager reference SaveManager & get_save_manager() const; + //! Retrieve LoopTimerManager reference + LoopTimerManager & get_loop_timer() const; + //! \} private: diff --git a/src/crepe/system/ScriptSystem.cpp b/src/crepe/system/ScriptSystem.cpp index d6b2ca1..4afd2ba 100644 --- a/src/crepe/system/ScriptSystem.cpp +++ b/src/crepe/system/ScriptSystem.cpp @@ -11,6 +11,7 @@ void ScriptSystem::update() { dbg_trace(); ComponentManager & mgr = this->mediator.component_manager; + LoopTimerManager & timer = this->mediator.loop_timer; RefVector behavior_scripts = mgr.get_components_by_type(); for (BehaviorScript & behavior_script : behavior_scripts) { @@ -23,6 +24,8 @@ void ScriptSystem::update() { script->init(); script->initialized = true; } - script->update(); + + duration_t delta_time = timer.get_delta_time(); + script->update(delta_time); } } diff --git a/src/test/CollisionTest.cpp b/src/test/CollisionTest.cpp index 5dbc670..a34189e 100644 --- a/src/test/CollisionTest.cpp +++ b/src/test/CollisionTest.cpp @@ -54,6 +54,7 @@ public: ComponentManager mgr{m}; CollisionSystem collision_sys{m}; ScriptSystem script_sys{m}; + LoopTimerManager loop_timer{m}; GameObject world = mgr.new_object("world", "", {50, 50}); GameObject game_object1 = mgr.new_object("object1", "", {50, 50}); diff --git a/src/test/ScriptTest.h b/src/test/ScriptTest.h index 31fa7c9..7aa858d 100644 --- a/src/test/ScriptTest.h +++ b/src/test/ScriptTest.h @@ -17,6 +17,7 @@ public: crepe::ComponentManager component_manager{mediator}; crepe::ScriptSystem system{mediator}; crepe::EventManager event_mgr{mediator}; + crepe::LoopTimerManager loop_timer{mediator}; crepe::GameObject entity = component_manager.new_object(OBJ_NAME); class MyScript : public crepe::Script { -- cgit v1.2.3 From 83131edf875c5997eb6a9f3441b5d42b22498bd8 Mon Sep 17 00:00:00 2001 From: Loek Le Blansch Date: Fri, 13 Dec 2024 18:04:49 +0100 Subject: update tests --- src/test/ScriptTest.cpp | 13 +++++++++++++ src/test/ScriptTest.h | 4 ++++ 2 files changed, 17 insertions(+) (limited to 'src/test') diff --git a/src/test/ScriptTest.cpp b/src/test/ScriptTest.cpp index acdae70..2aee0fd 100644 --- a/src/test/ScriptTest.cpp +++ b/src/test/ScriptTest.cpp @@ -73,3 +73,16 @@ TEST_F(ScriptTest, UpdateInactive) { system.update(); } } + +TEST_F(ScriptTest, SaveManager) { + MyScript & script = this->script; + + EXPECT_EQ(&script.get_save_manager(), &this->save_manager); +} + +TEST_F(ScriptTest, LoopTimerManager) { + MyScript & script = this->script; + + EXPECT_EQ(&script.get_loop_timer(), &this->loop_timer); +} + diff --git a/src/test/ScriptTest.h b/src/test/ScriptTest.h index 7aa858d..537169d 100644 --- a/src/test/ScriptTest.h +++ b/src/test/ScriptTest.h @@ -7,7 +7,10 @@ #include #include #include +#include +#include #include + class ScriptTest : public testing::Test { protected: crepe::Mediator mediator; @@ -18,6 +21,7 @@ public: crepe::ScriptSystem system{mediator}; crepe::EventManager event_mgr{mediator}; crepe::LoopTimerManager loop_timer{mediator}; + crepe::SaveManager save_manager{mediator}; crepe::GameObject entity = component_manager.new_object(OBJ_NAME); class MyScript : public crepe::Script { -- cgit v1.2.3 From ae80ecde90ea6ab3305deed899bbec1560b93a6f Mon Sep 17 00:00:00 2001 From: Loek Le Blansch Date: Fri, 13 Dec 2024 18:05:56 +0100 Subject: `make format` --- src/crepe/api/Script.h | 2 +- src/test/ScriptTest.cpp | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) (limited to 'src/test') diff --git a/src/crepe/api/Script.h b/src/crepe/api/Script.h index 3569b4a..1429108 100644 --- a/src/crepe/api/Script.h +++ b/src/crepe/api/Script.h @@ -2,8 +2,8 @@ #include -#include "../manager/LoopTimerManager.h" #include "../manager/EventManager.h" +#include "../manager/LoopTimerManager.h" #include "../manager/Mediator.h" #include "../system/CollisionSystem.h" #include "../types.h" diff --git a/src/test/ScriptTest.cpp b/src/test/ScriptTest.cpp index 2aee0fd..499be5a 100644 --- a/src/test/ScriptTest.cpp +++ b/src/test/ScriptTest.cpp @@ -85,4 +85,3 @@ TEST_F(ScriptTest, LoopTimerManager) { EXPECT_EQ(&script.get_loop_timer(), &this->loop_timer); } - -- cgit v1.2.3 From fa0d298afafdc81d00164765903161205cf09a7e Mon Sep 17 00:00:00 2001 From: Loek Le Blansch Date: Sat, 14 Dec 2024 16:24:08 +0100 Subject: move DB fix from `loek/doxygen` to `loek/savemgr` --- src/crepe/facade/DB.cpp | 13 ++----- src/crepe/facade/DB.h | 2 - src/crepe/manager/SaveManager.cpp | 49 ++++++++++++------------ src/crepe/manager/SaveManager.h | 6 +-- src/doc/feature/proxy.dox | 43 +++++++++++++++++++++ src/doc/feature/savemgr.dox | 80 +++++++++++++++++++++++++++++++++++++++ src/test/DBTest.cpp | 9 +++++ src/test/SaveManagerTest.cpp | 17 +++++++-- src/test/main.cpp | 3 +- 9 files changed, 179 insertions(+), 43 deletions(-) create mode 100644 src/doc/feature/proxy.dox create mode 100644 src/doc/feature/savemgr.dox (limited to 'src/test') diff --git a/src/crepe/facade/DB.cpp b/src/crepe/facade/DB.cpp index 95cf606..2232a21 100644 --- a/src/crepe/facade/DB.cpp +++ b/src/crepe/facade/DB.cpp @@ -21,12 +21,6 @@ DB::DB(const string & path) { const char * file = path.empty() ? NULL : path.c_str(); ret = this->db->open(this->db.get(), NULL, file, NULL, libdb::DB_BTREE, DB_CREATE, 0); if (ret != 0) throw runtime_error(format("db->open: {}", libdb::db_strerror(ret))); - - // create cursor - libdb::DBC * cursor; - ret = this->db->cursor(this->db.get(), NULL, &cursor, 0); - if (ret != 0) throw runtime_error(format("db->cursor: {}", libdb::db_strerror(ret))); - this->cursor = {cursor, [](libdb::DBC * cursor) { cursor->close(cursor); }}; } libdb::DBT DB::to_thing(const string & thing) const noexcept { @@ -42,10 +36,10 @@ string DB::get(const string & key) { libdb::DBT db_val; memset(&db_val, 0, sizeof(libdb::DBT)); - int ret = this->cursor->get(this->cursor.get(), &db_key, &db_val, DB_FIRST); + int ret = this->db->get(this->db.get(), NULL, &db_key, &db_val, 0); if (ret == 0) return {static_cast(db_val.data), db_val.size}; - string err = format("cursor->get: {}", libdb::db_strerror(ret)); + string err = format("db->get: {}", libdb::db_strerror(ret)); if (ret == DB_NOTFOUND) throw out_of_range(err); else throw runtime_error(err); } @@ -54,7 +48,7 @@ void DB::set(const string & key, const string & value) { libdb::DBT db_key = this->to_thing(key); libdb::DBT db_val = this->to_thing(value); int ret = this->db->put(this->db.get(), NULL, &db_key, &db_val, 0); - if (ret != 0) throw runtime_error(format("cursor->get: {}", libdb::db_strerror(ret))); + if (ret != 0) throw runtime_error(format("db->get: {}", libdb::db_strerror(ret))); } bool DB::has(const std::string & key) { @@ -65,3 +59,4 @@ bool DB::has(const std::string & key) { } return true; } + diff --git a/src/crepe/facade/DB.h b/src/crepe/facade/DB.h index 115c0f1..84cdf19 100644 --- a/src/crepe/facade/DB.h +++ b/src/crepe/facade/DB.h @@ -61,8 +61,6 @@ public: private: //! RAII wrapper around \c DB struct std::unique_ptr> db; - //! RAII wrapper around \c DBC struct - std::unique_ptr> cursor; private: /** diff --git a/src/crepe/manager/SaveManager.cpp b/src/crepe/manager/SaveManager.cpp index 691ea2f..f313ed2 100644 --- a/src/crepe/manager/SaveManager.cpp +++ b/src/crepe/manager/SaveManager.cpp @@ -128,10 +128,33 @@ template void SaveManager::set(const string &, const int64_t &); template void SaveManager::set(const string &, const float &); template void SaveManager::set(const string &, const double &); +template +T SaveManager::get(const string & key) { + return this->deserialize(this->get_db().get(key)); +} +template uint8_t SaveManager::get(const string &); +template int8_t SaveManager::get(const string &); +template uint16_t SaveManager::get(const string &); +template int16_t SaveManager::get(const string &); +template uint32_t SaveManager::get(const string &); +template int32_t SaveManager::get(const string &); +template uint64_t SaveManager::get(const string &); +template int64_t SaveManager::get(const string &); +template float SaveManager::get(const string &); +template double SaveManager::get(const string &); +template string SaveManager::get(const string &); + template ValueBroker SaveManager::get(const string & key, const T & default_value) { if (!this->has(key)) this->set(key, default_value); - return this->get(key); + T value; + return { + [this, key](const T & target) { this->set(key, target); }, + [this, key, value]() mutable -> const T & { + value = this->get(key); + return value; + }, + }; } template ValueBroker SaveManager::get(const string &, const uint8_t &); template ValueBroker SaveManager::get(const string &, const int8_t &); @@ -144,27 +167,3 @@ template ValueBroker SaveManager::get(const string &, const int64_t &); template ValueBroker SaveManager::get(const string &, const float &); template ValueBroker SaveManager::get(const string &, const double &); template ValueBroker SaveManager::get(const string &, const string &); - -template -ValueBroker SaveManager::get(const string & key) { - T value; - return { - [this, key](const T & target) { this->set(key, target); }, - [this, key, value]() mutable -> const T & { - DB & db = this->get_db(); - value = this->deserialize(db.get(key)); - return value; - }, - }; -} -template ValueBroker SaveManager::get(const string &); -template ValueBroker SaveManager::get(const string &); -template ValueBroker SaveManager::get(const string &); -template ValueBroker SaveManager::get(const string &); -template ValueBroker SaveManager::get(const string &); -template ValueBroker SaveManager::get(const string &); -template ValueBroker SaveManager::get(const string &); -template ValueBroker SaveManager::get(const string &); -template ValueBroker SaveManager::get(const string &); -template ValueBroker SaveManager::get(const string &); -template ValueBroker SaveManager::get(const string &); diff --git a/src/crepe/manager/SaveManager.h b/src/crepe/manager/SaveManager.h index 61a978d..1e34bc0 100644 --- a/src/crepe/manager/SaveManager.h +++ b/src/crepe/manager/SaveManager.h @@ -36,17 +36,17 @@ public: ValueBroker get(const std::string & key, const T & default_value); /** - * \brief Get a read/write reference to a value + * \brief Get a value directly * * \param key The value key * - * \return Read/write reference to the value + * \return The value * * \note Attempting to read this value before it is initialized (i.e. set) will result in an * exception */ template - ValueBroker get(const std::string & key); + T get(const std::string & key); /** * \brief Set a value directly diff --git a/src/doc/feature/proxy.dox b/src/doc/feature/proxy.dox new file mode 100644 index 0000000..66bbd2f --- /dev/null +++ b/src/doc/feature/proxy.dox @@ -0,0 +1,43 @@ +// vim:ft=doxygen +namespace crepe { +/** + +\defgroup feature_proxy Proxy utility +\ingroup feature +\brief Use ValueBroker as if it were a regular variable + +Proxy provides operators that allow you to use a ValueBroker instance as if it +were a regular variable. Proxy implements a constructor that allows it to be +used as a substitute return type for any function that returns ValueBroker. + +\see ValueBroker +\see Proxy + +\par Example + +```cpp +#include +#include + +int calculation(int value) { + return 3 * value; +} + +void anywhere() { + crepe::ValueBroker foo_handle; + crepe::Proxy foo = foo_handle; + + // implicitly calls .set() + foo += 10; + + // implicitly calls .get() + int out = calculation(foo); + + // explicitly cast (also calls .get()) + int casted = int(foo); +} + +``` + +*/ +} diff --git a/src/doc/feature/savemgr.dox b/src/doc/feature/savemgr.dox new file mode 100644 index 0000000..6aeab03 --- /dev/null +++ b/src/doc/feature/savemgr.dox @@ -0,0 +1,80 @@ +// vim:ft=doxygen +namespace crepe { +/** + +\defgroup feature_savemgr Save data +\ingroup feature +\brief Functions to persistently store and retrieve arbitrary values + +The SaveManager may be used to persistently store game state such as player +progress, statistics, achievements, etc. It works like a key-value store, where +the key is a string and the value is an arbitrary type. + +SaveManager implements the following: + +- Storage and retrieval of primitive types and strings. +- Automatic initialization of the database using default values. +- The underlying database format is journaled, which reduces the likelihood of + players losing save data when an unexpected crash occurs while the SaveManager + is writing to disk. + +\see SaveManager + +\par Example + +The SaveManager instance reference may be retrieved by calling \c +get_save_manager(). This function is available--- + +- Within (derivatives of) Script + +- \todo Within (derivatives of) Scene + +- \todo As a public member function of LoopManager + +```cpp +// Retrieve save manager +crepe::SaveManager & save_manager = get_save_manager(); +``` + +SaveManager may be used *explicitly*, using the \ref SaveManager::set "set()", +\ref SaveManager::get "get()" and \ref SaveManager::has "has()" methods: +```cpp +// Check if the key "foo" exists, and initialize it to 3 if it doesn't +if (!save_manager.has("foo")) + save_manager.set("foo", 3); +// Get value of key "foo" +int foo = save_manager.get("foo"); + +// ~~~ arbitrary game code ~~~ +foo += 10; +// ~~~ arbitrary game code ~~~ + +// Save "foo" back to database +save_manager.set("foo", foo); +``` + +Alternatively, SaveManager::get may be called with a default value as second +parameter. This changes its return type to ValueBroker, which acts as a +read/write handle to the specific key requested, and remembers the key and its +value type for you: +```cpp +// Get a read/write handle to the value stored in key "foo", and initialize it +// to 3 if it doesn't exist yet +ValueBroker foo_handle = save_manager.get("foo", 3); +int foo = foo_handle.get(); + +// ~~~ arbitrary game code ~~~ +foo += 10; +// ~~~ arbitrary game code ~~~ + +// Save back to database +foo_handle.set(foo); +``` + +To further simplify game code, the return value of SaveManager::get may be +implicitly cast to Proxy instead of ValueBroker. This allows the database value +to be used as if it were a regular variable. This usage is detailed separately +in \"\ref feature_proxy\". + +*/ +} diff --git a/src/test/DBTest.cpp b/src/test/DBTest.cpp index 99dedff..0c98e10 100644 --- a/src/test/DBTest.cpp +++ b/src/test/DBTest.cpp @@ -27,3 +27,12 @@ TEST_F(DBTest, Has) { db.set("foo", "bar"); EXPECT_EQ(db.has("foo"), true); } + +TEST_F(DBTest, MultipleKeys) { + db.set("foo", "foo"); + db.set("bar", "bar"); + + EXPECT_EQ(db.get("foo"), "foo"); + EXPECT_EQ(db.get("bar"), "bar"); +} + diff --git a/src/test/SaveManagerTest.cpp b/src/test/SaveManagerTest.cpp index e9b0c29..7609e69 100644 --- a/src/test/SaveManagerTest.cpp +++ b/src/test/SaveManagerTest.cpp @@ -27,8 +27,8 @@ TEST_F(SaveManagerTest, ReadWrite) { mgr.set("foo", "bar"); ASSERT_TRUE(mgr.has("foo")); - ValueBroker value = mgr.get("foo"); - EXPECT_EQ(value.get(), "bar"); + string value = mgr.get("foo"); + EXPECT_EQ(value, "bar"); } TEST_F(SaveManagerTest, DefaultValue) { @@ -36,5 +36,16 @@ TEST_F(SaveManagerTest, DefaultValue) { ASSERT_EQ(value.get(), 3); value.set(5); - ASSERT_EQ(value.get(), 5); + EXPECT_EQ(value.get(), 5); +} + +TEST_F(SaveManagerTest, MultipleKeys) { + ValueBroker foo = mgr.get("foo", 1); + ValueBroker bar = mgr.get("bar", 2); + + EXPECT_EQ(foo.get(), 1); + EXPECT_EQ(bar.get(), 2); + + EXPECT_EQ(mgr.get("foo"), 1); + EXPECT_EQ(mgr.get("bar"), 2); } diff --git a/src/test/main.cpp b/src/test/main.cpp index ed2aed5..0e1bc75 100644 --- a/src/test/main.cpp +++ b/src/test/main.cpp @@ -1,6 +1,7 @@ -#include #include +#include + using namespace crepe; using namespace testing; -- cgit v1.2.3 From 154ed5353ef18eb46cc31744e8bf1bc54afd5acc Mon Sep 17 00:00:00 2001 From: Loek Le Blansch Date: Sat, 14 Dec 2024 16:24:25 +0100 Subject: `make format` --- src/crepe/facade/DB.cpp | 1 - src/test/DBTest.cpp | 1 - 2 files changed, 2 deletions(-) (limited to 'src/test') diff --git a/src/crepe/facade/DB.cpp b/src/crepe/facade/DB.cpp index 2232a21..ae2d4bc 100644 --- a/src/crepe/facade/DB.cpp +++ b/src/crepe/facade/DB.cpp @@ -59,4 +59,3 @@ bool DB::has(const std::string & key) { } return true; } - diff --git a/src/test/DBTest.cpp b/src/test/DBTest.cpp index 0c98e10..7f2c339 100644 --- a/src/test/DBTest.cpp +++ b/src/test/DBTest.cpp @@ -35,4 +35,3 @@ TEST_F(DBTest, MultipleKeys) { EXPECT_EQ(db.get("foo"), "foo"); EXPECT_EQ(db.get("bar"), "bar"); } - -- cgit v1.2.3 From 16f3aa77cfbfd3327a50a3f11f27e7d7dd303026 Mon Sep 17 00:00:00 2001 From: JAROWMR Date: Mon, 16 Dec 2024 21:14:46 +0100 Subject: Added util for position --- src/crepe/facade/SDLContext.cpp | 2 +- src/crepe/system/CollisionSystem.cpp | 79 +++++++++++++++--------------------- src/crepe/system/CollisionSystem.h | 2 +- src/crepe/system/RenderSystem.cpp | 5 ++- src/crepe/util/AbsoluutPosition.cpp | 21 ++++++++++ src/crepe/util/AbsoluutPosition.h | 17 ++++++++ src/crepe/util/CMakeLists.txt | 2 + src/example/game.cpp | 53 ++++++++++++++++-------- src/test/CollisionTest.cpp | 20 ++++----- 9 files changed, 123 insertions(+), 78 deletions(-) create mode 100644 src/crepe/util/AbsoluutPosition.cpp create mode 100644 src/crepe/util/AbsoluutPosition.h (limited to 'src/test') diff --git a/src/crepe/facade/SDLContext.cpp b/src/crepe/facade/SDLContext.cpp index 20bb030..ee7d149 100644 --- a/src/crepe/facade/SDLContext.cpp +++ b/src/crepe/facade/SDLContext.cpp @@ -235,7 +235,7 @@ SDL_FRect SDLContext::get_dst_rect(const DestinationRectangleData & ctx) const { } size *= cam_aux_data.render_scale * ctx.img_scale * data.scale_offset; - vec2 screen_pos = (ctx.pos + data.position_offset - cam_aux_data.cam_pos + vec2 screen_pos = (ctx.pos - cam_aux_data.cam_pos + (cam_aux_data.zoomed_viewport) / 2) * cam_aux_data.render_scale - size / 2 + cam_aux_data.bar_size; diff --git a/src/crepe/system/CollisionSystem.cpp b/src/crepe/system/CollisionSystem.cpp index fc8c430..294e7b3 100644 --- a/src/crepe/system/CollisionSystem.cpp +++ b/src/crepe/system/CollisionSystem.cpp @@ -15,31 +15,15 @@ #include "api/Rigidbody.h" #include "api/Transform.h" #include "api/Vector2.h" +#include "util/OptionalRef.h" +#include "util/AbsoluutPosition.h" #include "Collider.h" #include "CollisionSystem.h" #include "types.h" -#include "util/OptionalRef.h" using namespace crepe; -vec2 get_current_position(const Transform & transform,const vec2 & offset) { - // Get the rotation in radians - float radians1 = transform.rotation * (M_PI / 180.0); - - // Calculate total offset with scale - vec2 total_offset = offset * transform.scale; - - // Rotate - float rotated_total_offset_x1 - = total_offset.x * cos(radians1) - total_offset.y * sin(radians1); - float rotated_total_offset_y1 - = total_offset.x * sin(radians1) + total_offset.y * cos(radians1); - - // Final positions considering scaling and rotation - return (transform.position + vec2(rotated_total_offset_x1, rotated_total_offset_y1)); -} - void CollisionSystem::update() { std::vector all_colliders; game_object_id_t id = 0; @@ -155,8 +139,9 @@ CollisionSystem::collision_handler(CollisionInternal & data1, CollisionInternal = std::get>(data1.collider); const BoxCollider & collider2 = std::get>(data2.collider); - vec2 collider_pos1 = get_current_position(data1.transform,collider1.offset); - vec2 collider_pos2 = get_current_position(data2.transform,collider2.offset); + + vec2 collider_pos1 = AbsoluutPosition::get_position(data1.transform,collider1.offset); + vec2 collider_pos2 = AbsoluutPosition::get_position(data2.transform,collider2.offset); resolution = this->get_box_box_resolution(collider1, collider2, collider_pos1, collider_pos2); break; @@ -166,8 +151,8 @@ CollisionSystem::collision_handler(CollisionInternal & data1, CollisionInternal = std::get>(data1.collider); const CircleCollider & collider2 = std::get>(data2.collider); - vec2 collider_pos1 = get_current_position(data1.transform,collider1.offset); - vec2 collider_pos2 = get_current_position(data2.transform,collider2.offset); + vec2 collider_pos1 = AbsoluutPosition::get_position(data1.transform,collider1.offset); + vec2 collider_pos2 = AbsoluutPosition::get_position(data2.transform,collider2.offset); resolution = -this->get_circle_box_resolution(collider2, collider1, collider_pos2, collider_pos1); break; @@ -177,8 +162,8 @@ CollisionSystem::collision_handler(CollisionInternal & data1, CollisionInternal = std::get>(data1.collider); const CircleCollider & collider2 = std::get>(data2.collider); - vec2 collider_pos1 = get_current_position(data1.transform,collider1.offset); - vec2 collider_pos2 = get_current_position(data2.transform,collider2.offset); + vec2 collider_pos1 = AbsoluutPosition::get_position(data1.transform,collider1.offset); + vec2 collider_pos2 = AbsoluutPosition::get_position(data2.transform,collider2.offset); resolution = this->get_circle_circle_resolution(collider1, collider2, collider_pos1, collider_pos2); break; @@ -188,8 +173,8 @@ CollisionSystem::collision_handler(CollisionInternal & data1, CollisionInternal = std::get>(data1.collider); const BoxCollider & collider2 = std::get>(data2.collider); - vec2 collider_pos1 = get_current_position(data1.transform,collider1.offset); - vec2 collider_pos2 = get_current_position(data2.transform,collider2.offset); + vec2 collider_pos1 = AbsoluutPosition::get_position(data1.transform,collider1.offset); + vec2 collider_pos2 = AbsoluutPosition::get_position(data2.transform,collider2.offset); resolution = this->get_circle_box_resolution(collider1, collider2, collider_pos1, collider_pos2); break; @@ -311,15 +296,7 @@ vec2 CollisionSystem::get_circle_box_resolution(const CircleCollider & circle_co } void CollisionSystem::determine_collision_handler(CollisionInfo & info) { - // If both objects are static skip handle call collision script - if(info.this_rigidbody.data.body_type == Rigidbody::BodyType::STATIC && info.other_rigidbody.data.body_type == Rigidbody::BodyType::STATIC) return; - - // First body is not dynamic - if(info.this_rigidbody.data.body_type != Rigidbody::BodyType::DYNAMIC) - { - bool static_collision = info.this_rigidbody.data.body_type == Rigidbody::BodyType::STATIC && info.other_rigidbody.data.body_type == Rigidbody::BodyType::DYNAMIC; - bool kinematic_collision = info.this_rigidbody.data.body_type == Rigidbody::BodyType::KINEMATIC && info.other_rigidbody.data.body_type == Rigidbody::BodyType::DYNAMIC && info.this_rigidbody.data.kinematic_collision; - // Inverted collision info + // Inverted collision info CollisionInfo inverted = { .this_collider = info.other_collider, .this_transform = info.other_transform, @@ -332,13 +309,22 @@ void CollisionSystem::determine_collision_handler(CollisionInfo & info) { .resolution = -info.resolution, .resolution_direction = info.resolution_direction, }; + // If both objects are static skip handle call collision script + if(info.this_rigidbody.data.body_type == Rigidbody::BodyType::STATIC && info.other_rigidbody.data.body_type == Rigidbody::BodyType::STATIC) return; + + // First body is not dynamic + if(info.this_rigidbody.data.body_type != Rigidbody::BodyType::DYNAMIC) + { + bool static_collision = info.this_rigidbody.data.body_type == Rigidbody::BodyType::STATIC && info.other_rigidbody.data.body_type == Rigidbody::BodyType::DYNAMIC; + bool kinematic_collision = info.this_rigidbody.data.body_type == Rigidbody::BodyType::KINEMATIC && info.other_rigidbody.data.body_type == Rigidbody::BodyType::DYNAMIC && info.this_rigidbody.data.kinematic_collision; + if(static_collision || kinematic_collision){ // Static collision this->static_collision_handler(inverted); }; // Call scripts - this->call_collision_events(inverted); + this->call_collision_events(inverted,info); return; } @@ -348,20 +334,21 @@ void CollisionSystem::determine_collision_handler(CollisionInfo & info) { bool static_collision = info.other_rigidbody.data.body_type == Rigidbody::BodyType::STATIC; bool kinematic_collision = info.other_rigidbody.data.body_type == Rigidbody::BodyType::KINEMATIC && info.other_rigidbody.data.kinematic_collision; if(static_collision || kinematic_collision) this->static_collision_handler(info); - this->call_collision_events(info); + this->call_collision_events(info,inverted); return; } //dynamic this->dynamic_collision_handler(info); - this->call_collision_events(info); + this->call_collision_events(info,inverted); } -void CollisionSystem::call_collision_events(CollisionInfo & info){ +void CollisionSystem::call_collision_events(CollisionInfo & info,CollisionInfo & info_inverted){ CollisionEvent data(info); + CollisionEvent data_inverted(info_inverted); EventManager & emgr = this->mediator.event_manager; emgr.trigger_event(data, info.this_collider.game_object_id); - emgr.trigger_event(data, info.other_collider.game_object_id); + emgr.trigger_event(data_inverted, info_inverted.this_collider.game_object_id); } void CollisionSystem::static_collision_handler(CollisionInfo & info) { @@ -615,8 +602,8 @@ bool CollisionSystem::get_box_box_collision(const BoxCollider & box1, const BoxC const Rigidbody & rigidbody1, const Rigidbody & rigidbody2) const { // Get current positions of colliders - vec2 final_position1 = get_current_position(transform1,box1.offset); - vec2 final_position2 = get_current_position(transform2,box2.offset); + vec2 final_position1 = AbsoluutPosition::get_position(transform1,box1.offset); + vec2 final_position2 = AbsoluutPosition::get_position(transform2,box2.offset); // Scale dimensions vec2 scaled_box1 = box1.dimensions * transform1.scale; @@ -642,8 +629,8 @@ bool CollisionSystem::get_box_circle_collision(const BoxCollider & box1, const Rigidbody & rigidbody1, const Rigidbody & rigidbody2) const { // Get current positions of colliders - vec2 final_position1 = get_current_position(transform1,box1.offset); - vec2 final_position2 = get_current_position(transform2,circle2.offset); + vec2 final_position1 = AbsoluutPosition::get_position(transform1,box1.offset); + vec2 final_position2 = AbsoluutPosition::get_position(transform2,circle2.offset); // Scale dimensions vec2 scaled_box = box1.dimensions * transform1.scale; @@ -675,8 +662,8 @@ bool CollisionSystem::get_circle_circle_collision(const CircleCollider & circle1 const Rigidbody & rigidbody1, const Rigidbody & rigidbody2) const { // Get current positions of colliders - vec2 final_position1 = get_current_position(transform1,circle1.offset); - vec2 final_position2 = get_current_position(transform2,circle2.offset); + vec2 final_position1 = AbsoluutPosition::get_position(transform1,circle1.offset); + vec2 final_position2 = AbsoluutPosition::get_position(transform2,circle2.offset); // Scale dimensions float scaled_circle1 = circle1.radius * transform1.scale; diff --git a/src/crepe/system/CollisionSystem.h b/src/crepe/system/CollisionSystem.h index 78fce46..b802426 100644 --- a/src/crepe/system/CollisionSystem.h +++ b/src/crepe/system/CollisionSystem.h @@ -188,7 +188,7 @@ private: * * \param info Collision information containing data about both colliders. */ - void call_collision_events(CollisionInfo & info); + void call_collision_events(CollisionInfo & info,CollisionInfo & info_inverted); /** * \brief Handles collisions involving static objects. diff --git a/src/crepe/system/RenderSystem.cpp b/src/crepe/system/RenderSystem.cpp index afd9548..d14d78d 100644 --- a/src/crepe/system/RenderSystem.cpp +++ b/src/crepe/system/RenderSystem.cpp @@ -13,6 +13,7 @@ #include "../facade/Texture.h" #include "../manager/ComponentManager.h" #include "../manager/ResourceManager.h" +#include "util/AbsoluutPosition.h" #include "RenderSystem.h" #include "types.h" @@ -105,11 +106,11 @@ void RenderSystem::render_normal(const Sprite & sprite, const Transform & tm) { SDLContext & ctx = this->mediator.sdl_context; ResourceManager & resource_manager = this->mediator.resource_manager; const Texture & res = resource_manager.get(sprite.source); - + vec2 pos = AbsoluutPosition::get_position(tm,sprite.data.position_offset); ctx.draw(SDLContext::RenderContext{ .sprite = sprite, .texture = res, - .pos = tm.position, + .pos = pos, .angle = tm.rotation, .scale = tm.scale, }); diff --git a/src/crepe/util/AbsoluutPosition.cpp b/src/crepe/util/AbsoluutPosition.cpp new file mode 100644 index 0000000..8be625e --- /dev/null +++ b/src/crepe/util/AbsoluutPosition.cpp @@ -0,0 +1,21 @@ +#include "AbsoluutPosition.h" + +using namespace crepe; + +vec2 AbsoluutPosition::get_position(const Transform & transform,const vec2 & offset) { + // Get the rotation in radians + float radians1 = transform.rotation * (M_PI / 180.0); + + // Calculate total offset with scale + vec2 total_offset = offset * transform.scale; + + // Rotate + float rotated_total_offset_x1 + = total_offset.x * cos(radians1) - total_offset.y * sin(radians1); + float rotated_total_offset_y1 + = total_offset.x * sin(radians1) + total_offset.y * cos(radians1); + + // Final positions considering scaling and rotation + return (transform.position + vec2(rotated_total_offset_x1, rotated_total_offset_y1)); +} + diff --git a/src/crepe/util/AbsoluutPosition.h b/src/crepe/util/AbsoluutPosition.h new file mode 100644 index 0000000..4441f90 --- /dev/null +++ b/src/crepe/util/AbsoluutPosition.h @@ -0,0 +1,17 @@ +#pragma once + + +#include "api/Transform.h" + +#include "types.h" + +namespace crepe { + + +class AbsoluutPosition { +public: + static vec2 get_position(const Transform & transform,const vec2 & offset); + +}; + +} // namespace crepe diff --git a/src/crepe/util/CMakeLists.txt b/src/crepe/util/CMakeLists.txt index 94ed906..b4b9221 100644 --- a/src/crepe/util/CMakeLists.txt +++ b/src/crepe/util/CMakeLists.txt @@ -1,6 +1,7 @@ target_sources(crepe PUBLIC LogColor.cpp Log.cpp + AbsoluutPosition.cpp ) target_sources(crepe PUBLIC FILE_SET HEADERS FILES @@ -11,5 +12,6 @@ target_sources(crepe PUBLIC FILE_SET HEADERS FILES Proxy.hpp OptionalRef.h OptionalRef.hpp + AbsoluutPosition.h ) diff --git a/src/example/game.cpp b/src/example/game.cpp index 8ea50ea..3ba15d2 100644 --- a/src/example/game.cpp +++ b/src/example/game.cpp @@ -3,6 +3,7 @@ #include "manager/ComponentManager.h" #include "manager/Mediator.h" #include "types.h" +#include #include #include #include @@ -66,11 +67,6 @@ class MyScript1 : public Script { //add collider switch break; } - case Keycode::Q: { - Rigidbody & rg = this->get_component(); - rg.data.angular_velocity = 1; - break; - } default: break; } @@ -139,6 +135,31 @@ class MyScript2 : public Script { //add collider switch break; } + case Keycode::J: { + Rigidbody & tf = this->get_component(); + tf.data.linear_velocity.x = -10; + break; + } + case Keycode::I: { + Rigidbody & tf = this->get_component(); + tf.data.linear_velocity.y -= 1; + break; + } + case Keycode::K: { + Rigidbody & tf = this->get_component(); + tf.data.linear_velocity.y += 1; + break; + } + case Keycode::L: { + Rigidbody & tf = this->get_component(); + tf.data.linear_velocity.x = 10; + break; + } + case Keycode::O: { + Rigidbody & tf = this->get_component(); + tf.data.linear_velocity.x = 0; + break; + } default: break; } @@ -175,7 +196,6 @@ public: .mass = 0, .gravity_scale = 0, .body_type = Rigidbody::BodyType::STATIC, - .offset = {0, 0}, .collision_layers = {0}, }); world.add_component( @@ -198,24 +218,26 @@ public: }); GameObject game_object1 = new_object( - "Name", "Tag", vec2{screen_size_width / 2, screen_size_height / 2}, 0, 1); + "Name", "Tag", vec2{screen_size_width / 2, screen_size_height / 2}, 45, 1); game_object1.add_component(Rigidbody::Data{ .mass = 1, - .gravity_scale = 1, - .body_type = Rigidbody::BodyType::DYNAMIC, + .gravity_scale = 0, + .body_type = Rigidbody::BodyType::KINEMATIC, .linear_velocity = {0, 1}, .constraints = {0, 0, 0}, .elastisity_coefficient = 1, - .offset = {0, 0}, .collision_layers = {0}, }); // add box with boxcollider game_object1.add_component(vec2{0, 0}, vec2{20, 20}); game_object1.add_component().set_script(); - Asset img1{"asset/texture/square.png"}; + Asset img1{"asset/texture/test_ap43.png"}; game_object1.add_component(img1, Sprite::Data{ + .sorting_in_layer = 2, + .order_in_layer = 2, .size = {20, 20}, + .position_offset = {0,-10}, }); //add circle with cirlcecollider deactiveated @@ -233,16 +255,15 @@ public: "Name", "Tag", vec2{screen_size_width / 2, screen_size_height / 2}, 0, 1); game_object2.add_component(Rigidbody::Data{ .mass = 1, - .gravity_scale = 0, - .body_type = Rigidbody::BodyType::STATIC, + .gravity_scale = 1, + .body_type = Rigidbody::BodyType::KINEMATIC, .linear_velocity = {0, 0}, .constraints = {0, 0, 0}, - .elastisity_coefficient = 1, - .offset = {0, 0}, + .elastisity_coefficient = 0.66, .collision_layers = {0}, }); // add box with boxcollider - game_object2.add_component(vec2{0, 0}, vec2{20, 20}); + game_object2.add_component(vec2{0, 0}, vec2{INFINITY, 20}); game_object2.add_component().set_script(); game_object2.add_component(img1, Sprite::Data{ diff --git a/src/test/CollisionTest.cpp b/src/test/CollisionTest.cpp index 2ad65fa..43bf77d 100644 --- a/src/test/CollisionTest.cpp +++ b/src/test/CollisionTest.cpp @@ -66,7 +66,6 @@ public: world.add_component(Rigidbody::Data{ // TODO: remove unrelated properties: .body_type = Rigidbody::BodyType::STATIC, - .offset = {0, 0}, }); // Create a box with an inner size of 10x10 units world.add_component(vec2{0, -100}, vec2{100, 100}); // Top @@ -81,7 +80,6 @@ public: .linear_velocity = {0, 0}, .constraints = {0, 0, 0}, .elastisity_coefficient = 1, - .offset = {0, 0}, .collision_layers = {0}, }); game_object1.add_component(vec2{0, 0}, vec2{10, 10}); @@ -97,7 +95,6 @@ public: .linear_velocity = {0, 0}, .constraints = {0, 0, 0}, .elastisity_coefficient = 1, - .offset = {0, 0}, .collision_layers = {0}, }); game_object2.add_component(vec2{0, 0}, vec2{10, 10}); @@ -138,8 +135,8 @@ TEST_F(CollisionTest, collision_box_box_dynamic_both_no_velocity) { script_object2_ref->test_fn = [&collision_happend](const CollisionEvent & ev) { collision_happend = true; EXPECT_EQ(ev.info.this_collider.game_object_id, 2); - EXPECT_EQ(ev.info.resolution.x, 10); - EXPECT_EQ(ev.info.resolution.y, 10); + EXPECT_EQ(ev.info.resolution.x, -10); + EXPECT_EQ(ev.info.resolution.y, -10); EXPECT_EQ(ev.info.resolution_direction, crepe::CollisionSystem::Direction::BOTH); }; EXPECT_FALSE(collision_happend); @@ -211,8 +208,8 @@ TEST_F(CollisionTest, collision_box_box_dynamic_both) { script_object2_ref->test_fn = [&collision_happend](const CollisionEvent & ev) { collision_happend = true; EXPECT_EQ(ev.info.this_collider.game_object_id, 2); - EXPECT_EQ(ev.info.resolution.x, 10); - EXPECT_EQ(ev.info.resolution.y, 10); + EXPECT_EQ(ev.info.resolution.x, -10); + EXPECT_EQ(ev.info.resolution.y, -10); EXPECT_EQ(ev.info.resolution_direction, crepe::CollisionSystem::Direction::BOTH); }; EXPECT_FALSE(collision_happend); @@ -294,8 +291,7 @@ TEST_F(CollisionTest, collision_box_box_static_both) { EXPECT_EQ(ev.info.resolution_direction, crepe::CollisionSystem::Direction::BOTH); }; script_object2_ref->test_fn = [&collision_happend](const CollisionEvent & ev) { - // is static should not be called - FAIL(); + collision_happend = true; }; EXPECT_FALSE(collision_happend); Transform & tf = this->mgr.get_components_by_id(1).front().get(); @@ -318,7 +314,7 @@ TEST_F(CollisionTest, collision_box_box_static_x_direction) { }; script_object2_ref->test_fn = [&collision_happend](const CollisionEvent & ev) { // is static should not be called - FAIL(); + //FAIL(); }; EXPECT_FALSE(collision_happend); Transform & tf = this->mgr.get_components_by_id(1).front().get(); @@ -343,7 +339,7 @@ TEST_F(CollisionTest, collision_box_box_static_y_direction) { }; script_object2_ref->test_fn = [&collision_happend](const CollisionEvent & ev) { // is static should not be called - FAIL(); + //FAIL(); }; EXPECT_FALSE(collision_happend); Transform & tf = this->mgr.get_components_by_id(1).front().get(); @@ -368,7 +364,7 @@ TEST_F(CollisionTest, collision_box_box_static_multiple) { //todo check visually }; script_object2_ref->test_fn = [&](const CollisionEvent & ev) { // is static should not be called - FAIL(); + //FAIL(); }; EXPECT_FALSE(collision_happend); Transform & tf = this->mgr.get_components_by_id(1).front().get(); -- cgit v1.2.3 From 5bece30f9ad495a0e82097b2c5668e979856fb69 Mon Sep 17 00:00:00 2001 From: JAROWMR Date: Mon, 16 Dec 2024 21:22:35 +0100 Subject: make format --- src/crepe/facade/SDLContext.cpp | 3 +- src/crepe/system/CollisionSystem.cpp | 123 +++++++++++++++++++---------------- src/crepe/system/CollisionSystem.h | 2 +- src/crepe/system/ParticleSystem.cpp | 2 +- src/crepe/system/RenderSystem.cpp | 2 +- src/crepe/util/AbsoluutPosition.cpp | 3 +- src/crepe/util/AbsoluutPosition.h | 5 +- src/example/game.cpp | 2 +- src/test/CollisionTest.cpp | 5 +- src/test/Profiling.cpp | 26 ++++---- 10 files changed, 90 insertions(+), 83 deletions(-) (limited to 'src/test') diff --git a/src/crepe/facade/SDLContext.cpp b/src/crepe/facade/SDLContext.cpp index ee7d149..a1a6f97 100644 --- a/src/crepe/facade/SDLContext.cpp +++ b/src/crepe/facade/SDLContext.cpp @@ -235,8 +235,7 @@ SDL_FRect SDLContext::get_dst_rect(const DestinationRectangleData & ctx) const { } size *= cam_aux_data.render_scale * ctx.img_scale * data.scale_offset; - vec2 screen_pos = (ctx.pos - cam_aux_data.cam_pos - + (cam_aux_data.zoomed_viewport) / 2) + vec2 screen_pos = (ctx.pos - cam_aux_data.cam_pos + (cam_aux_data.zoomed_viewport) / 2) * cam_aux_data.render_scale - size / 2 + cam_aux_data.bar_size; diff --git a/src/crepe/system/CollisionSystem.cpp b/src/crepe/system/CollisionSystem.cpp index 294e7b3..9604543 100644 --- a/src/crepe/system/CollisionSystem.cpp +++ b/src/crepe/system/CollisionSystem.cpp @@ -15,8 +15,8 @@ #include "api/Rigidbody.h" #include "api/Transform.h" #include "api/Vector2.h" -#include "util/OptionalRef.h" #include "util/AbsoluutPosition.h" +#include "util/OptionalRef.h" #include "Collider.h" #include "CollisionSystem.h" @@ -139,9 +139,11 @@ CollisionSystem::collision_handler(CollisionInternal & data1, CollisionInternal = std::get>(data1.collider); const BoxCollider & collider2 = std::get>(data2.collider); - - vec2 collider_pos1 = AbsoluutPosition::get_position(data1.transform,collider1.offset); - vec2 collider_pos2 = AbsoluutPosition::get_position(data2.transform,collider2.offset); + + vec2 collider_pos1 + = AbsoluutPosition::get_position(data1.transform, collider1.offset); + vec2 collider_pos2 + = AbsoluutPosition::get_position(data2.transform, collider2.offset); resolution = this->get_box_box_resolution(collider1, collider2, collider_pos1, collider_pos2); break; @@ -151,8 +153,10 @@ CollisionSystem::collision_handler(CollisionInternal & data1, CollisionInternal = std::get>(data1.collider); const CircleCollider & collider2 = std::get>(data2.collider); - vec2 collider_pos1 = AbsoluutPosition::get_position(data1.transform,collider1.offset); - vec2 collider_pos2 = AbsoluutPosition::get_position(data2.transform,collider2.offset); + vec2 collider_pos1 + = AbsoluutPosition::get_position(data1.transform, collider1.offset); + vec2 collider_pos2 + = AbsoluutPosition::get_position(data2.transform, collider2.offset); resolution = -this->get_circle_box_resolution(collider2, collider1, collider_pos2, collider_pos1); break; @@ -162,8 +166,10 @@ CollisionSystem::collision_handler(CollisionInternal & data1, CollisionInternal = std::get>(data1.collider); const CircleCollider & collider2 = std::get>(data2.collider); - vec2 collider_pos1 = AbsoluutPosition::get_position(data1.transform,collider1.offset); - vec2 collider_pos2 = AbsoluutPosition::get_position(data2.transform,collider2.offset); + vec2 collider_pos1 + = AbsoluutPosition::get_position(data1.transform, collider1.offset); + vec2 collider_pos2 + = AbsoluutPosition::get_position(data2.transform, collider2.offset); resolution = this->get_circle_circle_resolution(collider1, collider2, collider_pos1, collider_pos2); break; @@ -173,8 +179,10 @@ CollisionSystem::collision_handler(CollisionInternal & data1, CollisionInternal = std::get>(data1.collider); const BoxCollider & collider2 = std::get>(data2.collider); - vec2 collider_pos1 = AbsoluutPosition::get_position(data1.transform,collider1.offset); - vec2 collider_pos2 = AbsoluutPosition::get_position(data2.transform,collider2.offset); + vec2 collider_pos1 + = AbsoluutPosition::get_position(data1.transform, collider1.offset); + vec2 collider_pos2 + = AbsoluutPosition::get_position(data2.transform, collider2.offset); resolution = this->get_circle_box_resolution(collider1, collider2, collider_pos1, collider_pos2); break; @@ -297,58 +305,67 @@ vec2 CollisionSystem::get_circle_box_resolution(const CircleCollider & circle_co void CollisionSystem::determine_collision_handler(CollisionInfo & info) { // Inverted collision info - CollisionInfo inverted = { - .this_collider = info.other_collider, - .this_transform = info.other_transform, - .this_rigidbody = info.other_rigidbody, - .this_metadata = info.other_metadata, - .other_collider = info.this_collider, - .other_transform = info.this_transform, - .other_rigidbody = info.this_rigidbody, - .other_metadata = info.this_metadata, - .resolution = -info.resolution, - .resolution_direction = info.resolution_direction, - }; + CollisionInfo inverted = { + .this_collider = info.other_collider, + .this_transform = info.other_transform, + .this_rigidbody = info.other_rigidbody, + .this_metadata = info.other_metadata, + .other_collider = info.this_collider, + .other_transform = info.this_transform, + .other_rigidbody = info.this_rigidbody, + .other_metadata = info.this_metadata, + .resolution = -info.resolution, + .resolution_direction = info.resolution_direction, + }; // If both objects are static skip handle call collision script - if(info.this_rigidbody.data.body_type == Rigidbody::BodyType::STATIC && info.other_rigidbody.data.body_type == Rigidbody::BodyType::STATIC) return; + if (info.this_rigidbody.data.body_type == Rigidbody::BodyType::STATIC + && info.other_rigidbody.data.body_type == Rigidbody::BodyType::STATIC) + return; // First body is not dynamic - if(info.this_rigidbody.data.body_type != Rigidbody::BodyType::DYNAMIC) - { - bool static_collision = info.this_rigidbody.data.body_type == Rigidbody::BodyType::STATIC && info.other_rigidbody.data.body_type == Rigidbody::BodyType::DYNAMIC; - bool kinematic_collision = info.this_rigidbody.data.body_type == Rigidbody::BodyType::KINEMATIC && info.other_rigidbody.data.body_type == Rigidbody::BodyType::DYNAMIC && info.this_rigidbody.data.kinematic_collision; - - - if(static_collision || kinematic_collision){ + if (info.this_rigidbody.data.body_type != Rigidbody::BodyType::DYNAMIC) { + bool static_collision + = info.this_rigidbody.data.body_type == Rigidbody::BodyType::STATIC + && info.other_rigidbody.data.body_type == Rigidbody::BodyType::DYNAMIC; + bool kinematic_collision + = info.this_rigidbody.data.body_type == Rigidbody::BodyType::KINEMATIC + && info.other_rigidbody.data.body_type == Rigidbody::BodyType::DYNAMIC + && info.this_rigidbody.data.kinematic_collision; + + if (static_collision || kinematic_collision) { // Static collision this->static_collision_handler(inverted); }; // Call scripts - this->call_collision_events(inverted,info); + this->call_collision_events(inverted, info); return; } // Second body is not dynamic - if(info.other_rigidbody.data.body_type != Rigidbody::BodyType::DYNAMIC) - { - bool static_collision = info.other_rigidbody.data.body_type == Rigidbody::BodyType::STATIC; - bool kinematic_collision = info.other_rigidbody.data.body_type == Rigidbody::BodyType::KINEMATIC && info.other_rigidbody.data.kinematic_collision; - if(static_collision || kinematic_collision) this->static_collision_handler(info); - this->call_collision_events(info,inverted); + if (info.other_rigidbody.data.body_type != Rigidbody::BodyType::DYNAMIC) { + bool static_collision + = info.other_rigidbody.data.body_type == Rigidbody::BodyType::STATIC; + bool kinematic_collision + = info.other_rigidbody.data.body_type == Rigidbody::BodyType::KINEMATIC + && info.other_rigidbody.data.kinematic_collision; + if (static_collision || kinematic_collision) this->static_collision_handler(info); + this->call_collision_events(info, inverted); return; } //dynamic this->dynamic_collision_handler(info); - this->call_collision_events(info,inverted); + this->call_collision_events(info, inverted); } -void CollisionSystem::call_collision_events(CollisionInfo & info,CollisionInfo & info_inverted){ +void CollisionSystem::call_collision_events(CollisionInfo & info, + CollisionInfo & info_inverted) { CollisionEvent data(info); CollisionEvent data_inverted(info_inverted); EventManager & emgr = this->mediator.event_manager; emgr.trigger_event(data, info.this_collider.game_object_id); - emgr.trigger_event(data_inverted, info_inverted.this_collider.game_object_id); + emgr.trigger_event(data_inverted, + info_inverted.this_collider.game_object_id); } void CollisionSystem::static_collision_handler(CollisionInfo & info) { @@ -400,9 +417,9 @@ void CollisionSystem::static_collision_handler(CollisionInfo & info) { } } -void CollisionSystem::dynamic_collision_handler(CollisionInfo & info){ - info.this_transform.position += info.resolution/2; - info.other_transform.position += -(info.resolution/2); +void CollisionSystem::dynamic_collision_handler(CollisionInfo & info) { + info.this_transform.position += info.resolution / 2; + info.other_transform.position += -(info.resolution / 2); switch (info.resolution_direction) { case Direction::BOTH: @@ -410,8 +427,7 @@ void CollisionSystem::dynamic_collision_handler(CollisionInfo & info){ info.this_rigidbody.data.linear_velocity = -info.this_rigidbody.data.linear_velocity * info.this_rigidbody.data.elastisity_coefficient; - } - else { + } else { info.this_rigidbody.data.linear_velocity = {0, 0}; } @@ -419,8 +435,7 @@ void CollisionSystem::dynamic_collision_handler(CollisionInfo & info){ info.other_rigidbody.data.linear_velocity = -info.other_rigidbody.data.linear_velocity * info.other_rigidbody.data.elastisity_coefficient; - } - else { + } else { info.other_rigidbody.data.linear_velocity = {0, 0}; } break; @@ -602,8 +617,8 @@ bool CollisionSystem::get_box_box_collision(const BoxCollider & box1, const BoxC const Rigidbody & rigidbody1, const Rigidbody & rigidbody2) const { // Get current positions of colliders - vec2 final_position1 = AbsoluutPosition::get_position(transform1,box1.offset); - vec2 final_position2 = AbsoluutPosition::get_position(transform2,box2.offset); + vec2 final_position1 = AbsoluutPosition::get_position(transform1, box1.offset); + vec2 final_position2 = AbsoluutPosition::get_position(transform2, box2.offset); // Scale dimensions vec2 scaled_box1 = box1.dimensions * transform1.scale; @@ -629,8 +644,8 @@ bool CollisionSystem::get_box_circle_collision(const BoxCollider & box1, const Rigidbody & rigidbody1, const Rigidbody & rigidbody2) const { // Get current positions of colliders - vec2 final_position1 = AbsoluutPosition::get_position(transform1,box1.offset); - vec2 final_position2 = AbsoluutPosition::get_position(transform2,circle2.offset); + vec2 final_position1 = AbsoluutPosition::get_position(transform1, box1.offset); + vec2 final_position2 = AbsoluutPosition::get_position(transform2, circle2.offset); // Scale dimensions vec2 scaled_box = box1.dimensions * transform1.scale; @@ -662,8 +677,8 @@ bool CollisionSystem::get_circle_circle_collision(const CircleCollider & circle1 const Rigidbody & rigidbody1, const Rigidbody & rigidbody2) const { // Get current positions of colliders - vec2 final_position1 = AbsoluutPosition::get_position(transform1,circle1.offset); - vec2 final_position2 = AbsoluutPosition::get_position(transform2,circle2.offset); + vec2 final_position1 = AbsoluutPosition::get_position(transform1, circle1.offset); + vec2 final_position2 = AbsoluutPosition::get_position(transform2, circle2.offset); // Scale dimensions float scaled_circle1 = circle1.radius * transform1.scale; @@ -679,5 +694,3 @@ bool CollisionSystem::get_circle_circle_collision(const CircleCollider & circle1 // Check if the distance between the centers is less than or equal to the sum of the radii return distance_squared < radius_sum * radius_sum; } - - diff --git a/src/crepe/system/CollisionSystem.h b/src/crepe/system/CollisionSystem.h index b802426..23752e1 100644 --- a/src/crepe/system/CollisionSystem.h +++ b/src/crepe/system/CollisionSystem.h @@ -188,7 +188,7 @@ private: * * \param info Collision information containing data about both colliders. */ - void call_collision_events(CollisionInfo & info,CollisionInfo & info_inverted); + void call_collision_events(CollisionInfo & info, CollisionInfo & info_inverted); /** * \brief Handles collisions involving static objects. diff --git a/src/crepe/system/ParticleSystem.cpp b/src/crepe/system/ParticleSystem.cpp index fb6cfd7..56f1dfd 100644 --- a/src/crepe/system/ParticleSystem.cpp +++ b/src/crepe/system/ParticleSystem.cpp @@ -48,7 +48,7 @@ void ParticleSystem::update() { void ParticleSystem::emit_particle(ParticleEmitter & emitter, const Transform & transform) { constexpr float DEG_TO_RAD = M_PI / 180.0; - + vec2 initial_position = AbsoluutPosition::get_position(transform, emitter.data.offset); float random_angle = this->generate_random_angle(emitter.data.min_angle, emitter.data.max_angle); diff --git a/src/crepe/system/RenderSystem.cpp b/src/crepe/system/RenderSystem.cpp index fcb52c3..c0717fc 100644 --- a/src/crepe/system/RenderSystem.cpp +++ b/src/crepe/system/RenderSystem.cpp @@ -106,7 +106,7 @@ void RenderSystem::render_normal(const Sprite & sprite, const Transform & tm) { SDLContext & ctx = this->mediator.sdl_context; ResourceManager & resource_manager = this->mediator.resource_manager; const Texture & res = resource_manager.get(sprite.source); - vec2 pos = AbsoluutPosition::get_position(tm,sprite.data.position_offset); + vec2 pos = AbsoluutPosition::get_position(tm, sprite.data.position_offset); ctx.draw(SDLContext::RenderContext{ .sprite = sprite, .texture = res, diff --git a/src/crepe/util/AbsoluutPosition.cpp b/src/crepe/util/AbsoluutPosition.cpp index 8be625e..296cc09 100644 --- a/src/crepe/util/AbsoluutPosition.cpp +++ b/src/crepe/util/AbsoluutPosition.cpp @@ -2,7 +2,7 @@ using namespace crepe; -vec2 AbsoluutPosition::get_position(const Transform & transform,const vec2 & offset) { +vec2 AbsoluutPosition::get_position(const Transform & transform, const vec2 & offset) { // Get the rotation in radians float radians1 = transform.rotation * (M_PI / 180.0); @@ -18,4 +18,3 @@ vec2 AbsoluutPosition::get_position(const Transform & transform,const vec2 & off // Final positions considering scaling and rotation return (transform.position + vec2(rotated_total_offset_x1, rotated_total_offset_y1)); } - diff --git a/src/crepe/util/AbsoluutPosition.h b/src/crepe/util/AbsoluutPosition.h index 4441f90..30a7f93 100644 --- a/src/crepe/util/AbsoluutPosition.h +++ b/src/crepe/util/AbsoluutPosition.h @@ -1,17 +1,14 @@ #pragma once - #include "api/Transform.h" #include "types.h" namespace crepe { - class AbsoluutPosition { public: - static vec2 get_position(const Transform & transform,const vec2 & offset); - + static vec2 get_position(const Transform & transform, const vec2 & offset); }; } // namespace crepe diff --git a/src/example/game.cpp b/src/example/game.cpp index b30166e..01a509f 100644 --- a/src/example/game.cpp +++ b/src/example/game.cpp @@ -238,7 +238,7 @@ public: .sorting_in_layer = 2, .order_in_layer = 2, .size = {20, 20}, - .position_offset = {0,-10}, + .position_offset = {0, -10}, }); //add circle with cirlcecollider deactiveated diff --git a/src/test/CollisionTest.cpp b/src/test/CollisionTest.cpp index 43bf77d..3cb7f33 100644 --- a/src/test/CollisionTest.cpp +++ b/src/test/CollisionTest.cpp @@ -290,9 +290,8 @@ TEST_F(CollisionTest, collision_box_box_static_both) { EXPECT_EQ(ev.info.resolution.y, 10); EXPECT_EQ(ev.info.resolution_direction, crepe::CollisionSystem::Direction::BOTH); }; - script_object2_ref->test_fn = [&collision_happend](const CollisionEvent & ev) { - collision_happend = true; - }; + script_object2_ref->test_fn + = [&collision_happend](const CollisionEvent & ev) { collision_happend = true; }; EXPECT_FALSE(collision_happend); Transform & tf = this->mgr.get_components_by_id(1).front().get(); tf.position = {50, 30}; diff --git a/src/test/Profiling.cpp b/src/test/Profiling.cpp index 1585061..16736b8 100644 --- a/src/test/Profiling.cpp +++ b/src/test/Profiling.cpp @@ -219,19 +219,19 @@ TEST_F(DISABLED_ProfilingTest, Profiling_3) { .order_in_layer = 1, .size = {.y = 500}, }); - auto & test = gameobject.add_component(test_sprite,ParticleEmitter::Data{ - .max_particles = 10, - .emission_rate = 100, - .end_lifespan = 100000, - .boundary{ - .width = 1000, - .height = 1000, - .offset = vec2{0, 0}, - .reset_on_exit = false, - }, - - } - ); + auto & test = gameobject.add_component( + test_sprite, ParticleEmitter::Data{ + .max_particles = 10, + .emission_rate = 100, + .end_lifespan = 100000, + .boundary{ + .width = 1000, + .height = 1000, + .offset = vec2{0, 0}, + .reset_on_exit = false, + }, + + }); } render_sys.update(); this->game_object_count++; -- cgit v1.2.3 From b4335bd670cb7f3f622e6ab701123cfbabd15d37 Mon Sep 17 00:00:00 2001 From: Loek Le Blansch Date: Tue, 17 Dec 2024 15:32:57 +0100 Subject: fix tests + nitpick #77 --- src/crepe/facade/FontFacade.cpp | 32 +++++++++++++------------------- src/test/InputTest.cpp | 7 ++++++- 2 files changed, 19 insertions(+), 20 deletions(-) (limited to 'src/test') diff --git a/src/crepe/facade/FontFacade.cpp b/src/crepe/facade/FontFacade.cpp index 5db06d2..d47095f 100644 --- a/src/crepe/facade/FontFacade.cpp +++ b/src/crepe/facade/FontFacade.cpp @@ -10,44 +10,38 @@ using namespace std; using namespace crepe; FontFacade::FontFacade() { - if (!FcInit()) { + if (!FcInit()) throw runtime_error("Failed to initialize Fontconfig."); - } } FontFacade::~FontFacade() { FcFini(); } Asset FontFacade::get_font_asset(const string & font_family) { - FcPattern * raw_pattern = FcNameParse(reinterpret_cast(font_family.c_str())); - if (!raw_pattern) { - throw runtime_error("Failed to create font pattern."); - } + if (raw_pattern == NULL) throw runtime_error("Failed to create font pattern."); - std::unique_ptr> pattern( - raw_pattern, [](FcPattern * p) { FcPatternDestroy(p); }); + unique_ptr> pattern{ + raw_pattern, [](FcPattern * p) { FcPatternDestroy(p); } + }; FcConfig * config = FcConfigGetCurrent(); - if (!config) { - throw runtime_error("Failed to get current Fontconfig configuration."); - } + if (config == NULL) throw runtime_error("Failed to get current Fontconfig configuration."); FcResult result; FcPattern * raw_matched_pattern = FcFontMatch(config, pattern.get(), &result); - if (!raw_matched_pattern) { - throw runtime_error("No matching font found."); - } + if (raw_matched_pattern == NULL) throw runtime_error("No matching font found."); - std::unique_ptr> matched_pattern( - raw_matched_pattern, [](FcPattern * p) { FcPatternDestroy(p); }); + unique_ptr> matched_pattern = { + raw_matched_pattern, [](FcPattern * p) { FcPatternDestroy(p); } + }; FcChar8 * file_path = nullptr; - if (FcPatternGetString(matched_pattern.get(), FC_FILE, 0, &file_path) != FcResultMatch - || !file_path) { + FcResult res = FcPatternGetString(matched_pattern.get(), FC_FILE, 0, &file_path); + if (res != FcResultMatch || file_path == NULL) throw runtime_error("Failed to get font file path."); - } string font_file_path = reinterpret_cast(file_path); return Asset(font_file_path); } + diff --git a/src/test/InputTest.cpp b/src/test/InputTest.cpp index d893276..2d844d4 100644 --- a/src/test/InputTest.cpp +++ b/src/test/InputTest.cpp @@ -1,7 +1,11 @@ -#include "system/RenderSystem.h" #include + +#include +#include + #define protected public #define private public + #include "api/KeyCodes.h" #include "manager/ComponentManager.h" #include "manager/EventManager.h" @@ -29,6 +33,7 @@ public: SDLContext sdl_context{mediator}; InputSystem input_system{mediator}; + ResourceManager resman{mediator}; RenderSystem render{mediator}; EventManager event_manager{mediator}; //GameObject camera; -- cgit v1.2.3 From eb9c76082d7d0ee0c3e55cb8eadfa5f8978bd8f2 Mon Sep 17 00:00:00 2001 From: WBoerenkamps Date: Tue, 17 Dec 2024 20:12:30 +0100 Subject: button improvements --- src/crepe/api/Button.cpp | 6 ++-- src/crepe/api/Button.h | 50 ++++++++-------------------------- src/crepe/api/Event.h | 3 +- src/crepe/system/InputSystem.cpp | 26 +++++++++--------- src/crepe/system/InputSystem.h | 22 +++++++++++++++ src/test/InputTest.cpp | 59 ++++++++++++++++++++++++++-------------- 6 files changed, 89 insertions(+), 77 deletions(-) (limited to 'src/test') diff --git a/src/crepe/api/Button.cpp b/src/crepe/api/Button.cpp index 305922c..40153c9 100644 --- a/src/crepe/api/Button.cpp +++ b/src/crepe/api/Button.cpp @@ -2,9 +2,7 @@ namespace crepe { -Button::Button(game_object_id_t id, const vec2 & dimensions, const vec2 & offset, - const std::function & on_click) - : UIObject(id, dimensions, offset), - on_click(on_click) {} +Button::Button(game_object_id_t id, const vec2 & dimensions, const vec2 & offset) + : UIObject(id, dimensions, offset) {} } // namespace crepe diff --git a/src/crepe/api/Button.h b/src/crepe/api/Button.h index e97f884..5d4156b 100644 --- a/src/crepe/api/Button.h +++ b/src/crepe/api/Button.h @@ -5,18 +5,21 @@ #include "UIObject.h" #include "Event.h" #include "Metadata.h" + namespace crepe { /** - * \brief Event triggered when a button is pressed + * \brief Button component. + * + * This component creates a clickable surface at the transform location with the specified width and height. + * + * The Button can be used in scripts by subscribing a EventHandler to the following events: + * - **ButtonPressEvent**: Triggered when the surface is clicked with the mouse. Contains GameObject metadata. + * - **MouseEnterEvent**: Triggered when the mouse enters the button area. Contains GameObject metadata. + * - **MouseExitEvent**: Triggered when the mouse leaves the button area. Contains GameObject metadata. + * \see EventManager * */ -class ButtonPressEvent : public Event{ - public: - - -} -//! Represents a clickable UI button, derived from the UiObject class. class Button : public UIObject { public: /** @@ -25,43 +28,14 @@ public: * \param id The unique ID of the game object associated with this button. * \param dimensions The width and height of the UIObject * \param offset The offset relative this GameObjects Transform - * \param on_click callback function that will be invoked when the button is clicked. */ - Button(game_object_id_t id, const vec2 & dimensions, const vec2 & offset, - const std::function & on_click); - - // TODO: create separate toggle button class - /** - * \brief The callback function to be executed when the button is clicked. - * - * This function is invoked whenever the button is clicked. It can be set to any - * function that matches the signature `void()`. - */ - std::function on_click = nullptr; - - /** - * \brief Callback function to be executed when the mouse enters the button's boundaries. - * - * This function is triggered when the mouse cursor moves over the button, allowing - * custom actions like visual effects, highlighting, or sound effects. - */ - std::function on_mouse_enter = nullptr; - - /** - * \brief Callback function to be executed when the mouse exits the button's boundaries. - * - * This function is triggered when the mouse cursor moves out of the button's area, - * allowing custom actions like resetting visual effects or playing exit-related effects. - */ - std::function on_mouse_exit = nullptr; + Button(game_object_id_t id, const vec2 & dimensions, const vec2 & offset); private: - //! friend relation for is_pressed and hover variables + //! friend relation hover variable friend class InputSystem; //! Indicates whether the mouse is currently hovering over the button bool hover = false; - -public: }; } // namespace crepe diff --git a/src/crepe/api/Event.h b/src/crepe/api/Event.h index b0dd931..a03bb54 100644 --- a/src/crepe/api/Event.h +++ b/src/crepe/api/Event.h @@ -3,9 +3,10 @@ #include -#include "api/KeyCodes.h" #include "types.h" +#include "api/KeyCodes.h" + namespace crepe { /** diff --git a/src/crepe/system/InputSystem.cpp b/src/crepe/system/InputSystem.cpp index fca540f..5d1537d 100644 --- a/src/crepe/system/InputSystem.cpp +++ b/src/crepe/system/InputSystem.cpp @@ -155,28 +155,27 @@ void InputSystem::handle_non_mouse_event(const EventData & event) { void InputSystem::handle_move(const EventData & event_data, const vec2 & mouse_pos) { ComponentManager & mgr = this->mediator.component_manager; - + EventManager& event_mgr = this->mediator.event_manager; RefVector