gpui_hooks/hooks/
use_ref.rs1use super::Hook;
2use std::any::Any;
3use std::cell::RefCell;
4use std::rc::Rc;
5
6pub struct UseRef<T: 'static> {
8 current: Rc<RefCell<T>>,
9}
10
11impl<T: 'static> UseRef<T> {
12 pub fn new(initial: T) -> Self {
13 Self {
14 current: Rc::new(RefCell::new(initial)),
15 }
16 }
17
18 pub fn get_ref(&self) -> Rc<RefCell<T>> {
20 self.current.clone()
21 }
22}
23
24impl<T: 'static> Hook for UseRef<T> {
25 fn as_any(&self) -> &dyn Any {
26 self
27 }
28 fn as_any_mut(&mut self) -> &mut dyn Any {
29 self
30 }
31}
32
33pub trait UseRefHook {
38 fn _hooks_ref(&self) -> &RefCell<Vec<Box<dyn Hook>>>;
40
41 fn _next_hook_index(&self) -> usize;
43
44 fn use_ref<T, F>(&self, initial: F) -> Rc<RefCell<T>>
47 where
48 T: 'static,
49 F: FnOnce() -> T,
50 {
51 let idx = self._next_hook_index();
52 let hooks_ref = self._hooks_ref();
53
54 let hooks_len = hooks_ref.borrow().len();
56 if idx >= hooks_len {
57 let hook = UseRef::new(initial());
58 hooks_ref.borrow_mut().push(Box::new(hook));
59 }
60
61 let hook_ptr: *const dyn Hook = {
63 let hooks = hooks_ref.borrow();
64 let hook = hooks.get(idx).expect("Hook index out of bounds");
65 hook.as_ref() as *const dyn Hook
66 };
67
68 unsafe {
70 let ref_hook = &*(hook_ptr as *const UseRef<T>);
71 ref_hook.get_ref()
72 }
73 }
74}