1use wgpu::CompilationMessageType;
5
6use crate::graphics::Driver;
7use crate::shaders;
8
9pub fn create_hotloader<T: 'static>(
10 path: &std::path::Path,
11 label: &'static str,
12 driver: std::sync::Weak<Driver>,
13) -> eyre::Result<notify::RecommendedWatcher> {
14 use notify::Watcher;
15 let mut prev = std::fs::read_to_string(path)?;
16 let pathbuf = path.to_owned();
17 let mut watcher = notify::recommended_watcher(move |_| {
18 if let Some(driver) = driver.upgrade() {
19 let contents = std::fs::read_to_string(&pathbuf).unwrap();
20 if contents != prev {
21 prev = contents;
22 driver
23 .device
24 .push_error_scope(wgpu::ErrorFilter::Validation);
25 let module = shaders::load_wgsl(&driver.device, label, &prev);
26 let err = futures_lite::future::block_on(driver.device.pop_error_scope());
27 if let Some(e) = err {
28 println!("{e}");
29 } else {
30 let info = futures_lite::future::block_on(module.get_compilation_info());
31
32 let mut errored = false;
33 for m in info.messages {
34 println!("{m:?}");
35 errored = errored || m.message_type == CompilationMessageType::Error;
36 }
37 if !errored {
38 driver.reload_pipeline::<T>(module);
39 }
40 }
41 }
42 }
43 })?;
44
45 watcher.watch(path, notify::RecursiveMode::NonRecursive)?;
46
47 Ok(watcher)
48}
49
50pub(crate) fn alloca_array<T, R>(n: usize, f: impl FnOnce(&mut [T]) -> R) -> R {
52 use std::mem::{align_of, size_of};
53
54 alloca::with_alloca_zeroed(
55 (n * size_of::<T>()) + (align_of::<T>() - 1),
56 |memory| unsafe {
57 let mut raw_memory = memory.as_mut_ptr();
58 if raw_memory as usize % align_of::<T>() != 0 {
59 raw_memory =
60 raw_memory.add(align_of::<T>() - raw_memory as usize % align_of::<T>());
61 }
62
63 f(std::slice::from_raw_parts_mut::<T>(
64 raw_memory.cast::<T>(),
65 n,
66 ))
67 },
68 )
69}