aboutsummaryrefslogtreecommitdiff
path: root/mingling_core
diff options
context:
space:
mode:
author魏曹先生 <1992414357@qq.com>2026-05-16 15:43:34 +0800
committer魏曹先生 <1992414357@qq.com>2026-05-16 15:43:34 +0800
commitf7964129a5b5e41fd6da0f191a7e37e93bd36814 (patch)
treecab11413bbb109239e01bc4384a8dfa85757a348 /mingling_core
parentae78d9211c879516779dde9dd470d998ba3644a8 (diff)
Add mutable resource injection to `#[chain]` macro
Diffstat (limited to 'mingling_core')
-rw-r--r--mingling_core/src/asset/global_resource.rs34
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()?;