Skip to content
/ klecs Public

a tiny, ergonomic header-only ecs in modern c++

License

Notifications You must be signed in to change notification settings

thekatze/klecs

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

klecs

a tiny, ergonomic header-only ecs in modern c++.
first built as part of a learning project, now powering two of my games.

usage

consider using flecs or EnTT first.

quickstart

#include <klecs.h>

struct Transform {
    int position[3];
};

struct Rigidbody {
    int linear_velocity[3];
};

int main() {
    klecs::World world{};

    world.spawn(Transform{.position = {0, 0, 0}}, Rigidbody{.linear_velocity = {1, 0, 0}});

    world.query<Transform &, Rigidbody &>(
        [](const EntityId &id, Transform &transform, const Rigidbody &rigidbody) {
            transform.position[0] += rigidbody.linear_velocity[0];
            transform.position[1] += rigidbody.linear_velocity[1];
            transform.position[2] += rigidbody.linear_velocity[2];
        });

    return 0;
}

delete entity by id

#include <klecs.h>

int main() {
    klecs::World world{};

    klecs::EntityId id = world.spawn(0);
    world.remove(id);

    return 0;
}

clear archetypes

#include <klecs.h>

int main() {
    klecs::World world{};

    world.spawn(0);                  // Id: 1
    world.spawn(0, 0.0f);            // Id: 2
    world.clear_exact<int>();        // clears 1, but leaves 2 intact because signature doesn't fully match
    world.clear_exact<int, float>(); // clears 2, but leaves 1 intact
    world.clear_matching<int>();     // clears both 1 and 2

    return 0;
}

get components from id

#include <klecs.h>

int main() {
    klecs::World world{};

    klecs::EntityId id = world.spawn(0, 0.0f, 'c');
    std::optional<std::tuple<int, float&>> components = world.get<int, float&>(id);

    if (!components.has_value()) {
        // world.get returns nullopt if we requested a component this entity does not have
        // for example: world.get<double>(id);
        return 1;
    }

    float& float_ref = std::get<float&>(*components);

    float_ref = 1.0f;

    return 0;
}

query into vec

useful for nested queries, i.e. simple collision checks.

#include <iostream>
#include <klecs.h>

int main() {
    klecs::World world{};

    world.spawn(0); 
    world.spawn(1); 
    world.spawn(2); 
    world.spawn(3); 

    std::vector<std::tuple<int>> numbers = world.query_into_vec<int>();

    for (auto& number : numbers) {
        std::cout << std::get<int>(number) << ", "; // 1, 2, 3, 4, 
    }

    return 0;
}

query count

useful for checking if entities with certain components still exist.

#include <klecs.h>

int main() {
    klecs::World world{};
    
    world.spawn(0, 'c');
    world.spawn(0.0f, 'a');
    world.spawn(5, 't');
    world.spawn(1.0, 's');
     
    world.query_count<char>(); // -> 4

    return 0;
}

projects using klecs

About

a tiny, ergonomic header-only ecs in modern c++

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published