Description
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
}