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

Code before:
            TexturePlugin,
            BatchingPlugin {
                debug_flags: self.debug_flags,
            },
            SyncWorldPlugin,
            StoragePlugin,
            GpuReadbackPlugin::default(),
            OcclusionCullingPlugin,
            #[cfg(feature = "tracing-tracy")]
            diagnostic::RenderDiagnosticsPlugin,
        ));

        app.init_resource::<RenderAssetBytesPerFrame>();
        if let Some(render_app) = app.get_sub_app_mut(RenderApp) {
            render_app.init_resource::<RenderAssetBytesPerFrameLimiter>();
            render_app
                .add_systems(ExtractSchedule, extract_render_asset_bytes_per_frame)
                .add_systems(
                    Render,
                    reset_render_asset_bytes_per_frame.in_set(RenderSystems::Cleanup),
                );
        }
    }

    fn ready(&self, app: &App) -> bool {
        app.world().get_resource::<RenderResources>().is_some()
    }

    fn finish(&self, app: &mut App) {
        load_shader_library!(app, "maths.wgsl");
        load_shader_library!(app, "color_operations.wgsl");
        load_shader_library!(app, "bindless.wgsl");
        if let Some(render_resources) = app.world_mut().remove_resource::<RenderResources>() {
            let RenderResources(device, queue, adapter_info, render_adapter, instance, ..) =
                render_resources;

            let compressed_image_format_support = CompressedImageFormatSupport(
                CompressedImageFormats::from_features(device.features()),
            );

            app.insert_resource(device.clone())
                .insert_resource(queue.clone())
                .insert_resource(adapter_info.clone())
                .insert_resource(render_adapter.clone())
                .insert_resource(compressed_image_format_support);

            let render_app = app.sub_app_mut(RenderApp);

            #[cfg(feature = "raw_vulkan_init")]
            {
                let additional_vulkan_features: renderer::raw_vulkan_init::AdditionalVulkanFeatures =

Review comment (bug):
This might not help, but I checked out your branch to see why the `no_renderer` example is failing, and I think it might have something to do with the `ready` function. If I change this to just return `true`, the example runs fine / I am able to close the window.

The previous `ready` seems to return true even if it wasn’t able to lock `FutureRenderResources` iiuc. I wonder if the example is able to progress because of that rather than progressing because `RenderResources` is `Some`

Code after:
                .add_systems(ExtractSchedule, extract_render_asset_bytes_per_frame)
                .add_systems(
                    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) {
        load_shader_library!(app, "maths.wgsl");
        load_shader_library!(app, "color_operations.wgsl");
        load_shader_library!(app, "bindless.wgsl");
        if let Some(future_render_resources) =
            app.world_mut().remove_resource::<FutureRenderResources>()
        {
            let render_resources = future_render_resources.0.lock().unwrap().take().unwrap();
            let RenderResources(device, queue, adapter_info, render_adapter, instance, ..) =
                render_resources;

            let compressed_image_format_support = CompressedImageFormatSupport(
                CompressedImageFormats::from_features(device.features()),
            );

            app.insert_resource(device.clone())
                .insert_resource(queue.clone())
                .insert_resource(adapter_info.clone())
                .insert_resource(render_adapter.clone())
                .insert_resource(compressed_image_format_support);

            let render_app = app.sub_app_mut(RenderApp);

            #[cfg(feature = "raw_vulkan_init")]
            {
                let additional_vulkan_features: renderer::raw_vulkan_init::AdditionalVulkanFeatures =
                    render_resources.5;
                render_app.insert_resource(additional_vulkan_features);