Last active
November 8, 2023 16:42
-
-
Save zicklag/de14ce29d7c6977999286efe949f77ef to your computer and use it in GitHub Desktop.
Piccolo Singleton Manager
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pub struct LuaSingletons { | |
singletons: Rc<AtomicCell<HashMap<usize, Box<dyn Any>>>>, | |
} | |
impl Default for LuaSingletons { | |
fn default() -> Self { | |
Self { | |
singletons: Rc::new(AtomicCell::new(HashMap::default())), | |
} | |
} | |
} | |
impl LuaSingletons { | |
/// Fetch a lua singleton, initializing it if it has not yet been created. | |
/// | |
/// The singleton is defined by a function pointer that returns a stashable value. | |
fn get< | |
'gc, | |
S: Fetchable<'gc, Fetched = T> + 'static, | |
T: Stashable<'gc, Stashed = S> + Clone + Copy + 'gc, | |
>( | |
&self, | |
ctx: Context<'gc>, | |
singleton: fn(Context<'gc>) -> T, | |
) -> T { | |
let map = self.singletons.borrow_mut(); | |
let id = singleton as usize; | |
if let Some(entry) = map.get(&id) { | |
let stashed = entry.downcast_ref::<S>().expect( | |
"Encountered two functions with different return types and \ | |
the same function pointer.", | |
); | |
ctx.state.registry.fetch(stashed) | |
} else { | |
drop(map); // Make sure we don't deadlock | |
let v = singleton(ctx); | |
let stashed = ctx.state.registry.stash(&ctx, v); | |
self.singletons.borrow_mut().insert(id, Box::new(stashed)); | |
v | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment