-
-
Notifications
You must be signed in to change notification settings - Fork 954
Request: Support for auto-registered functions on meta #1245
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
How would the template <typename T>
inline void operator()(void *type_) const; We have two different layers of template machinery in this case: one when you register the interfaces, the other one on the intefaces. |
There is no way to register functions on a specific class at runtime without specifying all the intervfaces at compile time entt::locator<entt::meta_ctx>::value_or()
.register_auto_interface<hash_interface>(); // ok: hash_interface will be registered for all types that support it needs to return a type that holds all int main()
{
auto locator = entt::locator<entt::meta_ctx>::value_or()
.register_auto_interface<hash_interface>(); // ok: hash_interface will be registered for all types that support it
// have to register all states at this call by chaining maybe?
// passing locator
entt::meta_factory<foo>{locator} // 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
} you are essentially trying to solve the issue of arbitary std::any visitation without specifying all the interfaces to visit which is impossible. I know you could get close with Stateful meta programming but I wouldn't like to see that used in a library as it is inconsistent and not portable |
Then why not an ADL-solved invocation from within |
ADL is |
First of all, my idea was to have a
That would work actually, I think it's cleaner/less error prone (?) + simpler to write overall. Maybe not an ADL solution, but a simple type trait would do I think. // default implementation
template <typename>
struct inject_interfaces {
template <typename T>
inline static void inject(entt::meta_factory<T> &type) {} // do nothing by default
};
// specialize inject_interfaces<void> if you want your own implementation
template <>
struct inject_interfaces<void> {
template <typename T>
inline static void inject(entt::meta_factory<T> &type) {
// similar to the hash_interface example earlier
}
}; Also another alternative I was thinking of is to simply have functions that return the // how do you compose this with other traits?
template <typename T>
auto meta_hashable() {
if constexpr (is-hashable<T>) {
return entt::meta_factory<T>{}.func<&hash-func>("hash"_hs);
} else {
return entt::meta_factory<T>{};
}
} |
but wouldn't limitting it to 1 specilization disallow you to overload it if it is already overloaded by some other library? |
Yes, that's a problem. For me you don't want to do that either way because afaik it can and will cause ODR violations (ie. having specializations of a type/function and pick the "most recent" one). Maybe libraries should have something like a "register_traits" which you can/should call manually instead? I'm open to suggestions though, so let me know if you have a better idea. |
did you see my code I posted about returning a local variable? |
Yes, what about it? |
What I meant is this, that is, a straightforward mechanism that allows users to define meta setup functions in user space. With concepts they are waaaaaay nicer than what I did in the tests too. entt::meta_factory<MyType> factory{};
meta_setup(factory); // defined in user space
factory.do_something_else(); However, the |
Ok, now I see what you meant with ADL. Seems we are on the same page on what it should look like then, but I still have one last thing to ask. Why should |
Yes and no. With the That said, I reverted the ADL changes because they failed and I didn't get why. 🤔 |
Well not exactly ADL, but you can get it to work if you specialize
Ok, I see. I would still argue to at least have some tag that says "call this setup automatically in the constructor for me". Something in the lines of: // user should write this
void meta_setup(entt::meta_factory<foo> &factory, entt::auto_setup_t) { /* ... */ }
// then on meta_factory<T> constructor
if constexpr (requires { meta_setup(*this, auto_setup_t{}); }) {
meta_setup(*this, auto_setup_t{});
} Let me know what you think. |
the issue I see is with UB because what if the user doesn't include this overload with their class type? it will cause ODR voilations. I don't hace an idea to prevent it.... |
I think that happens with specializing traits too, right? There's no good way around it as far as I can tell neither unless we have struct foo {
static void meta_setup(entt::meta_factory<foo> &factory) {
// ...
}
}; This is similar to |
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:
The text was updated successfully, but these errors were encountered: