rustbevyentity-component-system

Copy from Render World to Main World using Bevy 0.12/0.13


I would like to copy a resource from the render world to the main world. How can I achieve this?

e.g., I have a resource like this:

#[derive(Resource, Clone, Deref, ExtractResource, Reflect)]
pub struct SharedData(pub Vec<u8>);

and write to it in a RenderWorld-system like

fn store(mut data: ResMut<SharedData>, /* ... */) {
    // ...
    data.0 = something.clone();
}

that is registered like

app.register_type::<SharedData>()
   .add_plugins(ExtractResourcePlugin::<SharedData>::default())
   .add_systems(PreUpdate, check_vec_len);

let render_app = app.sub_app_mut(RenderApp);
render_app.add_systems(
        Render,
        store
            .after(RenderSet::Render)
            .before(RenderSet::Cleanup),
    );

However, when checking the contents of SharedData from the MainWorld, it is not modified at all:

fn check_vec_len(extracted: Res<SharedData>) {
    println!("Extracted data: {:?}", extracted.0); // returns empty Vec
}

How to copy the results back to the MainWorld?


Solution

  • Thanks to Bubbly_Expression_38 on reddit I figured out you can simply use the following Extract-System:

    pub fn sync_data(render_world_data: Res<SharedData>, mut world: ResMut<MainWorld>) {
        let mut main_world_data = world.get_resource_mut::<SharedData>().unwrap();
        main_world_data.raw = render_world_data.raw.clone();
    }
    

    and register it like

    render_app.init_resource::<SharedData>()
              .add_systems(ExtractSchedule, sync_data)
    
    app.register_type::<SharedData>()
       .insert_resource(SharedData::default())
    

    without using the ExtractResource-Plugin.