Skip to content

Commit

Permalink
backup (arch): added primitive systems
Browse files Browse the repository at this point in the history
  • Loading branch information
Sara01-s committed Mar 6, 2025
1 parent 4706d04 commit c0b58c5
Show file tree
Hide file tree
Showing 10 changed files with 164 additions and 67 deletions.
43 changes: 36 additions & 7 deletions examples/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,62 @@

struct Position {
float x, y, z;
friend std::ostream& operator<<(std::ostream& os, Position const& pos) {
return os << "Position { x: " << pos.x << ", y: " << pos.y << ", z: " << pos.z << " }";
}
};

struct Velocity {
float dx, dy, dz;
friend std::ostream& operator<<(std::ostream& os, Velocity const& vel) {
return os << "Velocity { dx: " << vel.dx << ", dy: " << vel.dy << ", dz: " << vel.dz << " }";
}
};

struct Health {
int value;
constexpr void reset() noexcept { value = 100; };
friend std::ostream& operator<<(std::ostream& os, Health const& health) {
return os << "Health { value: " << health.value << " }";
}
};


int main() {
using log_t = vecs::debug_t;

vecs::world_t<Position, Velocity, Health> world{};
log_t::log("-------------------------------------------------");

auto position { Position { 1.0f, 1.0f, 0.0f } };
auto velocity { Velocity { 0.0f, 2.0f, 0.0f } };
auto health { Health { 50 } };
auto position1 { Position { 1.0f, 1.0f, 0.0f } };
auto velocity1 { Velocity { 0.0f, 2.0f, 0.0f } };
auto health1 { Health { 50 } };

auto position2 { Position { 2.0f, 2.0f, 0.0f } };
auto velocity2 { Velocity { 1.0f, 1.0f, 0.0f } };
auto health2 { Health { 75 } };

world.spawn_entity(position, velocity, health);
auto const entity_id = world.spawn_entity(velocity, health);
auto position3 { Position { 3.0f, 3.0f, 0.0f } };
auto velocity3 { Velocity { 0.5f, 0.5f, 0.0f } };
auto health3 { Health { 100 } };

world.spawn_entity(position1, velocity1, health1);
world.spawn_entity(position2, velocity2, health2);
auto const entity_id = world.spawn_entity(velocity1, health1);

world.despawn_entity(entity_id);
world.spawn_entity(velocity3);

world.spawn_entity(velocity);
world.spawn_entity(health);
log_t::log("-------------------------------------------------");
world.for_each<Position, Velocity, Health>(
[](Position const& pos, Velocity const& vel, Health const& health
) {
log_t::log("System matched the following components in entity: ");
log_t::log(" ╰> ", log_t::YELLOW, pos);
log_t::log(" ╰> ", log_t::YELLOW, vel);
log_t::log(" ╰> ", log_t::YELLOW, health);
log_t::log("");
});

return 0;
}
Expand Down
4 changes: 2 additions & 2 deletions tests/unit/test_slotmap.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ TEST_CASE("Insertion and deletion benchmarks.", "[!benchmark]") {
}
};

BENCHMARK("UnorderedMap Insertior and deletion.") {
BENCHMARK("UnorderedMap Insertion and deletion.") {
std::unordered_map<int, int> unordered_map;
for (int i = 0; i < num_elements; ++i) {
unordered_map[i] = i;
Expand Down Expand Up @@ -100,4 +100,4 @@ TEST_CASE("Insertion and deletion benchmarks.", "[!benchmark]") {

return sum;
};
}
}
28 changes: 14 additions & 14 deletions vecs/include/vecs/archetype.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// std
#include <tuple>
#include <vector>
#include <algorithm>

// lib
#include "types.hpp"
Expand All @@ -28,44 +29,43 @@ struct archetype_t final {
return std::get<0>(_component_table).size();
}

std::vector<component_key_t>
add_entity(vecs::entity_id_t const entity_id, Cs&&... components) {
std::vector<vecs::component_key_t>
add_entity(vecs::entity_id_t const entity_id, Cs&&... components) noexcept {
// Add a column.
std::vector<component_key_t> cmp_keys{};
cmp_keys.reserve(_component_count);

// C++17 fold expression for iterating each element in pack `components`.
([&](auto&& component) {
using component_type_t = std::remove_reference_t<decltype(component)>;
auto& component_row =
std::get<component_row_t<component_type_t>>(_component_table);

auto& component_row = std::get<
component_row_t<component_type_t>>(_component_table);
vecs::component_key_t const key = component_row.push_back(component);

cmp_keys.push_back(key);
} (std::forward<Cs>(components)), ...);

return cmp_keys;
}

template <Component C>
vecs::component_key_t const
store_component(C&& component) {
store_component(C&& component) noexcept {
auto& component_row = std::get<component_row_t<C>>(_component_table);
auto const key = component_row.push_back(component);

return key;
}

template <typename F>
void
for_each(F&& function) {
assert(!std::get<0>(_component_table).empty()
&& "Component table is empty.");

for_each(auto&& system) noexcept {
vecs::usize const entity_count { std::get<0>(_component_table).size() };

for (vecs::usize entity_id{}; entity_id < entity_count; ++entity_id) {
std::apply([&function, entity_id](auto&... component_row) {
std::forward<F>(function)(component_row[entity_id]...);
std::apply([&system, entity_id](auto&... component_row) {
vecs::debug_t::log(vecs::debug_t::LIGHT_BLUE, "Found Entity ID: ", entity_id);
std::forward<decltype(system)>(system)(component_row[entity_id]...);
}, _component_table);
}
}
Expand Down Expand Up @@ -108,7 +108,7 @@ struct archetype_t final {
A column in the table represents an entity an it's components!
*/
template <Component T>
using component_row_t = vecs::slotmap_t<T, MAX_REGISTRABLE_COMPONENTS>;
using component_row_t = vecs::slotmap_t<T, vecs::MAX_INSTANCES_PER_COMPONENT>;
using component_table_t = std::tuple<component_row_t<Cs>...>;
component_table_t _component_table{};
};
Expand Down
43 changes: 26 additions & 17 deletions vecs/include/vecs/component_storage.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ struct component_storage_t final {
vecs::entity_id_t const entity_id,
Cs&&... components
) noexcept {
mask_t mask = (_component_masks[typeid(Cs).hash_code()] | ...);
vecs::mask_t mask = (_component_masks[typeid(Cs).hash_code()] | ...);
_entity_masks[entity_id] = mask;

if (!_is_archetype_registered(mask)) {
Expand All @@ -61,11 +61,18 @@ struct component_storage_t final {

void
remove_components(vecs::entity_id_t const entity_id) noexcept {
mask_t const mask = _entity_masks[entity_id];
_entity_masks[entity_id] = mask_t{};
vecs::mask_t const mask = _entity_masks[entity_id];
_entity_masks[entity_id] = vecs::DEAD_ENTITY_ID;
}

[[nodiscard]] mask_t
template <Component... Cs>
void
for_each(auto&& system) {
vecs::archetype_t<Cs...>& archetype = _get_archetype<Cs...>();
archetype.for_each(std::forward<decltype(system)>(system));
}

[[nodiscard]] vecs::mask_t
get_entity_mask(vecs::entity_id_t const entity_id) const noexcept {
return _entity_masks[entity_id];
}
Expand All @@ -78,7 +85,7 @@ struct component_storage_t final {
<= std::numeric_limits<decltype(_next_component_mask)>::max()
&& "Component registration limit reached.");

component_id_t const component_id = component_info->hash_code();
vecs::component_id_t const component_id = component_info->hash_code();

assert(!_component_masks.contains(component_id)
&& "Component already registered.");
Expand All @@ -90,9 +97,9 @@ struct component_storage_t final {
// This repeats for Velocity and Health.
// Resulting in archetype.id = 0b111.
// TODO - Remove this log.
component_name_t const component_name = component_info->name();
vecs::component_name_t const component_name = component_info->name();
log_t::log(log_t::YELLOW, "Registered component: ", log_t::CLEAR,
component_name, " with mask: ", log_t::LIGHT_MAGENTA, _component_masks[component_id].to_string());
component_name, " with mask: ", log_t::LIGHT_MAGENTA, "0b", _component_masks[component_id].to_string());
}
}

Expand All @@ -109,18 +116,20 @@ struct component_storage_t final {
_archetypes[archetype.mask()] = std::any { std::move(archetype) };
}

template <Component... Cs>
[[nodiscard]] vecs::entity_id_t const
_add_entity(vecs::archetype_t<Cs...> const& archetype) noexcept {

auto&
_get_entity_components(vecs::entity_id_t const entity_id) noexcept {
auto entity_mask = _entity_masks[entity_id];

assert(_is_archetype_registered(entity_mask)
&& "Archetype not registered");

auto& archetype = _get_archetype(entity_mask);
}

template <Component C>
[[nodiscard]] vecs::mask_t
_get_component_mask() noexcept {
component_id_t component_id = typeid(C).hash_code();
vecs::component_id_t component_id = typeid(C).hash_code();
assert(_component_masks.contains(component_id)
&& "Component not registered.");

Expand All @@ -141,9 +150,9 @@ struct component_storage_t final {
}

template <Component... Cs>
[[nodiscard]] archetype_t<Cs...>&
[[nodiscard]] vecs::archetype_t<Cs...>&
_get_archetype() noexcept {
vecs::mask_t archetype_mask = _get_archetype_mask<Cs...>();
vecs::mask_t const archetype_mask = _get_archetype_mask<Cs...>();

assert(_is_archetype_registered(archetype_mask)
&& "Archetype not registered.");
Expand All @@ -164,13 +173,13 @@ struct component_storage_t final {
std::array<
std::type_info const*,
sizeof...(RegisteredComponents)> const _registered_components_type_info{};

vecs::u64 _next_component_mask { 0b1 };

// Component Storage Data Layout.
std::unordered_map<component_id_t, vecs::mask_t> _component_masks{};
std::unordered_map<vecs::component_id_t, vecs::mask_t> _component_masks{};
std::array<vecs::mask_t, MaxAliveEntities> _entity_masks{};
std::unordered_map<vecs::mask_t, std::any> _archetypes{};

vecs::u64 _next_component_mask { 0b1 };
};

} // namespace vecs
Expand Down
10 changes: 10 additions & 0 deletions vecs/include/vecs/data_structures/slotmap.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,16 @@ class slotmap_t final {
_init_freelist();
}

[[nodiscard]] constexpr T&
operator[](index_t index) {
return _data[index];
}

[[nodiscard]] constexpr T const&
operator[](index_t index) const {
return _data[index];
}

private:
constexpr void
_init_freelist() noexcept {
Expand Down
25 changes: 14 additions & 11 deletions vecs/include/vecs/debug.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <fstream>
#include <filesystem>
#include <algorithm>
#include <typeinfo>

namespace vecs {

Expand Down Expand Up @@ -34,7 +35,7 @@ class debug_t {
~debug_t() = delete;
debug_t(const debug_t&) = delete;

static constexpr auto CLEAR { "\033[0m" };
static constexpr auto CLEAR { "\033[0m" };
static constexpr auto BLACK { "\033[30m" };
static constexpr auto RED { "\033[31m" };
static constexpr auto GREEN { "\033[32m" };
Expand All @@ -43,7 +44,7 @@ class debug_t {
static constexpr auto MAGENTA { "\033[35m" };
static constexpr auto CYAN { "\033[36m" };
static constexpr auto WHITE { "\033[37m" };
static constexpr auto GRAY { "\033[90m" };
static constexpr auto GRAY { "\033[90m" };

static constexpr auto LIGHT_BLACK { "\033[90m" };
static constexpr auto LIGHT_RED { "\033[91m" };
Expand All @@ -53,20 +54,20 @@ class debug_t {
static constexpr auto LIGHT_MAGENTA { "\033[95m" };
static constexpr auto LIGHT_CYAN { "\033[96m" };
static constexpr auto LIGHT_WHITE { "\033[97m" };
static constexpr auto LIGHT_GRAY { "\033[97m" };
static constexpr auto LIGHT_GRAY { "\033[97m" };

static constexpr auto BOLD { "\033[1m" };
static constexpr auto UNDERLINE { "\033[4m" };
static constexpr auto INVERT { "\033[7m" };

static constexpr auto BG_BLACK { "\033[40m" };
static constexpr auto BG_RED { "\033[41m" };
static constexpr auto BG_GREEN { "\033[42m" };
static constexpr auto BG_YELLOW { "\033[43m" };
static constexpr auto BG_BLUE { "\033[44m" };
static constexpr auto BG_MAGENTA { "\033[45m" };
static constexpr auto BG_CYAN { "\033[46m" };
static constexpr auto BG_WHITE { "\033[47m" };
static constexpr auto BG_BLACK { "\033[40m" };
static constexpr auto BG_RED { "\033[41m" };
static constexpr auto BG_GREEN { "\033[42m" };
static constexpr auto BG_YELLOW { "\033[43m" };
static constexpr auto BG_BLUE { "\033[44m" };
static constexpr auto BG_MAGENTA { "\033[45m" };
static constexpr auto BG_CYAN { "\033[46m" };
static constexpr auto BG_WHITE { "\033[47m" };
static constexpr auto BG_GRAY { "\033[100m" };

static constexpr auto LIGHT_BG_BLACK { "\033[100m" };
Expand Down Expand Up @@ -121,6 +122,8 @@ class debug_t {
log_message("[ERROR]: ", RED, std::forward<Args>(args)...);
}



private:
template <typename... Args>
static void
Expand Down
6 changes: 2 additions & 4 deletions vecs/include/vecs/entity_storage.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ template <vecs::usize Capacity = 64, vecs::usize MaxComponents = 64>
struct entity_storage_t {
using log_t = vecs::debug_t;

static constexpr vecs::usize DEAD_ENTITY_ID { 0b0 }; // 0b0 = No components = dead/invalid entity.

[[nodiscard]]
constexpr vecs::entity_id_t const
add_entity() noexcept {
Expand All @@ -40,13 +38,13 @@ struct entity_storage_t {
void
add_component_keys(
vecs::entity_id_t const entity_id,
std::vector<component_key_t> cmp_keys
std::vector<vecs::component_key_t> cmp_keys
) {
_entity_keys[entity_id] = cmp_keys;
}

private:
std::array<std::vector<component_key_t>, Capacity> _entity_keys{};
std::array<std::vector<vecs::component_key_t>, Capacity> _entity_keys{};
vecs::reusable_id_t<vecs::entity_id_t> _entity_ids{};
};

Expand Down
21 changes: 21 additions & 0 deletions vecs/include/vecs/query.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#pragma once

// std
#include <tuple>
#include <vector>

// lib
#include "types.hpp"

namespace vecs {

template <Component... Cs>
struct query_t final {



std::tuple<std::vector<vecs::component_t<Cs...>>> data{};

};

} // namespace vecs
Loading

0 comments on commit c0b58c5

Please sign in to comment.