Allow removing asset from embedded asset registry (#14912)

# Objective

- Allow not only inserting `Data` into `EmbeddedAssetRegistry` and `Dir`
in turn but now also removing it again.
- This way when used to embed asset data from *somewhere* but not load
it using the conventional means via `AssetServer` (which I observed
takes ownership of the `Data`) the `Data` does not need to stay in
memory of the `EmbeddedAssetRegistry` throughout the lifetime of the
application.

## Solution

- added the `remove_asset` functions in `EmbeddedAssetRegistry` and
`Dir`

## Testing

- added a module unittest
- does this require changes if build with feature `embedded_watcher`?
This commit is contained in:
extrawurst 2024-08-27 02:29:05 +08:00 committed by GitHub
parent 484721be80
commit 23979b8160
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 30 additions and 1 deletions

View file

@ -52,6 +52,13 @@ impl EmbeddedAssetRegistry {
self.dir.insert_meta(asset_path, value);
}
/// Removes an asset stored using `full_path` (the full path as [`file`] would return for that file, if it was capable of
/// running in a non-rust file). If no asset is stored with at `full_path` its a no-op.
/// It returning `Option` contains the originally stored `Data` or `None`.
pub fn remove_asset(&self, full_path: &Path) -> Option<super::memory::Data> {
self.dir.remove_asset(full_path)
}
/// Registers a `embedded` [`AssetSource`] that uses this [`EmbeddedAssetRegistry`].
// NOTE: unused_mut because embedded_watcher feature is the only mutable consumer of `let mut source`
#[allow(unused_mut)]
@ -300,7 +307,7 @@ macro_rules! load_internal_binary_asset {
#[cfg(test)]
mod tests {
use super::_embedded_asset_path;
use super::{EmbeddedAssetRegistry, _embedded_asset_path};
use std::path::Path;
// Relative paths show up if this macro is being invoked by a local crate.
@ -404,4 +411,15 @@ mod tests {
// Really, should be "my_crate/src/the/asset.png"
assert_eq!(asset_path, Path::new("my_crate/the/asset.png"));
}
#[test]
fn remove_embedded_asset() {
let reg = EmbeddedAssetRegistry::default();
let path = std::path::PathBuf::from("a/b/asset.png");
reg.insert_asset(path.clone(), &path, &[]);
assert!(reg.dir.get_asset(&path).is_some());
assert!(reg.remove_asset(&path).is_some());
assert!(reg.dir.get_asset(&path).is_none());
assert!(reg.remove_asset(&path).is_none());
}
}

View file

@ -55,6 +55,17 @@ impl Dir {
);
}
/// Removes the stored asset at `path` and returns the `Data` stored if found and otherwise `None`.
pub fn remove_asset(&self, path: &Path) -> Option<Data> {
let mut dir = self.clone();
if let Some(parent) = path.parent() {
dir = self.get_or_insert_dir(parent);
}
let key: Box<str> = path.file_name().unwrap().to_string_lossy().into();
let data = dir.0.write().assets.remove(&key);
data
}
pub fn insert_meta(&self, path: &Path, value: impl Into<Value>) {
let mut dir = self.clone();
if let Some(parent) = path.parent() {