C++ ECS 实战

20 篇文章 0 订阅
19 篇文章 0 订阅

GitHub - skypjack/entt: Gaming meets modern C++ - a fast and reliable entity component system (ECS) and much more

#include <entt/entt.hpp>
#include <iostream>

struct position {
    float x;
    float y;
};

struct velocity {
    float dx;
    float dy;
};

void update(entt::registry& registry) {
    auto view = registry.view<const position, velocity>();

    // use a callback
    view.each([](const auto& pos, auto& vel) { /* ... */ });

    // use an extended callback
    view.each([](const auto entity, const auto& pos, auto& vel) { /* ... */ });

    // use a range-for
    for (auto [entity, pos, vel] : view.each()) {
        // ...
    }

    // use forward iterators and get only the components of interest
    for (auto entity : view) {
        auto& vel = view.get<velocity>(entity);
        // ...
    }
    //registry.destroy(view.begin(), view.end());
}

struct some_component {
    int i = 0;

    void init() {
        std::cout << "I've init'd: " << i << std::endl;
    }
};

static void my_free_function(entt::registry&, entt::entity) {
    std::cout << "entity call back" << std::endl;
}

void test() {
    entt::registry registry;

    some_component component;
    registry.on_construct<some_component>().connect<&some_component::init>(&component);

    // connects a free function  void(entt::registry &, entt::entity);
    registry.on_construct<position>().connect<&my_free_function>();

    connects a member function   void(entt::registry &, entt::entity);
    //registry.on_construct<position>().connect<&my_class::member>(instance);

    // disconnects a free function void(entt::registry &, entt::entity);
    registry.on_construct<position>().disconnect<&my_free_function>();

    disconnects a member function  void(entt::registry &, entt::entity);
    //registry.on_construct<position>().disconnect<&my_class::member>(instance);

    for (auto i = 0u; i < 10u; ++i) {
        const auto entity = registry.create();
        auto& emplacePos = registry.emplace<position>(entity, i * 1.f, i * 1.f);
        emplacePos.x = 0.;
        emplacePos.y = 0.;
        if (i % 2 == 0) { registry.emplace<velocity>(entity, i * .1f, i * .1f); }

        // returns true if the entity is still valid, false otherwise
        bool b = registry.valid(entity);

        // gets the actual version for the given entity
        auto curr = registry.current(entity);

        // gets the version contained in the entity identifier
        auto version = entt::to_version(entity);

        // replaces the component in-place
        registry.patch<position>(entity, [](auto& pos) { pos.x = pos.y = 0.; });

        // constructs a new instance from a list of arguments and replaces the component
        //registry.replace<position>(entity, 0., 0.);

        //auto [pos, vel] = registry.get<position, velocity>(entity); // 不确定是否存在,用try_get

        //registry.emplace_or_replace<position>(entity, 0., 0.);
        //if (registry.all_of<velocity>(entity)) {
        //    registry.replace<velocity>(entity, 0., 0.);
        //}
        //else {
        //    registry.emplace<velocity>(entity, 0., 0.);
        //}
        // true if entity has at least one of the given components
        bool any = registry.any_of<position, velocity>(entity);

        registry.erase<position>(entity);   // 确定实体拥有组件,删除组件
        registry.remove<position>(entity);  //不确定实体拥有组件,删除组件
        registry.clear<position>();  // 组件的实体中删除给定组件
    }

    update(registry);

    //registry.release(entity); // 孤立,只移除,不删除。会更新entity版本号
    // destroys an entity and all its components
    //registry.destroy(entity);

    default initialized type assigned by copy to all entities
    //registry.insert<position>(first, last);

    user-defined instance assigned by copy to all entities
    //registry.insert(from, to, position{ 0., 0. });
    registry.clear();   //销毁registry中的所有实体

    // 组件更新监控
    entt::observer observer{ registry, entt::collector.update<position>() };
    //entt::collector.group<position, velocity>(entt::exclude<destroyed>);
    //entt::collector.update<sprite>().where<position>(entt::exclude<velocity>);
    for (const auto entity : observer)
        ;
    observer.clear();

    //registry.sort<renderable>([](const entt::entity lhs, const entt::entity rhs) {
    //    return entt::registry::entity(lhs) < entt::registry::entity(rhs);
    //    });
    //registry.sort<movement, physics>();

    Dependencies
    //registry.on_construct<my_type>().connect<&entt::registry::emplace_or_replace<a_type>>(); // 只要将my_type指定给实体,以下代码就会添加(或替换)组件a_type
    //registry.on_construct<my_type>().connect<&entt::registry::remove<a_type>>(); // 只要将my_type分配给实体,下面的代码就会从实体中删除a_type
    //registry.on_construct<my_type>().disconnect<&entt::registry::emplace_or_replace<a_type>>();
    //registry.on_construct<clazz>().connect<entt::invoke<&clazz::func>>();  // 信号传播到组件的成员函数
    //entt::sigh_helper{ registry }
    //    .with<position>()
    //    .on_construct<&a_listener>()
    //    .on_destroy<&another_listener>()
    //    .with<velocity>()
    //    .on_update<yet_another_listener>();
    
    // handle 
    using my_handle = entt::basic_handle<entt::basic_registry<position>>;
    using my_const_handle = entt::basic_handle<const entt::basic_registry<position>>;

    // Organizer 执行图
    entt::organizer organizer;

    // adds a free function to the organizer
    //organizer.emplace<&free_function, position, velocity>("func");

    adds a member function and an instance on which to invoke it to the organizer
    //clazz instance;
    //organizer.emplace<&clazz::member_function>(&instance);
    //organizer.emplace(+[](const void*, entt::registry&) { /* ... */ }, & instance);

    // adds a decayed lambda directly
    organizer.emplace(+[](const void*, entt::registry&) { /* ... */ });

    std::vector<entt::organizer::vertex> graph = organizer.graph();
    for (auto&& node : graph) {
        node.prepare(registry); // registry与图一起执行
    }

    // Context 上下文
    struct my_type {
        int a;
        char b;
    };
    registry.ctx().emplace<my_type>(42, 'c');
    my_type refType;
    registry.ctx().emplace<my_type&>(refType);
    auto& var = registry.ctx().get<my_type>();
    registry.ctx().erase<my_type>();
    const bool contains = registry.ctx().contains<my_type>();
    const my_type* value = registry.ctx().find<const my_type>();

    保存快照
    //output_archive output;
    //entt::snapshot{ registry }
    //    .entities(output)
    //    .component<a_component, another_component>(output);
    加载快照
    //input_archive input;
    //entt::snapshot_loader{ registry }
    //    .entities(input)
    //    .component<a_component, another_component>(input)
    //    .orphans();

    auto view = registry.view<position>();
    for (auto it = view.rbegin(), last = view.rend(); it != last; ++it) {
    }

    //auto group = registry.group<position>(entt::get<velocity, renderable>);
    //for (auto entity : group) {
    //    // a component at a time ...
    //    auto& position = group.get<position>(entity);
    //    auto& velocity = group.get<velocity>(entity);

    //    // ... multiple components ...
    //    auto [pos, vel] = group.get<position, velocity>(entity);

    //    // ... all components at once
    //    //auto [pos, vel, rend] = group.get(entity);
    //}
}


创作不易,小小的支持一下吧!

  • 36
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码力码力我爱你

创作不易,小小的支持一下吧!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值