Skip to content

Request: Support for auto-registered functions on meta #1245

Open
@TerensTare

Description

@TerensTare

In C++, we normally have several tools to customize functions/"interfaces" for types (think of serialize/deserialize), which are most of the time defined at compile time. However, in gamedev specifically there is often a need to have customization for data which is loaded at runtime and is often type-erased, which is why EnTT has meta to help with this part. However, meta needs the user to specify the functions supported by a certain type, which is not optimal as you need to be explicit about everything. Furthermore, the registration might be cumbersome when a function is overloaded (think of ADL scenarios).

For this reason, also based on the recent discussion on imgui-based editors that use meta, I think it would be great if meta had a mechanism to automatically detect certain interfaces and automatically "register" them for each type supporting them. These interfaces don't need to be a fixed set and should probably be tied to a meta context. The idea would be to have something like the following:

using namespace entt::literals;

struct hash_interface {
  template <typename T>
  inline void operator()(void *type_) const {
    auto &&type  = *(entt::meta_factory<T> *)type_;

    if constexpr (requires { std::hash<T>{}; }) // ok, std::hash is specialized for T, register hashing
        type.func<&std::hash<T>::operator()>("hash"_hs);
  }
};

struct foo
{
     int a;
    char b;
    float c;
};

// dummy setup
template <>
struct std::hash<foo>
{
    inline std::size_t operator()(foo const &) const { return 42; }
};

int main()
{
    entt::locator<entt::meta_ctx>::value_or()
        .register_auto_interface<hash_interface>(); // ok: hash_interface will be registered for all types that support it

    entt::meta_factory<foo>{} // all registered interfaces are checked here, in this case only `hash_interface`
        .data<&foo::a>("a"_hs)
        .data<&foo::b>("b"_hs)
        .data<&foo::c>("c"_hs);


    foo f{.a = 10, .b = 'b', .c = 0.1f};
    entt::meta_any any_foo{f};
    auto hash = entt::resolve<foo>().func("hash"_hs);

    // prints 42
    std::cout << hash(any_foo); // I can't remember if this is the syntax, but you get the idea
}

Metadata

Metadata

Assignees

Labels

enhancementaccepted requests, sooner or later I'll do it

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions