Skip to content

Generic Queries and Lifetimes #26

@bbarker

Description

@bbarker

In this discord thread we basically weren't able to resolve the issue of how to make this code generic:

pub fn get_player_last_comp_system<'a, 'q, Q: Clone>(
    query: Query<'_, '_, &'q Q, With<Player>>,
) -> Option<Q>
// Rust seems to want this return type: Option<<<&'q Q as QueryData>::ReadOnly as WorldQuery>::Item<'q>>
where
    &'q Q: QueryData,
    for<'b> <<&'q Q as QueryData>::ReadOnly as WorldQuery>::Item<'b>: Clone,
{
    let data = query.iter().last();
    let foo = data.map(|res| res.clone());
    foo
}

Also this doesn't work:

// Doesn't work since we can't query bundles:
pub fn get_player_component2_system<C1: Component + Clone, C2: Component + Clone>(
    In(player_name): In<String>,
    query: Query<'_, '_, (&(C1, C2), &Name), With<Player>>,
) -> Option<(C1, C2)> {
    let data = query
        .iter()
        .find_map(|(data, name)| (name.to_string() == player_name).then_some(data));

    data.cloned()
}

But we can do one function for each # of components:

pub fn get_player_component1_system<C: Component + Clone>(
    In(player_name): In<String>,
    query: Query<'_, '_, (&C, &Name), With<Player>>,
) -> Option<C> {
    let data = query
        .iter()
        .find_map(|(data, name)| (name.to_string() == player_name).then_some(data));

    data.cloned()
}

pub fn get_player_component2_system<C1: Component + Clone, C2: Component + Clone>(
    In(player_name): In<String>,
    query: Query<'_, '_, (&C1, &C2, &Name), With<Player>>,
) -> Option<(C1, C2)> {
    let data = query
        .iter()
        .find_map(|(c1, c2, name)| (name.to_string() == player_name).then_some((c1, c2)));

    data.map(|(c1, c2)| (c1.clone(), c2.clone()))
}

We can however make it generic for

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions