gled-ui 2.32.1

gled's egui interface, shared by the desktop app and the browser
Documentation
use eframe::egui_wgpu::CallbackTrait;
use kanal::{Receiver, Sender, bounded};
use std::sync::LazyLock;
use wgpu::CommandBuffer;

/// Command buffers recorded while drawing, submitted when egui paints.
static QUEUE: LazyLock<(Sender<CommandBuffer>, Receiver<CommandBuffer>)> =
    LazyLock::new(|| bounded(16));

#[derive(Debug)]
pub(crate) struct RendererCallback;

impl RendererCallback {
    /// Queues `buffer` for the next paint. Waits while the queue is full on
    /// the desktop; a browser has no other thread to empty it, so there the
    /// buffer is dropped instead.
    #[cfg_attr(feature = "profiling", profiling::function)]
    pub(crate) fn add(buffer: CommandBuffer) {
        #[cfg(not(target_arch = "wasm32"))]
        if QUEUE.0.send(buffer).is_err() {
            tracing::warn!("The renderer callback queue is closed");
        }
        #[cfg(target_arch = "wasm32")]
        Self::try_add(buffer);
    }
}

impl RendererCallback {
    /// Like `add`, but drops the buffer instead of blocking when egui has not
    /// painted for a while. For work that is redone every frame anyway.
    pub(crate) fn try_add(buffer: CommandBuffer) {
        let sent = QUEUE.0.try_send(buffer);
        if !matches!(sent, Ok(true)) {
            tracing::trace!("Renderer callback queue is full, dropped a command buffer");
        }
    }
}

impl CallbackTrait for RendererCallback {
    fn paint(
        &self,
        _info: egui::PaintCallbackInfo,
        _render_pass: &mut wgpu::RenderPass<'static>,
        _callback_resources: &eframe::egui_wgpu::CallbackResources,
    ) {
    }

    #[cfg_attr(feature = "profiling", profiling::function)]
    fn prepare(
        &self,
        _device: &wgpu::Device,
        _queue: &wgpu::Queue,
        _screen_descriptor: &eframe::egui_wgpu::ScreenDescriptor,
        _egui_encoder: &mut wgpu::CommandEncoder,
        _callback_resources: &mut eframe::egui_wgpu::CallbackResources,
    ) -> Vec<wgpu::CommandBuffer> {
        let mut buffers = Vec::with_capacity(16);

        while let Ok(Some(buffer)) = QUEUE.1.try_recv() {
            buffers.push(buffer);
        }

        buffers
    }

    fn finish_prepare(
        &self,
        _device: &wgpu::Device,
        _queue: &wgpu::Queue,
        _egui_encoder: &mut wgpu::CommandEncoder,
        _callback_resources: &mut eframe::egui_wgpu::CallbackResources,
    ) -> Vec<wgpu::CommandBuffer> {
        Vec::new()
    }
}