Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
-
- #include <entt/entt.hpp>
- #include <cstdint>
- #include <deque>
- namespace entt
- {
- template<typename Entity> using Group = Registry<Entity>;
- template<typename Entity> class GroupRegistry
- {
- public:
- using size_type = std::size_t;
- using group_id = size_type;
- using group_type = Group<Entity>;
- public:
- GroupRegistry() = default;
- GroupRegistry(const GroupRegistry &) = delete;
- GroupRegistry(GroupRegistry &&) = default;
- GroupRegistry & operator=(const GroupRegistry &) = delete;
- GroupRegistry & operator=(GroupRegistry &&) = default;
- public:
- group_id create() noexcept
- {
- group_id group = 0;
- if (freed.empty())
- {
- group = groups.size();
- groups.emplace_back(group_type());
- }
- else
- {
- group = freed.front();
- freed.pop_front();
- }
- return group;
- }
- bool valid(group_id group) const noexcept
- {
- return group < groups.size();
- }
- bool has(group_id group) const noexcept
- {
- assert(valid(group));
- for (auto& idx : freed)
- {
- if (idx == group)
- {
- return false;
- }
- }
- return true;
- }
- group_type& get(group_id group) noexcept
- {
- return groups[group];
- }
- bool remove(group_id group)
- {
- if (has(group))
- {
- get(group).reset();
- freed.emplace_back(group);
- return true;
- }
- else
- {
- return false;
- }
- }
- void reset()
- {
- groups.clear();
- freed.clear();
- }
- size_type size() const noexcept
- {
- return groups.size() - freed.size();
- }
- size_type capacity() const noexcept
- {
- return groups.size();
- }
- bool empty() const noexcept
- {
- return groups.size() == freed.size();
- }
- private:
- std::deque<group_type> groups;
- std::deque<group_id> freed;
- };
- using DefaultGroup = Group<std::uint32_t>;
- using DefaultGroupRegistry = GroupRegistry<std::uint32_t>;
- }
- struct Position {
- float x;
- float y;
- };
- struct Velocity {
- float dx;
- float dy;
- };
- struct GroupEntry
- {
- entt::DefaultGroupRegistry::group_id id;
- };
- struct LinkInGroup
- {
- entt::DefaultGroupRegistry::group_id group;
- entt::DefaultRegistry::entity_type entity;
- };
- void visit(
- entt::DefaultGroupRegistry &groups,
- entt::DefaultGroupRegistry::group_id id,
- const std::function<bool(entt::DefaultGroup&)>& fn)
- {
- auto& registry = groups.get(id);
- if (fn && !fn(registry))
- {
- return;
- }
- auto view = registry.view<GroupEntry>();
- for (auto entity : view)
- {
- auto& group = view.get(entity);
- visit(groups, group.id, fn);
- }
- }
- void update(entt::DefaultRegistry ®istry) {
- auto view = registry.view<Position, Velocity>();
- for (auto entity : view) {
- // gets only the components that are going to be used ...
- auto &velocity = view.get<Velocity>(entity);
- velocity.dx = 0.;
- velocity.dy = 0.;
- // ...
- }
- }
- void update(std::uint64_t dt, entt::DefaultRegistry ®istry) {
- registry.view<Position, Velocity>().each([dt](auto entity, auto &position, auto &velocity) {
- // gets all the components of the view at once ...
- position.x += velocity.dx * dt;
- position.y += velocity.dy * dt;
- // ...
- });
- }
- int main() {
- entt::DefaultGroupRegistry rex;
- rex.remove(rex.create());
- auto root = rex.create();
- auto child = rex.create();
- {
- auto& reg = rex.get(root);
- for (auto i = 0; i < 3; ++i)
- {
- auto entity = reg.create(Position{ i * 2.f, i * 1.f });
- if (i == 0) { reg.assign<GroupEntry>(entity, child); }
- }
- }
- auto leaf = rex.create();
- {
- auto& reg = rex.get(child);
- for (auto i = 0; i < 5; ++i)
- {
- auto entity = reg.create(Position{ i * 1.f, i * 3.f });
- if (i == 0) { reg.assign<GroupEntry>(entity, leaf); }
- }
- }
- {
- auto& reg = rex.get(leaf);
- for (auto i = 0; i < 10; ++i)
- {
- auto entity = reg.create(Position{ i * 4.f, i * 4.f });
- if (i % 2 == 0) { reg.assign<Velocity>(entity, i * .1f, i * .1f); }
- }
- }
- visit(rex, root, [](entt::DefaultGroup& reg) {
- update(reg);
- return true;
- });
- visit(rex, root, [](entt::DefaultGroup& reg) {
- update(10, reg);
- return true;
- });
- return 0;
- }
Add Comment
Please, Sign In to add comment