-
-
Notifications
You must be signed in to change notification settings - Fork 4.1k
Description
What problem does this solve or what need does it fill?
Sometimes it is necessary to compose data from multiple parts of the world at once on a single entity (referencing resources, relationships and so on) currently there are two ways of doing this.
- Use a component only intended to store the composed data
This can be complicated as catching all ways in which the data can be modified is very tricky and often requires a lot of code.
While immutable components have made this easier, there are still situations in which it does not make sense to use them.
- Compose the data each time
While this does achieve the desired effect, it can introduce a lot of code for complex compositions, even something as simple as trying to sum a relationship adds an extra parameter that may not be used elsewhere.
What solution would you like?
Ephemeral components, components that are only constructed when they are queried for.
#[derive(Component)]
pub struct SumChildComponents(f32);
impl EphemeralComponent for SumChildComponents {
fn construct(entity: Entity, world: &World) -> Self {
let children = world.get::<Children>(entity).unwrap();
let total = children
.iter()
.map(|child| world.get::<Value>(child).unwrap().0)
.sum();
Self(total)
}
}
#[derive(Component)]
pub struct Value(f32);
fn display_sum(sum: Single<&SumChildComponents, With<Marker>>, mut display: Single<&mut Text>) {
display.0 = sum.0.to_string();
}
I'm not familiar with the code behind queries, so I'm not certain how possible this would be, nor the performance implications.
I'm also aware that the way I've done it now makes it easy for a user to query for an ephemeral value without realising, which some users may not like, though this could be easily solved with a wrapper.
What alternative(s) have you considered?
Continue as before.