2
\$\begingroup\$

I am trying to develop an ECS registry. How would you improve this ? First disadvantage comes to my mind is using lambdas might be expensive, however I was not able to replicate functionality using F&& template arguments.

    engine->addEntity(1, 
        Position{1, 1},
        Mesh{"thing.gltf"},
        PhysicsBody{10.0f}
    );

    engine->addEntity(2,
        Position{ 2, 2 },
        Mesh{ "other.gltf" },
        PhysicsBody{ 30.0f }
    );

    engine->entity<Position>(1, [&](auto pos) {
        std::cout << "entity";
    });
    engine->each<Position, Mesh>([] (int id, Position& pos, Mesh& mesh) {
        std::cout << "entity" << id;
    });
    template<typename First>
    void entity(int id, std::function<void(First&)> callback)
    {
        auto comp = storage<First>()->get(id);
        if (!comp) return;
        callback(*comp);
    }

    template<typename First, typename...Rest>
    void entity(int id, std::function<void(Rest&...)> callback)
    {
        auto comp = storage<First>()->get(id);
        if (!comp) return;
        entity<Rest...>(id, [](Rest&...args) {
            callback(*comp, args...)
        });
    }

    template<typename T, typename...Rest, typename F>
    void each(F&& callback)
    {
        storage<T>()->forEach([&](int id, T& value) {
            entity<Rest...>(id, [&](Rest&...args) {
                callback(id, value, args...);
            });
        });
    }
\$\endgroup\$

1 Answer 1

4
\$\begingroup\$

using lambdas might be expensive

Why do you think that?

Lambdas are simply syntactic hand waving for class functors (that have been around for over 3 decades). Functors are considered (in general) to be much more efficient than standard functions (especially when used by templates) as the compiler can do a lot of optimizations on them.

auto x = [&capture](X const& parm){ /* BODY */ }

You can consider as syntactic sugar for:

class CompilerNamedType
{
    TypeOfCapure&     capture;
    public:
        CompilerNamedType(TypeOfCapure& capture)
            : capture(capture)
        {}

        CompilerCalculatedReturnType operator()(X const& param) const
        {
            /* BODY */
        }
};

CompilerNamedType  x(capture);

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.