diff options
| author | 魏曹先生 <1992414357@qq.com> | 2026-05-16 15:43:34 +0800 |
|---|---|---|
| committer | 魏曹先生 <1992414357@qq.com> | 2026-05-16 15:43:34 +0800 |
| commit | f7964129a5b5e41fd6da0f191a7e37e93bd36814 (patch) | |
| tree | cab11413bbb109239e01bc4384a8dfa85757a348 /mingling_core/src | |
| parent | ae78d9211c879516779dde9dd470d998ba3644a8 (diff) | |
Add mutable resource injection to `#[chain]` macro
Diffstat (limited to 'mingling_core/src')
| -rw-r--r-- | mingling_core/src/asset/global_resource.rs | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/mingling_core/src/asset/global_resource.rs b/mingling_core/src/asset/global_resource.rs index 8e2ce9f..104367a 100644 --- a/mingling_core/src/asset/global_resource.rs +++ b/mingling_core/src/asset/global_resource.rs @@ -43,6 +43,40 @@ where } } + /// Internal syntax for the `&mut MyResource` syntax of #[chain], do not use directly + #[doc(hidden)] + pub fn __modify_res_and_return_any<Res, Return>( + &self, + f: impl FnOnce(&mut Res) -> Return, + ) -> impl Into<ChainProcess<C>> + where + Res: 'static + Default + ResourceMarker + Send + Sync, + Return: Into<ChainProcess<C>>, + { + let mut guard = match self.resources.lock() { + Ok(guard) => guard, + Err(_) => { + let mut default_res = Res::res_default(); + return f(&mut default_res); + } + }; + if let Some(arc_res) = guard + .get_mut(&TypeId::of::<Res>()) + .and_then(|a| a.downcast_mut::<Arc<Res>>()) + { + let mut new_res = match Arc::try_unwrap(std::mem::take(arc_res)) { + Ok(val) => val, + Err(arc) => (*arc).res_clone(), + }; + let r = f(&mut new_res); + *arc_res = Arc::new(new_res); + r + } else { + let mut default_res = Res::res_default(); + f(&mut default_res) + } + } + /// Get an resources by type, returning `Res` if present pub fn res<Res: 'static + Send + Sync>(&self) -> Option<GlobalResource<Res>> { let guard = self.resources.lock().ok()?; |
