Path: blob/main/crates/bevy_asset/src/io/embedded/embedded_watcher.rs
9418 views
use crate::io::{1file::{get_asset_path, get_base_path, new_asset_event_debouncer, FilesystemEventHandler},2memory::Dir,3AssetSourceEvent, AssetWatcher,4};5use alloc::{boxed::Box, sync::Arc, vec::Vec};6use bevy_platform::collections::HashMap;7use bevy_platform::sync::{PoisonError, RwLock};8use core::time::Duration;9use notify_debouncer_full::{notify::RecommendedWatcher, Debouncer, RecommendedCache};10use std::{11fs::File,12io::{BufReader, Read},13path::{Path, PathBuf},14};15use tracing::warn;1617/// A watcher for assets stored in the `embedded` asset source. Embedded assets are assets whose18/// bytes have been embedded into the Rust binary using the [`embedded_asset`](crate::embedded_asset) macro.19/// This watcher will watch for changes to the "source files", read the contents of changed files from the file system20/// and overwrite the initial static bytes of the file embedded in the binary with the new dynamically loaded bytes.21pub struct EmbeddedWatcher {22_watcher: Debouncer<RecommendedWatcher, RecommendedCache>,23}2425impl EmbeddedWatcher {26/// Creates a new `EmbeddedWatcher` that watches for changes to the embedded assets in the given `dir`.27pub fn new(28dir: Dir,29root_paths: Arc<RwLock<HashMap<Box<Path>, PathBuf>>>,30sender: async_channel::Sender<AssetSourceEvent>,31debounce_wait_time: Duration,32) -> Self {33let root = get_base_path();34let handler = EmbeddedEventHandler {35dir,36root: root.clone(),37sender,38root_paths,39last_event: None,40};41let watcher = new_asset_event_debouncer(root, debounce_wait_time, handler).unwrap();42Self { _watcher: watcher }43}44}4546impl AssetWatcher for EmbeddedWatcher {}4748/// A [`FilesystemEventHandler`] that uses [`EmbeddedAssetRegistry`](crate::io::embedded::EmbeddedAssetRegistry) to hot-reload49/// binary-embedded Rust source files. This will read the contents of changed files from the file system and overwrite50/// the initial static bytes from the file embedded in the binary.51pub(crate) struct EmbeddedEventHandler {52sender: async_channel::Sender<AssetSourceEvent>,53root_paths: Arc<RwLock<HashMap<Box<Path>, PathBuf>>>,54root: PathBuf,55dir: Dir,56last_event: Option<AssetSourceEvent>,57}5859impl FilesystemEventHandler for EmbeddedEventHandler {60fn begin(&mut self) {61self.last_event = None;62}6364fn get_path(&self, absolute_path: &Path) -> Option<(PathBuf, bool)> {65let (local_path, is_meta) = get_asset_path(&self.root, absolute_path);66let final_path = self67.root_paths68.read()69.unwrap_or_else(PoisonError::into_inner)70.get(local_path.as_path())?71.clone();72if is_meta {73warn!("Meta file asset hot-reloading is not supported yet: {final_path:?}");74}75Some((final_path, false))76}7778fn handle(&mut self, absolute_paths: &[PathBuf], event: AssetSourceEvent) {79if self.last_event.as_ref() != Some(&event) {80if let AssetSourceEvent::ModifiedAsset(path) = &event81&& let Ok(file) = File::open(&absolute_paths[0])82{83let mut reader = BufReader::new(file);84let mut buffer = Vec::new();8586// Read file into vector.87if reader.read_to_end(&mut buffer).is_ok() {88self.dir.insert_asset(path, buffer);89}90}91self.last_event = Some(event.clone());92self.sender.send_blocking(event).unwrap();93}94}95}969798