support for compute shaders
This commit is contained in:
121
src/watch.rs
121
src/watch.rs
@@ -13,12 +13,27 @@ pub struct Watch {
|
||||
pub rx: Receiver<Result<Message, Error>>,
|
||||
}
|
||||
|
||||
struct Loader {
|
||||
enum Loader {
|
||||
Graphics(GraphicsLoader),
|
||||
Compute(ComputeLoader),
|
||||
}
|
||||
|
||||
enum SrcPath {
|
||||
Graphics(PathBuf, PathBuf),
|
||||
Compute(PathBuf),
|
||||
}
|
||||
|
||||
struct GraphicsLoader {
|
||||
vertex: PathBuf,
|
||||
fragment: PathBuf,
|
||||
tx: Sender<Result<Message, Error>>,
|
||||
}
|
||||
|
||||
struct ComputeLoader {
|
||||
compute: PathBuf,
|
||||
tx: Sender<Result<Message, Error>>,
|
||||
}
|
||||
|
||||
pub struct Message {
|
||||
pub shaders: CompiledShaders,
|
||||
pub entry: Entry,
|
||||
@@ -31,9 +46,28 @@ impl Watch {
|
||||
where
|
||||
T: AsRef<Path>,
|
||||
{
|
||||
let (handler, rx) = create_watch(
|
||||
let src_path = SrcPath::Graphics(
|
||||
vertex.as_ref().to_path_buf(),
|
||||
fragment.as_ref().to_path_buf(),
|
||||
fragment.as_ref().to_path_buf()
|
||||
);
|
||||
let (handler, rx) = create_watch(
|
||||
src_path,
|
||||
frequency,
|
||||
)?;
|
||||
Ok(Watch {
|
||||
_handler: handler,
|
||||
rx,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn create_compute<T>(compute: T, frequency: Duration) -> Result<Self, Error>
|
||||
where
|
||||
T: AsRef<Path>,
|
||||
{
|
||||
let src_path = SrcPath::Compute(
|
||||
compute.as_ref(). to_path_buf());
|
||||
let (handler, rx) = create_watch(
|
||||
src_path,
|
||||
frequency,
|
||||
)?;
|
||||
Ok(Watch {
|
||||
@@ -43,10 +77,10 @@ impl Watch {
|
||||
}
|
||||
}
|
||||
|
||||
impl Loader {
|
||||
impl GraphicsLoader {
|
||||
fn create(vertex: PathBuf, fragment: PathBuf) -> (Self, Receiver<Result<Message, Error>>) {
|
||||
let (tx, rx) = mpsc::channel();
|
||||
let loader = Loader {
|
||||
let loader = GraphicsLoader {
|
||||
vertex,
|
||||
fragment,
|
||||
tx,
|
||||
@@ -67,6 +101,38 @@ impl Loader {
|
||||
}
|
||||
}
|
||||
|
||||
impl ComputeLoader {
|
||||
fn create(compute: PathBuf) -> (Self, Receiver<Result<Message, Error>>) {
|
||||
let (tx, rx) = mpsc::channel();
|
||||
let loader = ComputeLoader {
|
||||
compute,
|
||||
tx,
|
||||
};
|
||||
loader.reload();
|
||||
(loader, rx)
|
||||
}
|
||||
|
||||
fn reload(&self) {
|
||||
match crate::load_compute(&self.compute) {
|
||||
Ok(shaders) => {
|
||||
let entry = crate::parse_compute(&shaders);
|
||||
let msg = entry.map(|entry| Message { shaders, entry });
|
||||
self.tx.send(msg).ok()
|
||||
}
|
||||
Err(e) => self.tx.send(Err(e)).ok(),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
impl Loader {
|
||||
fn reload(&self) {
|
||||
match self {
|
||||
Loader::Graphics(g) => g.reload(),
|
||||
Loader::Compute(g) => g.reload(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct Handler {
|
||||
thread_tx: mpsc::Sender<()>,
|
||||
handle: Option<thread::JoinHandle<()>>,
|
||||
@@ -83,8 +149,7 @@ impl Drop for Handler {
|
||||
}
|
||||
|
||||
fn create_watch(
|
||||
vert_path: PathBuf,
|
||||
frag_path: PathBuf,
|
||||
src_path: SrcPath,
|
||||
frequency: Duration
|
||||
) -> Result<(Handler, mpsc::Receiver<Result<Message, Error>>), Error> {
|
||||
let (notify_tx, notify_rx) = mpsc::channel();
|
||||
@@ -92,20 +157,36 @@ fn create_watch(
|
||||
let mut watcher: RecommendedWatcher =
|
||||
Watcher::new(notify_tx, frequency).map_err(Error::FileWatch)?;
|
||||
|
||||
let mut vp = vert_path.clone();
|
||||
let mut fp = frag_path.clone();
|
||||
vp.pop();
|
||||
fp.pop();
|
||||
watcher
|
||||
.watch(&vp, RecursiveMode::NonRecursive)
|
||||
.map_err(Error::FileWatch)?;
|
||||
if vp != fp {
|
||||
watcher
|
||||
.watch(&fp, RecursiveMode::NonRecursive)
|
||||
.map_err(Error::FileWatch)?;
|
||||
}
|
||||
let (loader, rx) = match src_path {
|
||||
SrcPath::Graphics(vert_path, frag_path) => {
|
||||
let mut vp = vert_path.clone();
|
||||
let mut fp = frag_path.clone();
|
||||
vp.pop();
|
||||
fp.pop();
|
||||
watcher
|
||||
.watch(&vp, RecursiveMode::NonRecursive)
|
||||
.map_err(Error::FileWatch)?;
|
||||
if vp != fp {
|
||||
watcher
|
||||
.watch(&fp, RecursiveMode::NonRecursive)
|
||||
.map_err(Error::FileWatch)?;
|
||||
}
|
||||
|
||||
let (loader, rx) = GraphicsLoader::create(vert_path, frag_path);
|
||||
(Loader::Graphics(loader), rx)
|
||||
}
|
||||
SrcPath::Compute(compute_path) => {
|
||||
let mut cp = compute_path.clone();
|
||||
cp.pop();
|
||||
watcher
|
||||
.watch(&cp, RecursiveMode::NonRecursive)
|
||||
.map_err(Error::FileWatch)?;
|
||||
|
||||
let (loader, rx) = ComputeLoader::create(compute_path);
|
||||
(Loader::Compute(loader), rx)
|
||||
}
|
||||
};
|
||||
|
||||
let (loader, rx) = Loader::create(vert_path, frag_path);
|
||||
|
||||
let handle = thread::spawn(move || 'watch_loop: loop {
|
||||
if thread_rx.try_recv().is_ok() {
|
||||
|
||||
Reference in New Issue
Block a user