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

Code before:
                ),
            );

            render_app.init_schedule(RenderStartup);
            render_app.update_schedule = Some(RenderRecovery.intern());
            render_app.add_systems(RenderRecovery, move |world: &mut World| {
                if matches!(world.resource::<RenderState>(), RenderState::Ready) {
                    world.run_schedule(Render);
                }

                // update the time and send it to the app world regardless of whether we render
                let time_sender = world.resource::<TimeSender>();
                if let Err(error) = time_sender.0.try_send(Instant::now()) {
                    match error {
                        bevy_time::TrySendError::Full(_) => {
                            panic!(
                                "The TimeSender channel should always be empty during render. \
                            You might need to add the bevy::core::time_system to your app."
                            );
                        }
                        bevy_time::TrySendError::Disconnected(_) => {
                            // ignore disconnected errors, the main world probably just got dropped during shutdown
                        }
                    }
                }
            });
            render_app.add_systems(
                Render,
                (
                    (PipelineCache::process_pipeline_queue_system, render_system)
                        .chain()
                        .in_set(RenderSystems::Render),
                    reset_render_asset_bytes_per_frame.in_set(RenderSystems::Cleanup),
                ),
            );
        }
    }

    fn ready(&self, app: &App) -> bool {
        // This is a little tricky. `FutureRenderResources` is added in `build`, which runs synchronously before `ready`.
        // It is only added if there is a wgpu backend and thus the renderer can be created.
        // Hence, if we try and get the resource and it is not present, that means we are ready, because we dont need it.
        // On the other hand, if the resource is present, then we try and lock on it. The lock can fail, in which case
        // we currently can assume that means the `FutureRenderResources` is in the act of being populated, because
        // that is the only other place the lock may be held. If it is being populated, we can assume we're ready. This
        // happens via the `and_then` falling through to the same `unwrap_or(true)` case as when there's no resource.
        // If the lock succeeds, we can straightforwardly check if it is populated. If it is not, then we're not ready.
        app.world()
            .get_resource::<FutureRenderResources>()
            .and_then(|frr| frr.try_lock().map(|locked| locked.is_some()).ok())
            .unwrap_or(true)

Review comment (refactor):
this is a refactor i should have probably done in my pr, but since we're here now, can you make this be a couple real systems and not a single closure? call them `render_if_ready` and `send_time`, and chain order them please thanks 💚 

Code after:
                ),
            );

            render_app.init_schedule(RenderStartup);
            render_app.update_schedule = Some(RenderRecovery.intern());
            render_app.add_systems(
                RenderRecovery,
                (run_render_schedule.run_if(renderer_is_ready), send_time).chain(),
            );
            render_app.add_systems(
                Render,
                (
                    (PipelineCache::process_pipeline_queue_system, render_system)
                        .chain()
                        .in_set(RenderSystems::Render),
                    reset_render_asset_bytes_per_frame.in_set(RenderSystems::Cleanup),
                ),
            );
        }
    }

    fn ready(&self, app: &App) -> bool {
        // This is a little tricky. `FutureRenderResources` is added in `build`, which runs synchronously before `ready`.
        // It is only added if there is a wgpu backend and thus the renderer can be created.
        // Hence, if we try and get the resource and it is not present, that means we are ready, because we dont need it.
        // On the other hand, if the resource is present, then we try and lock on it. The lock can fail, in which case
        // we currently can assume that means the `FutureRenderResources` is in the act of being populated, because
        // that is the only other place the lock may be held. If it is being populated, we can assume we're ready. This
        // happens via the `and_then` falling through to the same `unwrap_or(true)` case as when there's no resource.
        // If the lock succeeds, we can straightforwardly check if it is populated. If it is not, then we're not ready.
        app.world()
            .get_resource::<FutureRenderResources>()
            .and_then(|frr| frr.try_lock().map(|locked| locked.is_some()).ok())
            .unwrap_or(true)
    }

    fn finish(&self, app: &mut App) {
        if let Some(future_render_resources) =
            app.world_mut().remove_resource::<FutureRenderResources>()
        {
            let bevy_app::SubApps { main, sub_apps } = app.sub_apps_mut();
            let render = sub_apps.get_mut(&RenderApp.intern()).unwrap();
            let render_resources = future_render_resources.0.lock().unwrap().take().unwrap();

            render_resources.unpack_into(
                main.world_mut(),
                render.world_mut(),
                self.synchronous_pipeline_compilation,
            );
        }
    }