From 123aa2b7dcfdd1a6322c9c6c8cf22ce0e46b69a1 Mon Sep 17 00:00:00 2001 From: NukeBird Date: Sun, 16 Feb 2025 21:18:39 +0300 Subject: [PATCH] Change .clang-format --- .clang-format | 9 ++++ tests/zecsy.cpp | 106 +++++++++++++++++++----------------------------- zecsy.hpp | 81 ++++++++++++++++++------------------ 3 files changed, 92 insertions(+), 104 deletions(-) diff --git a/.clang-format b/.clang-format index f62feeb..2d7c3fb 100644 --- a/.clang-format +++ b/.clang-format @@ -3,3 +3,12 @@ BreakBeforeBraces: Allman AccessModifierOffset: -4 IndentWidth: 4 AlwaysBreakTemplateDeclarations: Yes +NamespaceIndentation: All +SpaceAfterTemplateKeyword: false +PointerAlignment: Left +ReferenceAlignment: Left +SpaceAfterControlStatementKeyword: false +AllowShortFunctionsOnASingleLine: false +SpaceBeforeCtorInitializerColon: false +SpaceBeforeInheritanceColon: false +SpaceBeforeRangeBasedForLoopColon: false diff --git a/tests/zecsy.cpp b/tests/zecsy.cpp index ab6261e..eb8da86 100644 --- a/tests/zecsy.cpp +++ b/tests/zecsy.cpp @@ -1,5 +1,4 @@ #include -#include #include #define CATCH_CONFIG_MAIN #include @@ -11,26 +10,26 @@ using namespace zecsy; TEST_CASE("Create a single entity and verify its existence") { world w; - + auto e = w.make_entity(); - + REQUIRE(w.is_alive(e)); } TEST_CASE("Destroy an entity and ensure it no longer exists in the world") { world w; - + auto e = w.make_entity(); w.destroy_entity(e); - + REQUIRE_FALSE(w.is_alive(e)); } TEST_CASE("Entity #0 should be reserved and never used") { world w; - + auto e = w.make_entity(); REQUIRE(e != 0); @@ -39,7 +38,6 @@ TEST_CASE("Entity #0 should be reserved and never used") struct ChoosenOne { - }; TEST_CASE("Entity shouldn't have a component that wasn't attached to it") @@ -60,7 +58,8 @@ TEST_CASE("Attempt of getting non-owned component should throw") REQUIRE_THROWS(w.get(e)); } -TEST_CASE("Attach a simple component to an entity and verify it is correctly associated") +TEST_CASE("Attach a simple component to an entity and verify it is correctly " + "associated") { world w; @@ -74,13 +73,14 @@ TEST_CASE("Attach a simple component to an entity and verify it is correctly ass REQUIRE(w.has(e2)); } - -struct Name + +struct Name { std::string value; }; -TEST_CASE("Retrieve a component from an entity and verify its data matches what was set") +TEST_CASE("Retrieve a component from an entity and verify its data matches " + "what was set") { world w; @@ -94,7 +94,8 @@ TEST_CASE("Retrieve a component from an entity and verify its data matches what REQUIRE(w.get(e).value == "super-zecsy!"); } -TEST_CASE("Remove a component from an entity and verify it is no longer attached") +TEST_CASE( + "Remove a component from an entity and verify it is no longer attached") { world w; @@ -112,7 +113,7 @@ TEST_CASE("Remove a component from an entity and verify it is no longer attached TEST_CASE("Addresses of removed components should be reused") { - world w; + world w; std::vector entities; std::vector addr; @@ -133,7 +134,7 @@ TEST_CASE("Addresses of removed components should be reused") addr.emplace_back(&w.get(entities[j])); } } - else + else { for(int j = 0; j < N; ++j) { @@ -149,7 +150,8 @@ TEST_CASE("Addresses of removed components should be reused") } } -TEST_CASE("Attach multiple components to an entity and verify all are correctly stored and retrievable") +TEST_CASE("Attach multiple components to an entity and verify all are " + "correctly stored and retrievable") { world w; @@ -165,9 +167,10 @@ TEST_CASE("Attach multiple components to an entity and verify all are correctly REQUIRE_FALSE(w.has(e)); } -TEST_CASE("Create a simple system that processes entities with a specific component and verify it executes correctly") +TEST_CASE("Create a simple system that processes entities with a specific " + "component and verify it executes correctly") { - struct Component + struct Component { int value = 0; }; @@ -175,28 +178,26 @@ TEST_CASE("Create a simple system that processes entities with a specific compon world w; auto e0 = w.make_entity(), e1 = w.make_entity(); - w.set(e0); //or e0.set(Component{}) + w.set(e0); // or e0.set(Component{}) w.set(e1, Component{20}); REQUIRE(w.get(e0).value == 0); REQUIRE(w.get(e1).value == 20); - + /* * Really wanna deduce it to w.query([](Component&){}), * but I have some troubles with it */ - w.query([](Component& c) - { - c.value++; - }); + w.query([](Component& c) { c.value++; }); REQUIRE(w.get(e0).value == 1); REQUIRE(w.get(e1).value == 21); } -TEST_CASE("Test a systems ability to query and process only entities with a specific combination of components") +TEST_CASE("Test a systems ability to query and process only entities with a " + "specific combination of components") { - struct C0 + struct C0 { int value = 0; }; @@ -250,25 +251,19 @@ TEST_CASE("Systems execute at correct frequencies") int slow_count = 0; // Add a fast system (60 Hz) - scheduler.add_system(60, [&](float dt) - { - fast_count++; - }); + scheduler.add_system(60, [&](float dt) { fast_count++; }); // Add a slow system (1 Hz) - scheduler.add_system(1, [&](float dt) - { - slow_count++; - }); + scheduler.add_system(1, [&](float dt) { slow_count++; }); // Simulate 2 seconds of updates at 120 FPS - for (int i = 0; i < 240; ++i) + for(int i = 0; i < 240; ++i) { scheduler.update(1.0f / 120.0f); } // Verify counts - REQUIRE(fast_count == 120); // 60 Hz system should execute 60 times + REQUIRE(fast_count == 120); // 60 Hz system should execute 60 times REQUIRE(slow_count == 2); // 1 Hz system should execute 1 time } @@ -280,13 +275,10 @@ TEST_CASE("Systems handle zero-frequency gracefully") int zero_count = 0; // Add a zero-frequency system (should never execute) - scheduler.add_system(0, [&](float dt) - { - zero_count++; - }); + scheduler.add_system(0, [&](float dt) { zero_count++; }); // Simulate 1 second of updates at 60 FPS - for (int i = 0; i < 60; ++i) + for(int i = 0; i < 60; ++i) { scheduler.update(1.0f / 60.0f); } @@ -303,13 +295,10 @@ TEST_CASE("Systems handle varying update rates") int varying_count = 0; // Add a system with varying frequency (10 Hz) - scheduler.add_system(10, [&](float dt) - { - varying_count++; - }); + scheduler.add_system(10, [&](float dt) { varying_count++; }); // Simulate 1 second of updates at 30 FPS - for (int i = 0; i < 30; ++i) + for(int i = 0; i < 30; ++i) { scheduler.update(1.0f / 30.0f); } @@ -326,10 +315,7 @@ TEST_CASE("Systems handle large time steps") int large_step_count = 0; // Add a system (1 Hz) - scheduler.add_system(1, [&](float dt) - { - large_step_count++; - }); + scheduler.add_system(1, [&](float dt) { large_step_count++; }); // Simulate a large time step (2 seconds) scheduler.update(2.0f); @@ -353,7 +339,7 @@ TEST_CASE("Systems handle multiple frequencies") scheduler.add_system(1, [&](float dt) { slow_count++; }); // Simulate 1 second of updates at 120 FPS - for (int i = 0; i < 120; ++i) + for(int i = 0; i < 120; ++i) { scheduler.update(1.0f / 120.0f); } @@ -372,18 +358,16 @@ TEST_CASE("Systems handle fractional frequencies") int fractional_count = 0; // Add a system with fractional frequency (0.5 Hz) - scheduler.add_system(0.5f, [&](float dt) - { - fractional_count++; - }); + scheduler.add_system(0.5f, [&](float dt) { fractional_count++; }); // Simulate 4 seconds of updates at 60 FPS - for (int i = 0; i < 240; ++i) + for(int i = 0; i < 240; ++i) { scheduler.update(1.0f / 60.0f); } - // Verify fractional-frequency system executes twice (0.5 Hz = 2 times in 4 seconds) + // Verify fractional-frequency system executes twice (0.5 Hz = 2 times in 4 + // seconds) REQUIRE(fractional_count == 2); } @@ -395,10 +379,7 @@ TEST_CASE("Systems handle zero delta time") int zero_dt_count = 0; // Add a system (1 Hz) - scheduler.add_system(1, [&](float dt) - { - zero_dt_count++; - }); + scheduler.add_system(1, [&](float dt) { zero_dt_count++; }); // Simulate zero delta time scheduler.update(0.0f); @@ -415,10 +396,7 @@ TEST_CASE("Systems handle negative delta time") int count = 0; // Add a system (1 Hz) - scheduler.add_system(1, [&](float dt) - { - count++; - }); + scheduler.add_system(1, [&](float dt) { count++; }); // Simulate negative delta time scheduler.update(-1.0f); diff --git a/zecsy.hpp b/zecsy.hpp index 82a38fc..ceaf311 100644 --- a/zecsy.hpp +++ b/zecsy.hpp @@ -5,23 +5,22 @@ #include #include #include +#include #include #include #include -#include -#include -namespace zecsy +namespace zecsy { using entity_id = uint64_t; /* - * unordered_set is also an option. But probably sorting ids may be - * beneficial for queries, because it might increase the chance of reusing - * cpu cache (aka "required components were close to each other"). Definitely - * should play around with it + * unordered_set is also an option. But probably sorting ids may be + * beneficial for queries, because it might increase the chance of reusing + * cpu cache (aka "required components were close to each other"). + * Definitely should play around with it */ - using entities_set = std::set; + using entities_set = std::set; class component_storage final { @@ -37,38 +36,40 @@ namespace zecsy template void set(entity_id e); - + template void set(entity_id e, const T& comp); - + template void set(entity_id e); template - void set(entity_id e, const First& comp0, const Second& comp1, - const Rest&... rest_comps); - + void set(entity_id e, const First& comp0, const Second& comp1, + const Rest&... rest_comps); + template void remove(entity_id e); - + template void remove(entity_id e); + private: using comp_index = std::type_index; - using comp_to_entities_set = std::unordered_map; + using comp_to_entities_set = + std::unordered_map; using entity_to_index = std::unordered_map; - using comp_to_entity_dict = std::unordered_map; - - using comp_to_storage = std::unordered_map>; + using comp_to_entity_dict = + std::unordered_map; - using comp_to_reusable_ids = std::unordered_map>; + using comp_to_storage = + std::unordered_map>; + + using comp_to_reusable_ids = + std::unordered_map>; comp_to_entities_set entities_dict; - comp_to_entity_dict indices_dict; + comp_to_entity_dict indices_dict; comp_to_storage storage_dict; comp_to_reusable_ids reusable_id_queues; }; @@ -80,9 +81,10 @@ namespace zecsy void add_system(int freq, auto&& func); - void update(float dt); + void update(float dt); + private: - struct system_handler + struct system_handler { double interval; double accumulator = 0.0f; @@ -97,7 +99,7 @@ namespace zecsy public: entity_id make_entity(); void destroy_entity(entity_id e); - bool is_alive(entity_id e) const; + bool is_alive(entity_id e) const; template bool has(entity_id e) const; @@ -107,7 +109,7 @@ namespace zecsy template void set(entity_id e); - + template void set(entity_id e, const T&... comps); @@ -116,6 +118,7 @@ namespace zecsy template void query(auto&& system); + private: entities_set alive_entities; entity_id entity_counter = 0; @@ -155,12 +158,12 @@ namespace zecsy { if(!has(e)) { - throw std::runtime_error(std::format("Entity #{} doesn't have {}", - e, typeid(T).name())); + throw std::runtime_error( + std::format("Entity #{} doesn't have {}", e, typeid(T).name())); } auto index = indices_dict[typeid(T)].at(e); - + auto* ptr = reinterpret_cast(&storage_dict[typeid(T)][0]); ptr += index; @@ -203,7 +206,7 @@ namespace zecsy indices_dict[typeid(T)][e] = index; } - + template inline void component_storage::set(entity_id e) { @@ -252,7 +255,7 @@ namespace zecsy { return has(e) && has(e) && (has(e) && ...); } - + template inline void component_storage::set(entity_id e) { @@ -262,8 +265,9 @@ namespace zecsy } template - inline void component_storage::set(entity_id e, const First& comp0, const Second& comp1, - const Rest&... rest_comps) + inline void component_storage::set(entity_id e, const First& comp0, + const Second& comp1, + const Rest&... rest_comps) { set(e, comp0); set(e, comp1); @@ -292,11 +296,8 @@ namespace zecsy inline void system_scheduler::add_system(float freq, auto&& func) { - systems.push_back({ - 1.0f / freq, - 0.0f, - std::forward(func) - }); + systems.emplace_back(1.0f / freq, 0.0f, + std::forward(func)); } inline void system_scheduler::add_system(int freq, auto&& func) @@ -318,4 +319,4 @@ namespace zecsy } } } -}; +}; // namespace zecsy