-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
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
Make all builtin bundles !Component #403
Conversation
Annote fields with `#[bundle(skip)]` to skip them
Achieved by making them all `!Sync` Also removes unneeded requirements of `Sync` when spawning `Bundles`
Improve the experience for anyone who greps for unsafe
This is really clever and does accomplish the goal, but I'm hesitant to merge this change for a number of reasons:
I think I would prefer to wait for negative impls to stabilize, even if it takes more time. The "people try to use bundles as components" problem is something that is largely solved by better educational material. |
Thanks, I suppose.
I would have much rather made it not I hadn't seen rust-lang/rust#68318 - trying to And regarding educational material, to me this feels more like something we should prevent entirely, because it's never going to be correct. I'm already getting bored of telling people how wrong it is :| . I think it would be possible to add runtime validation using I can close this and pivot to that if you want @cart |
I think runtime validation using type_name would introduce more overhead than its worth. Component insertion is a "hot path". I think I'd take the solution in this pr over that.
I agree that its a minor complexity increase. Not a huge deal.
I think you're suggesting
Yeah backward compat isn't a big deal at this point.
Yup also not a huge deal. Your points are valid, but I'm still not convinced that this is the right call. There are enough concessions being made here that it doesn't seem worth it to me. This is a hard call and merging is "valid" for the same reason not merging is "valid". My bias here is to opt for simplicity and non-hackey solutions. Another option that we'll have when specialization lands (which is probably closer to stabilization than negative trait bounds): pub trait Component: Send + Sync + 'static {
default fn is_valid() -> bool {
true
}
}
// in derive macro
impl Component for MyBundle {
fn is_valid() -> bool {
false
}
}
// when adding components to a World:
assert!(component.is_valid()) |
In theory, since 1.46 there's no reason why we can't make the The specialisation solution is very neat - I hadn't considered that. Edit: Or it could be |
Yeah non-const type_name is a real shame. We also want to use that for StableTypeId / dynamic plugin loading, but sadly its a no-go for now. I'd consider a debug-only type_name validation, but we already have complaints about debug perf and adding "expensive" checks to hot paths would only make that situation worse. And using type name here throws away type safety in favor of naming conventions, which also feels really dirty to me. Sorry I'm not trying to be difficult here. This is just a hard problem. Its not satisfying, but waiting for specialization and improving documentation in the short term seems like a good non-hackey solution. |
I'm closing this for now, but we may come back to this implementation in the future if alternative impls dont work out. |
Yeah, that's fine |
@cart I've been experimenting quite a bit with bundles, especially when it comes to nesting as well and creating more complex entities and I'm starting to think we may be on a wrong approach. Every issue I tried to solve seemed to require more advanced/unstable rust features to work nicely. Eventually I settled on something super simple & very powerful that doesn't need any creative rust features. Just a regular struct (not bundle) that derives/implements default and has a
Then to use it I just do:
And because it derives/implements default, it is fully data driven and anything can be modified. For example:
or for those who prefer the more verbose way:
(Sorry if the code doesn't compile. I'm writing this from memory) |
Fixes #392
Component requires
Sync
, so this PR makes all built-in bundles!Sync
This prevents the following from compiling, among others
This is incredibly hacky, but it works to fix the motivating issue with no other side effects. Additionally, this issue has appeared several times in #help on the Discord
Ideally, we'd just
impl !Sync
directly, but that currently gives an error that negative impls aren't stable, which doesn't appear to be likely to be fixed any time soon