#How do I feed a resource to a sub function that requires it

1 messages · Page 1 of 1 (latest)

grizzled orchid
#

how do I feed resources to a function?

I have a function which implements a trait to load assets from the asset server
but rust complains about things being moved in the loop

use of moved value: `things`
value moved here, in previous iteration of loop
pub fn deserialize_wrapper_for<WrapperThing, Thing> (
    mut things: ResMut<Assets<Thing>>,
    wrapper_thing_query: Query<(Entity, &WrapperThing), Without<Handle<Thing>>>,
    asset_server: Res<AssetServer>,
    mut commands: Commands,
) 
    where
        WrapperThing: Component + ECSLoad<Thing>,
        Thing: Asset + TypeUuid
{
    for (e, wrapper_thing) in wrapper_thing_query.iter() {
        let thing_handle = WrapperThing::load_from(wrapper_thing, things, asset_server);
    
        commands.entity(e).insert(
            thing_handle
        );
    }
}

but when I try to make it a reference:

impl ECSLoad<Mesh> for GeometryFlag {
    fn load_from(value: &Self, mut things: &ResMut<Assets<Mesh>>, asset_server: Res<AssetServer>) -> Handle<Mesh>{
        match value {
            Self::Primitive(primitive) => {
                match primitive {
                    MeshPrimitive::Box { size } => {
                        things.add(shape::Box{
                            min_x: -size[0] * 0.5,
                            max_x: size[0] * 0.5,
                            min_y: -size[1] * 0.5,
                            max_y: size[1] * 0.5,
                            min_z: -size[2] * 0.5,
                            max_z: size[2] * 0.5,
                        }.into())
                    }
                    ... Rest of implementation

my load trait complains that things.add cant be used to via a reference since things doesn't implement Copy. How do I feed the Things + asset_server to ECSLoad<T>?

#

How do I feed a resource to a sub function that requires it

grizzled orchid
#

After thinking about the problem more. I realized that requiring the wrapper consume ResMut was a bad idea, and I changed it from returning a handle<Thing> into returning a Result<Thing, String>

#

pub fn deserialize_wrapper_for<WrapperThing, Thing> (
    mut things: ResMut<Assets<Thing>>,
    wrapper_thing_query: Query<(Entity, &WrapperThing), Without<Handle<Thing>>>,
    asset_server: Res<AssetServer>,
    mut commands: Commands,
) 
    where
        WrapperThing: Component + ECSLoad<Thing>,
        Thing: Asset + TypeUuid
{
    for (e, wrapper_thing) in wrapper_thing_query.iter() {
        let thing_fetch_attempt = WrapperThing::load_from(wrapper_thing);
    
        match thing_fetch_attempt {
            Ok(thing) => {
               let thing_handle = things.add(thing);
                commands.entity(e).insert(
                    thing_handle
                );
            }
            Err(file_path) => {
                let thing_handle: Handle<Thing> = asset_server.load(file_path);
                commands.entity(e).insert(
                    thing_handle
                );
            }
        }
    }
}