Make ResourceStorage trait &self-based and remove 'static requirement (#4188)

* Make ResourceStorage trait &self-based with elided-lifetime ResourceFuture

* Adress review comments
This commit is contained in:
Dennis Kobert
2026-06-01 12:37:05 +02:00
committed by GitHub
parent e32ff4b7f0
commit 7b9c480a8d
12 changed files with 52 additions and 48 deletions

View File

@@ -60,8 +60,14 @@ impl ApplicationIo for PlatformApplicationIo {
self.gpu_executor.as_ref()
}
fn load_resource(&self, hash: resource::ResourceHash) -> resource::ResourceFuture {
self.resources.as_ref().expect("Resource storage not initialized").load(hash)
fn load_resource(&self, hash: resource::ResourceHash) -> resource::ResourceFuture<'_> {
match self.resources.as_ref() {
Some(resources) => resources.load(hash),
None => {
log::error!("load_resource called before resource storage was initialized");
Box::pin(std::future::ready(None))
}
}
}
}

View File

@@ -23,25 +23,25 @@ impl HashMapResourceStorage {
}
impl LoadResource for HashMapResourceStorage {
fn load(&self, hash: ResourceHash) -> ResourceFuture {
fn load(&self, hash: ResourceHash) -> ResourceFuture<'_> {
let result = self.resources.lock().unwrap().get(&hash).cloned();
Box::pin(async move { result })
}
}
impl ResourceStorage for HashMapResourceStorage {
fn store(&mut self, data: &[u8]) -> ResourceHash {
fn store(&self, data: &[u8]) -> ResourceHash {
let hash = ResourceHash::from(data);
self.resources.get_mut().unwrap().insert(hash, Resource::new(Arc::<[u8]>::from(data)));
self.resources.lock().unwrap().insert(hash, Resource::new(Arc::<[u8]>::from(data)));
hash
}
fn contains(&mut self, hash: &ResourceHash) -> bool {
self.resources.get_mut().unwrap().contains_key(hash)
fn contains(&self, hash: &ResourceHash) -> bool {
self.resources.lock().unwrap().contains_key(hash)
}
fn garbage_collect(&mut self, used: &[ResourceHash]) {
fn garbage_collect(&self, used: &[ResourceHash]) {
let used_set: std::collections::HashSet<&ResourceHash> = used.iter().collect();
self.resources.get_mut().unwrap().retain(|hash, _| used_set.contains(hash));
self.resources.lock().unwrap().retain(|hash, _| used_set.contains(hash));
}
}

View File

@@ -61,14 +61,14 @@ impl MmapResourceStorage {
}
impl LoadResource for MmapResourceStorage {
fn load(&self, hash: ResourceHash) -> ResourceFuture {
fn load(&self, hash: ResourceHash) -> ResourceFuture<'_> {
let result = self.lookup(&hash);
Box::pin(async move { result })
}
}
impl ResourceStorage for MmapResourceStorage {
fn store(&mut self, data: &[u8]) -> ResourceHash {
fn store(&self, data: &[u8]) -> ResourceHash {
let hash = ResourceHash::from(data);
let path = self.path_for(&hash);
@@ -109,13 +109,13 @@ impl ResourceStorage for MmapResourceStorage {
hash
}
fn contains(&mut self, hash: &ResourceHash) -> bool {
self.cache.get_mut().unwrap_or_else(|poisoned| poisoned.into_inner()).contains_key(hash) || self.path_for(hash).exists()
fn contains(&self, hash: &ResourceHash) -> bool {
self.cache.read().unwrap_or_else(|poisoned| poisoned.into_inner()).contains_key(hash) || self.path_for(hash).exists()
}
fn garbage_collect(&mut self, used: &[ResourceHash]) {
fn garbage_collect(&self, used: &[ResourceHash]) {
let used_set: std::collections::HashSet<ResourceHash> = used.iter().cloned().collect();
self.cache.get_mut().unwrap_or_else(|poisoned| poisoned.into_inner()).retain(|hash, _| used_set.contains(hash));
self.cache.write().unwrap_or_else(|poisoned| poisoned.into_inner()).retain(|hash, _| used_set.contains(hash));
let Ok(top_entries) = fs::read_dir(&self.root) else { return };
for top_entry in top_entries.flatten() {

View File

@@ -50,7 +50,7 @@ impl OpfsResourceStorage {
}
impl LoadResource for OpfsResourceStorage {
fn load(&self, hash: ResourceHash) -> ResourceFuture {
fn load(&self, hash: ResourceHash) -> ResourceFuture<'_> {
let inner = self.inner.clone();
{
@@ -74,7 +74,7 @@ impl LoadResource for OpfsResourceStorage {
}
impl ResourceStorage for OpfsResourceStorage {
fn store(&mut self, data: &[u8]) -> ResourceHash {
fn store(&self, data: &[u8]) -> ResourceHash {
let hash = ResourceHash::from(data);
let mut guard = self.inner.lock().unwrap();
@@ -95,12 +95,12 @@ impl ResourceStorage for OpfsResourceStorage {
hash
}
fn contains(&mut self, hash: &ResourceHash) -> bool {
fn contains(&self, hash: &ResourceHash) -> bool {
let guard = self.inner.lock().unwrap();
guard.cache.contains_key(hash) || guard.on_disk.contains(hash)
}
fn garbage_collect(&mut self, used: &[ResourceHash]) {
fn garbage_collect(&self, used: &[ResourceHash]) {
let used: HashSet<ResourceHash> = used.iter().copied().collect();
let mut guard = self.inner.lock().unwrap();

View File

@@ -47,7 +47,7 @@ pub trait ApplicationIo {
fn gpu_executor(&self) -> Option<&Self::Executor> {
None
}
fn load_resource(&self, hash: resource::ResourceHash) -> resource::ResourceFuture;
fn load_resource(&self, hash: resource::ResourceHash) -> resource::ResourceFuture<'_>;
}
impl<T: ApplicationIo> ApplicationIo for &T {
@@ -57,7 +57,7 @@ impl<T: ApplicationIo> ApplicationIo for &T {
(**self).gpu_executor()
}
fn load_resource(&self, hash: resource::ResourceHash) -> resource::ResourceFuture {
fn load_resource(&self, hash: resource::ResourceHash) -> resource::ResourceFuture<'_> {
(**self).load_resource(hash)
}
}

View File

@@ -216,15 +216,15 @@ impl CacheHash for ResourceHash {
}
pub trait LoadResource: Send + Sync {
fn load(&self, hash: ResourceHash) -> ResourceFuture;
fn load(&self, hash: ResourceHash) -> ResourceFuture<'_>;
}
pub type ResourceFuture = Pin<Box<dyn Future<Output = Option<Resource>> + Send + 'static>>;
pub type ResourceFuture<'a> = Pin<Box<dyn Future<Output = Option<Resource>> + Send + 'a>>;
pub trait ResourceStorage: LoadResource {
fn store(&mut self, data: &[u8]) -> ResourceHash;
fn contains(&mut self, hash: &ResourceHash) -> bool;
fn garbage_collect(&mut self, used: &[ResourceHash]);
fn store(&self, data: &[u8]) -> ResourceHash;
fn contains(&self, hash: &ResourceHash) -> bool;
fn garbage_collect(&self, used: &[ResourceHash]);
}
#[repr(transparent)]