cranpose-render-wgpu 0.1.86

WGPU renderer backend for Cranpose
Documentation
use std::sync::OnceLock;
use web_time::Instant;

/// Creates an immutable GPU resource on first use and reports its real cost.
pub(crate) struct LazyGpuResource<T> {
    label: &'static str,
    value: OnceLock<T>,
}

impl<T> LazyGpuResource<T> {
    pub(crate) const fn new(label: &'static str) -> Self {
        Self {
            label,
            value: OnceLock::new(),
        }
    }

    pub(crate) fn get_or_init(&self, backend: wgpu::Backend, create: impl FnOnce() -> T) -> &T {
        self.value.get_or_init(|| {
            let started = Instant::now();
            let value = create();
            log::info!(
                "[gpu-pipeline] {:?} {} ready in {:.1} ms",
                backend,
                self.label,
                crate::render::instant_ms(started, Instant::now()),
            );
            value
        })
    }

    pub(crate) fn get(&self) -> Option<&T> {
        self.value.get()
    }

    #[cfg(test)]
    fn initialized(&self) -> bool {
        self.value.get().is_some()
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::cell::Cell;

    #[test]
    fn resource_is_created_only_when_first_requested() {
        let resource = LazyGpuResource::new("test");
        let calls = Cell::new(0);
        assert!(!resource.initialized());

        let first = resource.get_or_init(wgpu::Backend::Gl, || {
            calls.set(calls.get() + 1);
            41
        });
        let second = resource.get_or_init(wgpu::Backend::Gl, || {
            calls.set(calls.get() + 1);
            99
        });

        assert_eq!((*first, *second), (41, 41));
        assert_eq!(calls.get(), 1);
        assert!(resource.initialized());
    }
}