Skip to content

Dark River is an ECS (Entity-Component-System) library developed in C++23. It provides a powerful framework for building scalable and efficient game engines and simulations.

Notifications You must be signed in to change notification settings

GabrielBernardoDaSilva/DarkRiverECS

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

87 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Dark River ECS

DARKRIVER

Dark River is an ECS (Entity-Component-System) library developed in C++23. It provides a powerful framework for building scalable and efficient game engines and simulations.

Features

  • Entity Creation: Easily create entities and attach components to them.
  • Event Handling: Implement event-driven architecture with custom events and event handlers.
  • Schedulers: Schedule tasks to be executed at specific intervals or delays.
  • Queries: Efficiently query entities based on their components.
  • Systems: Implement game logic and behaviors through systems that process entities based on queries.
  • Plugins: Extend the functionality of the ECS with custom plugins.

Requirements

Installation

You can add the root repository to your cmake:

add_subdirectory(WinterRainECS)
target_link_libraries(${PROJECT_NAME} PRIVATE WinterRainECS)

Example Usage

#include <print>
#include <functional>
#include <thread>
#include <chrono>

#include "darkriver.hpp"

using namespace darkriver;
struct Position
{
    float x, y;
};

struct Velocity
{
    float x, y;
};

struct Timer
{
    float time;
};

struct Game
{
    int score;
};

struct Health
{
    int health;

    Health(int health) : health(health)
    {
        std::println("Constructor");
    }

    Health(const Health &other) = delete;
    Health(Health &&other) noexcept : health(std::move(other.health))
    {
        std::println("Move Constructor");
    }

    Health &operator=(const Health &other) = delete;

    Health &operator=(Health &&other) noexcept
    {
        health = std::move(other.health);
        std::println("Move Assignment");
        return *this;
    }
};

generator<WaitAmountOfSeconds> generate_numbers(World *world, int i)
{
    std::println("generate_numbers starting");
    co_yield WaitAmountOfSeconds{
        10.0f};
    std::println("generate_numbers ending");

    std::println("i: {}", i);
    std::exit(0);
}

struct Collision
{
    bool collided;
};

void check_collision(World &world, Collision collision)
{
    std::println("Collision: {}", collision.collided);
}

void modify_pos(Query<With<Entity &, Position &, Velocity &>> query, Query<With<Position &>, Without<Velocity &>> q2,
                EventManager &event_manager, EntityManager &entity_manager, ResourceManager &resource_manager)
{
    entity_manager.add_entity(Position{.x = 200.0f, .y = 200.0f}, Velocity{.x = 200.0f, .y = 200.0f});
    event_manager.subscribe<Collision>(check_collision);

    resource_manager.add<Game>({100});

    auto a = query.all();
    auto b = q2.all();
    for (auto &[entity, pos, vel] : a)
    {
        std::println("Entity: {}", entity.id);
        std::println("Position: x: {} y: {}", pos.x, pos.y);
        pos.x += 1.0f;
        std::println("Velocity: x: {} y: {}", vel.x, vel.y);
    }

    for (auto &[pos] : b)
    {
        std::println("Pos Health: x: {} y: {}", pos.x, pos.y);
        pos.x += 1.0f;
    }
}

void read_position(Query<With<Position &>> query, const Resource<Timer> timer, Resource<Game> game)
{
    std::println("Timer: {}", timer->time);
    game->score += 1;
    for (auto &[pos] : query.all())
    {
        std::println("Position: x: {} y: {}", pos.x, pos.y);
    }
}

class PluginTest : public Plugin
{
    virtual void build(World &world) override
    {
        world.subscribe<Collision>([&](World &world, Collision collision)
                                   { std::println("PluginTest Collision"); });
        std::println("PluginTest on_start");
    }
};

void p(std::function<void()> f)
{
    f();
}

int main()
{


    Position pos = {
        .x = 10.0f,
        .y = 20.0f};
    Velocity vel = {
        .x = 5.0f,
        .y = 5.0f};

    Position pos2 = {
        .x = 12.0f,
        .y = 22.0f};

    Velocity vel2 = {
        .x = 7.0f,
        .y = 7.0f};

    Position pos3 = {
        .x = 13.0f,
        .y = 23.0f};
    Health health = {
        100};

    World world;
    world.add_resource(Timer{10.0f});
    world.add_plugin<PluginTest>();
    world.build_plugins();
    auto e = world.add_entity_ret_id(pos, vel);
    world.add_entity(pos2, vel2)
        .add_entity(pos3, std::move(health));

    world.add_component_to_entity(e, Health{300});
    world.remove_component_from_entity<Health>(e);

    auto pos_query = [](Query<With<Position &>> query, const Resource<Game> game)
    {
        std::println("Game Score: {}", game->score);
        for (auto &[pos] : query.all())
        {
            std::println("Print Lambda Position: x: {} y: {}", pos.x, pos.y);
        }
    };

    world.add_executors(ExecutorType::Startup, modify_pos, read_position);
    world.add_executors(ExecutorType::Startup, pos_query);

    world.run();
    world.emit(Collision{.collided = true});

    // in case you need the world pass as pointer to has cohesion
    world.add_task(generate_numbers, &world, 10);

    // accept lambda task
    world.add_task([](int i) -> generator<WaitAmountOfSeconds>
                   { std::println("Lambda Task");
                    co_yield WaitAmountOfSeconds{10.0f}; }, 10);

    std::println("Run");
    int i = 0;
    while (true)
    {
        world.run_tasks(1.0f);
        std::this_thread::sleep_for(std::chrono::seconds(1));
        std::println("{}", i++);
    }
    return 0;
}

This README provides an overview of the library's features, example usage, requirements, installation instructions, and licensing information. Adjustments can be made as needed based on the specific details of the library.

License

Dark River is licensed under the MIT License. See LICENSE for details.

About

Dark River is an ECS (Entity-Component-System) library developed in C++23. It provides a powerful framework for building scalable and efficient game engines and simulations.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages