Skip to content

Ephemeral Components #20680

@Freyja-moth

Description

@Freyja-moth

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-ECSEntities, components, systems, and eventsC-FeatureA new feature, making something new possibleS-Nominated-To-CloseA triage team member thinks this PR or issue should be closed out.X-ControversialThere is active debate or serious implications around merging this PR

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions