Repository: bevyengine/bevy
File: crates/bevy_render/src/extract_plugin.rs (Rust)

Code before:
/// See [`Extract`](crate::Extract) for more details.
#[derive(Resource, Default)]
pub struct MainWorld(World);

impl Deref for MainWorld {
    type Target = World;

    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

impl DerefMut for MainWorld {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.0
    }
}

/// A "scratch" world used to avoid allocating new worlds every frame when
/// swapping out the [`MainWorld`] for [`ExtractSchedule`].
#[derive(Resource, Default)]
struct ScratchMainWorld(World);

/// Executes the [`ExtractSchedule`] step of the renderer.
/// This updates the render world with the extracted ECS data of the current frame.
pub fn extract(main_world: &mut World, render_world: &mut World) {
    // temporarily add the app world to the render world as a resource
    let scratch_world = main_world.remove_resource::<ScratchMainWorld>().unwrap();
    let inserted_world = core::mem::replace(main_world, scratch_world.0);
    render_world.insert_resource(MainWorld(inserted_world));
    render_world.run_schedule(ExtractSchedule);

    // move the app world back, as if nothing happened.
    let inserted_world = render_world.remove_resource::<MainWorld>().unwrap();
    let scratch_world = core::mem::replace(main_world, inserted_world.0);
    main_world.insert_resource(ScratchMainWorld(scratch_world));
}

#[cfg(test)]
mod test {
    use bevy_app::{App, Startup};
    use bevy_ecs::{prelude::*, schedule::ScheduleLabel};

    use crate::{
        extract_component::{ExtractComponent, ExtractComponentPlugin},
        extract_plugin::ExtractPlugin,
        sync_world::MainEntity,
        Render, RenderApp,
    };

    #[derive(Component, Clone, Debug)]

Review comment (refactor):
```suggestion
    // temporarily add the app world to the render world as a resource
    let scratch_world = main_world.remove_resource::<ScratchMainWorld>().unwrap();
    let inserted_world = core::mem::replace(main_world, scratch_world);
    render_world.insert_resource(MainWorld(inserted_world));
    render_world.run_schedule(ExtractSchedule);

    // move the app world back, as if nothing happened.
    let inserted_world = render_world.remove_resource::<MainWorld>().unwrap();
    let scratch_world = core::mem::replace(main_world, inserted_world);
    main_world.insert_resource(ScratchMainWorld(scratch_world));
```

Code after:
/// The simulation [`World`] of the application, stored as a resource.
///
/// This resource is only available during [`ExtractSchedule`] and not
/// during command application of that schedule.
/// See [`Extract`](crate::Extract) for more details.
#[derive(Resource, Default, Deref, DerefMut)]
pub struct MainWorld(World);

/// A "scratch" world used to avoid allocating new worlds every frame when
/// swapping out the [`MainWorld`] for [`ExtractSchedule`].
#[derive(Resource, Default)]
struct ScratchMainWorld(World);

/// Executes the [`ExtractSchedule`] step of the renderer.
/// This updates the render world with the extracted ECS data of the current frame.
pub fn extract(main_world: &mut World, render_world: &mut World) {
    // temporarily add the app world to the render world as a resource
    let scratch_world = main_world.remove_resource::<ScratchMainWorld>().unwrap();
    let inserted_world = core::mem::replace(main_world, scratch_world.0);
    render_world.insert_resource(MainWorld(inserted_world));
    render_world.run_schedule(ExtractSchedule);

    // move the app world back, as if nothing happened.
    let inserted_world = render_world.remove_resource::<MainWorld>().unwrap();
    let scratch_world = core::mem::replace(main_world, inserted_world.0);
    main_world.insert_resource(ScratchMainWorld(scratch_world));
}

#[cfg(test)]
mod test {
    use bevy_app::{App, Startup};
    use bevy_ecs::{prelude::*, schedule::ScheduleLabel};

    use crate::{
        extract_component::{ExtractComponent, ExtractComponentPlugin},
        extract_plugin::ExtractPlugin,
        sync_world::MainEntity,
        Render, RenderApp,
    };

    #[derive(Component, Clone, Debug)]
    struct RenderComponent;

    #[derive(Component, Clone, Debug)]
    struct RenderComponentExtra;

    #[derive(Component, Clone, Debug, ExtractComponent)]
    struct RenderComponentSeparate;

    #[derive(Component, Clone, Debug)]
    struct RenderComponentNoExtract;