Compare commits
No commits in common. "3aaa4557c6528ea2da6040f7178143900443ead8" and "c7f04c9d21cacb1264294c7e9e541b4b236e9bdb" have entirely different histories.
3aaa4557c6
...
c7f04c9d21
2 changed files with 45 additions and 63 deletions
|
@ -1,4 +1,5 @@
|
||||||
#include <catch2/catch_test_macros.hpp>
|
#include <catch2/catch_test_macros.hpp>
|
||||||
|
#include <string>
|
||||||
#define CATCH_CONFIG_MAIN
|
#define CATCH_CONFIG_MAIN
|
||||||
#include <catch2/catch_all.hpp>
|
#include <catch2/catch_all.hpp>
|
||||||
|
|
||||||
|
@ -73,9 +74,9 @@ TEST_CASE("Attach a simple component to an entity and verify it is correctly "
|
||||||
REQUIRE(w.has<ChoosenOne>(e2));
|
REQUIRE(w.has<ChoosenOne>(e2));
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Comp
|
struct Name
|
||||||
{
|
{
|
||||||
int v = 0;
|
std::string value;
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_CASE("Retrieve a component from an entity and verify its data matches "
|
TEST_CASE("Retrieve a component from an entity and verify its data matches "
|
||||||
|
@ -84,13 +85,13 @@ TEST_CASE("Retrieve a component from an entity and verify its data matches "
|
||||||
world w;
|
world w;
|
||||||
|
|
||||||
auto e = w.make_entity();
|
auto e = w.make_entity();
|
||||||
w.set(e, Comp());
|
w.set(e, Name{"zecsy!"});
|
||||||
|
|
||||||
REQUIRE(w.get<Comp>(e).v == 0);
|
REQUIRE(w.get<Name>(e).value == "zecsy!");
|
||||||
|
|
||||||
w.get<Comp>(e).v = 77;
|
w.get<Name>(e).value = "super-zecsy!";
|
||||||
|
|
||||||
REQUIRE(w.get<Comp>(e).v == 77);
|
REQUIRE(w.get<Name>(e).value == "super-zecsy!");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE(
|
TEST_CASE(
|
||||||
|
@ -160,15 +161,15 @@ TEST_CASE("Attach multiple components to an entity and verify all are "
|
||||||
world w;
|
world w;
|
||||||
|
|
||||||
auto e = w.make_entity();
|
auto e = w.make_entity();
|
||||||
w.set(e, ChoosenOne{}, Comp{});
|
w.set(e, ChoosenOne{}, Name{"zecsy"});
|
||||||
|
|
||||||
REQUIRE(w.has<ChoosenOne, Comp>(e));
|
REQUIRE(w.has<ChoosenOne, Name>(e));
|
||||||
|
|
||||||
w.remove<ChoosenOne, Comp>(e);
|
w.remove<ChoosenOne, Name>(e);
|
||||||
|
|
||||||
REQUIRE_FALSE(w.has<ChoosenOne, Comp>(e));
|
REQUIRE_FALSE(w.has<ChoosenOne, Name>(e));
|
||||||
REQUIRE_FALSE(w.has<ChoosenOne>(e));
|
REQUIRE_FALSE(w.has<ChoosenOne>(e));
|
||||||
REQUIRE_FALSE(w.has<Comp>(e));
|
REQUIRE_FALSE(w.has<Name>(e));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("Create a simple system that processes entities with a specific "
|
TEST_CASE("Create a simple system that processes entities with a specific "
|
||||||
|
|
83
zecsy.hpp
83
zecsy.hpp
|
@ -1,13 +1,11 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <concepts>
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <format>
|
#include <format>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <type_traits>
|
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
@ -15,23 +13,6 @@ namespace zecsy
|
||||||
{
|
{
|
||||||
using entity_id = uint64_t;
|
using entity_id = uint64_t;
|
||||||
|
|
||||||
/*
|
|
||||||
* Actually, not a pure POD. Gotta figure out a better name
|
|
||||||
*/
|
|
||||||
template<typename... T>
|
|
||||||
concept Component = []
|
|
||||||
{
|
|
||||||
static_assert((std::is_default_constructible_v<T> && ...),
|
|
||||||
"Should have a default constructor");
|
|
||||||
static_assert((std::is_trivially_copyable_v<T> && ...),
|
|
||||||
"Should be trivially copyable");
|
|
||||||
static_assert((std::is_trivially_destructible_v<T> && ...),
|
|
||||||
"Should be trivially destructible");
|
|
||||||
static_assert((std::is_standard_layout_v<T> && ...),
|
|
||||||
"Should have standard layout");
|
|
||||||
return true;
|
|
||||||
}();
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Using std::set for entities_set to maintain sorted order, which can
|
* Using std::set for entities_set to maintain sorted order, which can
|
||||||
* improve cache locality during queries and iterations.
|
* improve cache locality during queries and iterations.
|
||||||
|
@ -41,32 +22,32 @@ namespace zecsy
|
||||||
class component_storage final
|
class component_storage final
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
template<Component T>
|
template<typename T>
|
||||||
bool has(entity_id e) const;
|
bool has(entity_id e) const;
|
||||||
|
|
||||||
template<Component First, Component Second, Component... Rest>
|
template<typename First, typename Second, typename... Rest>
|
||||||
bool has(entity_id e) const;
|
bool has(entity_id e) const;
|
||||||
|
|
||||||
template<Component T>
|
template<typename T>
|
||||||
T& get(entity_id e);
|
T& get(entity_id e);
|
||||||
|
|
||||||
template<Component T>
|
template<typename T>
|
||||||
void set(entity_id e);
|
void set(entity_id e);
|
||||||
|
|
||||||
template<Component T>
|
template<typename T>
|
||||||
void set(entity_id e, const T& comp);
|
void set(entity_id e, const T& comp);
|
||||||
|
|
||||||
template<Component First, Component Second, Component... Rest>
|
template<typename First, typename Second, typename... Rest>
|
||||||
void set(entity_id e);
|
void set(entity_id e);
|
||||||
|
|
||||||
template<Component First, Component Second, Component... Rest>
|
template<typename First, typename Second, typename... Rest>
|
||||||
void set(entity_id e, const First& comp0, const Second& comp1,
|
void set(entity_id e, const First& comp0, const Second& comp1,
|
||||||
const Rest&... rest_comps);
|
const Rest&... rest_comps);
|
||||||
|
|
||||||
template<Component T>
|
template<typename T>
|
||||||
void remove(entity_id e);
|
void remove(entity_id e);
|
||||||
|
|
||||||
template<Component First, Component Second, Component... Rest>
|
template<typename First, typename Second, typename... Rest>
|
||||||
void remove(entity_id e);
|
void remove(entity_id e);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -94,7 +75,7 @@ namespace zecsy
|
||||||
|
|
||||||
inline component_storage::comp_id component_storage::next_component_id = 0;
|
inline component_storage::comp_id component_storage::next_component_id = 0;
|
||||||
|
|
||||||
template<Component T>
|
template<typename T>
|
||||||
inline bool component_storage::has(entity_id e) const
|
inline bool component_storage::has(entity_id e) const
|
||||||
{
|
{
|
||||||
auto id = get_component_id<T>();
|
auto id = get_component_id<T>();
|
||||||
|
@ -105,7 +86,7 @@ namespace zecsy
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<Component T>
|
template<typename T>
|
||||||
inline T& component_storage::get(entity_id e)
|
inline T& component_storage::get(entity_id e)
|
||||||
{
|
{
|
||||||
auto id = get_component_id<T>();
|
auto id = get_component_id<T>();
|
||||||
|
@ -120,7 +101,7 @@ namespace zecsy
|
||||||
return *reinterpret_cast<T*>(&pool.data[index * sizeof(T)]);
|
return *reinterpret_cast<T*>(&pool.data[index * sizeof(T)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<Component T>
|
template<typename T>
|
||||||
inline void component_storage::set(entity_id e, const T& comp)
|
inline void component_storage::set(entity_id e, const T& comp)
|
||||||
{
|
{
|
||||||
auto id = get_component_id<T>();
|
auto id = get_component_id<T>();
|
||||||
|
@ -143,13 +124,13 @@ namespace zecsy
|
||||||
pool.index_to_entity[index] = e;
|
pool.index_to_entity[index] = e;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<Component T>
|
template<typename T>
|
||||||
inline void component_storage::set(entity_id e)
|
inline void component_storage::set(entity_id e)
|
||||||
{
|
{
|
||||||
set(e, T{});
|
set(e, T{});
|
||||||
}
|
}
|
||||||
|
|
||||||
template<Component T>
|
template<typename T>
|
||||||
inline void component_storage::remove(entity_id e)
|
inline void component_storage::remove(entity_id e)
|
||||||
{
|
{
|
||||||
auto id = get_component_id<T>();
|
auto id = get_component_id<T>();
|
||||||
|
@ -172,13 +153,13 @@ namespace zecsy
|
||||||
pool.index_to_entity.erase(index);
|
pool.index_to_entity.erase(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<Component First, Component Second, Component... Rest>
|
template<typename First, typename Second, typename... Rest>
|
||||||
inline bool component_storage::has(entity_id e) const
|
inline bool component_storage::has(entity_id e) const
|
||||||
{
|
{
|
||||||
return has<First>(e) && has<Second>(e) && (has<Rest>(e) && ...);
|
return has<First>(e) && has<Second>(e) && (has<Rest>(e) && ...);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<Component First, Component Second, Component... Rest>
|
template<typename First, typename Second, typename... Rest>
|
||||||
inline void component_storage::set(entity_id e)
|
inline void component_storage::set(entity_id e)
|
||||||
{
|
{
|
||||||
set(e, First{});
|
set(e, First{});
|
||||||
|
@ -186,7 +167,7 @@ namespace zecsy
|
||||||
(set(e, Rest{}), ...);
|
(set(e, Rest{}), ...);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<Component First, Component Second, Component... Rest>
|
template<typename First, typename Second, typename... Rest>
|
||||||
inline void component_storage::set(entity_id e, const First& comp0,
|
inline void component_storage::set(entity_id e, const First& comp0,
|
||||||
const Second& comp1,
|
const Second& comp1,
|
||||||
const Rest&... rest_comps)
|
const Rest&... rest_comps)
|
||||||
|
@ -196,7 +177,7 @@ namespace zecsy
|
||||||
(set(e, rest_comps), ...);
|
(set(e, rest_comps), ...);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<Component First, Component Second, Component... Rest>
|
template<typename First, typename Second, typename... Rest>
|
||||||
inline void component_storage::remove(entity_id e)
|
inline void component_storage::remove(entity_id e)
|
||||||
{
|
{
|
||||||
remove<First>(e);
|
remove<First>(e);
|
||||||
|
@ -257,23 +238,23 @@ namespace zecsy
|
||||||
void destroy_entity(entity_id e);
|
void destroy_entity(entity_id e);
|
||||||
bool is_alive(entity_id e) const;
|
bool is_alive(entity_id e) const;
|
||||||
|
|
||||||
template<Component... T>
|
template<typename... T>
|
||||||
bool has(entity_id e) const;
|
bool has(entity_id e) const;
|
||||||
|
|
||||||
template<Component T>
|
template<typename T>
|
||||||
T& get(entity_id e);
|
T& get(entity_id e);
|
||||||
|
|
||||||
template<Component... T>
|
template<typename... T>
|
||||||
void set(entity_id e);
|
void set(entity_id e);
|
||||||
|
|
||||||
template<Component... T>
|
template<typename... T>
|
||||||
void set(entity_id e, const T&... comps);
|
void set(entity_id e, const T&... comps);
|
||||||
|
|
||||||
template<Component... T>
|
template<typename... T>
|
||||||
void remove(entity_id e);
|
void remove(entity_id e);
|
||||||
|
|
||||||
template<Component... T>
|
template<typename... T>
|
||||||
void query(std::invocable<T&...> auto&& system);
|
void query(auto&& system);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
entities_set alive_entities;
|
entities_set alive_entities;
|
||||||
|
@ -298,38 +279,38 @@ namespace zecsy
|
||||||
return alive_entities.contains(e);
|
return alive_entities.contains(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<Component... T>
|
template<typename... T>
|
||||||
inline bool world::has(entity_id e) const
|
inline bool world::has(entity_id e) const
|
||||||
{
|
{
|
||||||
return storage.has<T...>(e);
|
return storage.has<T...>(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<Component T>
|
template<typename T>
|
||||||
inline T& world::get(entity_id e)
|
inline T& world::get(entity_id e)
|
||||||
{
|
{
|
||||||
return storage.get<T>(e);
|
return storage.get<T>(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<Component... T>
|
template<typename... T>
|
||||||
inline void world::set(entity_id e)
|
inline void world::set(entity_id e)
|
||||||
{
|
{
|
||||||
storage.set<T...>(e);
|
storage.set<T...>(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<Component... T>
|
template<typename... T>
|
||||||
inline void world::set(entity_id e, const T&... comps)
|
inline void world::set(entity_id e, const T&... comps)
|
||||||
{
|
{
|
||||||
storage.set(e, comps...);
|
storage.set(e, comps...);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<Component... T>
|
template<typename... T>
|
||||||
inline void world::remove(entity_id e)
|
inline void world::remove(entity_id e)
|
||||||
{
|
{
|
||||||
storage.remove<T...>(e);
|
storage.remove<T...>(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<Component... T>
|
template<typename... T>
|
||||||
inline void world::query(std::invocable<T&...> auto&& system)
|
inline void world::query(auto&& system)
|
||||||
{
|
{
|
||||||
for(auto e: alive_entities)
|
for(auto e: alive_entities)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue