1use crate::storage::typed_storage::{Storable, TypedStorage};
2use crate::widget::{Context, NotificationHandler};
3use std::cell::{Ref, RefCell, RefMut};
4use std::marker::PhantomData;
5use std::ops::{Deref, DerefMut};
6use std::rc::Rc;
7use typed_slab::TypedSlab;
8use yew::Callback;
9
10pub trait RouterState: PartialEq + Storable + Default + Clone + 'static {
11 fn restored(&mut self);
15
16 fn update(&mut self, new_state: Self) {
18 *self = new_state;
19 }
20
21 fn on_update(&mut self) {}
22}
23
24pub struct DataChanged<T> {
25 _data: PhantomData<T>,
26}
27
28impl<T> DataChanged<T> {
29 fn new() -> Self {
30 Self { _data: PhantomData }
31 }
32}
33
34#[derive(Debug)]
35pub struct SharedObject<T> {
36 inner: Rc<RefCell<SharedObjectInner<T>>>,
37 listener: Option<ListenerId>,
38}
39
40impl<T> Clone for SharedObject<T> {
41 fn clone(&self) -> Self {
42 Self {
43 inner: self.inner.clone(),
44 listener: None,
45 }
46 }
47}
48
49impl<T> Drop for SharedObject<T> {
50 fn drop(&mut self) {
51 self.unsubscribe();
52 }
53}
54
55impl<T> Default for SharedObject<T>
56where
57 T: RouterState + Default,
58{
59 fn default() -> Self {
60 Self::new()
61 }
62}
63
64impl<T> SharedObject<T> {
65 pub fn new() -> Self
66 where
67 T: RouterState + Default,
68 {
69 let storage = TypedStorage::new();
70 let mut data: T = storage.restore().unwrap_or_default();
71 data.restored();
72 let inner = SharedObjectInner {
73 callbacks: TypedSlab::new(),
74 data,
75 };
76 Self {
77 inner: Rc::new(RefCell::new(inner)),
78 listener: None,
79 }
80 }
81
82 pub fn subscribe<W>(&mut self, context: &mut Context<W>)
83 where
84 W: NotificationHandler<DataChanged<T>>,
85 T: 'static,
86 {
87 self.unsubscribe();
88 let callback = context.notification();
89 let mut writer = self.inner.borrow_mut();
90 let id = writer.callbacks.insert(callback);
91 self.listener = Some(id);
92 }
93
94 pub fn unsubscribe(&mut self) {
95 if let Some(id) = self.listener.take() {
96 let mut writer = self.inner.borrow_mut();
97 writer.callbacks.remove(id);
98 }
99 }
100
101 pub fn read(&self) -> SharedObjectReader<'_, T> {
102 let reader = self.inner.borrow();
103 SharedObjectReader { reader }
104 }
105
106 pub fn write(&self) -> SharedObjectWriter<'_, T>
107 where
108 T: RouterState,
109 {
110 let writer = self.inner.borrow_mut();
111 SharedObjectWriter { writer }
112 }
113}
114
115pub struct SharedObjectReader<'a, T> {
116 reader: Ref<'a, SharedObjectInner<T>>,
117}
118
119impl<'a, T> Deref for SharedObjectReader<'a, T> {
120 type Target = T;
121
122 fn deref(&self) -> &Self::Target {
123 &self.reader.data
124 }
125}
126
127pub struct SharedObjectWriter<'a, T: RouterState> {
128 writer: RefMut<'a, SharedObjectInner<T>>,
129}
130
131impl<'a, T> Deref for SharedObjectWriter<'a, T>
132where
133 T: RouterState,
134{
135 type Target = T;
136
137 fn deref(&self) -> &Self::Target {
138 &self.writer.data
139 }
140}
141
142impl<'a, T> DerefMut for SharedObjectWriter<'a, T>
143where
144 T: RouterState,
145{
146 fn deref_mut(&mut self) -> &mut Self::Target {
147 &mut self.writer.data
148 }
149}
150
151impl<'a, T> Drop for SharedObjectWriter<'a, T>
152where
153 T: RouterState,
154{
155 fn drop(&mut self) {
156 self.writer.data.on_update();
157 let mut storage = TypedStorage::new();
159 storage.store(&self.writer.data);
160 for (_, callback) in self.writer.callbacks.iter() {
161 callback.emit(DataChanged::new());
162 }
163 }
164}
165
166type ListenerId = usize;
167
168#[derive(Debug)]
169struct SharedObjectInner<T> {
170 callbacks: TypedSlab<ListenerId, Callback<DataChanged<T>>>,
171 data: T,
172}