@@ -2,10 +2,16 @@ use dioxus_lib::prelude::*;
22use futures_util:: Future ;
33use std:: {
44 any:: TypeId ,
5+ cell:: RefCell ,
56 collections:: HashSet ,
67 hash:: Hash ,
8+ rc:: Rc ,
79 sync:: { Arc , RwLock , RwLockReadGuard } ,
810} ;
11+ mod warnings {
12+ pub use warnings:: Warning ;
13+ }
14+ pub use warnings:: Warning ;
915
1016use crate :: {
1117 cached_result:: CachedResult ,
@@ -62,25 +68,27 @@ where
6268
6369impl < T , E , K : Eq + Hash > Drop for UseQueryCleaner < T , E , K > {
6470 fn drop ( & mut self ) {
65- let mut queries_registry = match self . client . queries_registry . try_write_unchecked ( ) {
66- Err ( dioxus_lib:: prelude:: BorrowMutError :: Dropped ( _) ) => {
67- // It's safe to skip this error as the RadioStation's signals could have been dropped before the caller of this function.
68- // For instance: If you closed the app, the RadioStation would be dropped along all it's signals, causing the inner components
69- // to still have dropped signals and thus causing this error if they were to call the signals on a custom destructor.
70- return ;
71+ dioxus_lib:: prelude:: warnings:: signal_write_in_component_body:: allow ( || {
72+ let mut queries_registry = match self . client . queries_registry . try_write_unchecked ( ) {
73+ Err ( dioxus_lib:: prelude:: BorrowMutError :: Dropped ( _) ) => {
74+ // It's safe to skip this error as the RadioStation's signals could have been dropped before the caller of this function.
75+ // For instance: If you closed the app, the RadioStation would be dropped along all it's signals, causing the inner components
76+ // to still have dropped signals and thus causing this error if they were to call the signals on a custom destructor.
77+ return ;
78+ }
79+ Err ( e) => panic ! ( "Unexpected error: {e}" ) ,
80+ Ok ( v) => v,
81+ } ;
82+
83+ let query_listeners = queries_registry. get_mut ( & self . registry_entry ) . unwrap ( ) ;
84+ // Remove this listener
85+ query_listeners. listeners . remove ( & self . scope_id ) ;
86+
87+ // Clear the queries registry of this listener if it was the last one
88+ if query_listeners. listeners . is_empty ( ) {
89+ queries_registry. remove ( & self . registry_entry ) ;
7190 }
72- Err ( e) => panic ! ( "Unexpected error: {e}" ) ,
73- Ok ( v) => v,
74- } ;
75-
76- let query_listeners = queries_registry. get_mut ( & self . registry_entry ) . unwrap ( ) ;
77- // Remove this listener
78- query_listeners. listeners . remove ( & self . scope_id ) ;
79-
80- // Clear the queries registry of this listener if it was the last one
81- if query_listeners. listeners . is_empty ( ) {
82- queries_registry. remove ( & self . registry_entry ) ;
83- }
91+ } ) ;
8492 }
8593}
8694
@@ -135,45 +143,48 @@ where
135143 query. registry_entry . query_keys = query_keys. to_vec ( ) ;
136144
137145 let registry_entry = query. registry_entry ;
138- let mut queries_registry = client. queries_registry . write_unchecked ( ) ;
139-
140- // Create a group of listeners for the given [RegistryEntry] key.
141- let query_listeners =
142- queries_registry
143- . entry ( registry_entry. clone ( ) )
144- . or_insert ( QueryListeners {
145- listeners : HashSet :: default ( ) ,
146- value : QueryValue :: new ( RwLock :: new ( CachedResult :: new (
147- query. initial_value . unwrap_or_default ( ) ,
148- ) ) ) ,
149- query_fn : query. query_fn ,
150- } ) ;
151-
152- // Register this listener's scope
153- query_listeners
154- . listeners
155- . insert ( current_scope_id ( ) . unwrap ( ) ) ;
156-
157- let value = query_listeners. value . clone ( ) ;
158-
159- // Asynchronously initialize the query value
160- spawn ( {
161- to_owned ! [ registry_entry] ;
162- async move {
163- client. run_new_query ( & registry_entry) . await ;
164- }
165- } ) ;
166146
167- UseQuery {
168- client,
169- value,
170- scope_id : current_scope_id ( ) . unwrap ( ) ,
171- cleaner : Signal :: new ( UseQueryCleaner {
147+ dioxus_lib:: prelude:: warnings:: signal_write_in_component_body:: allow ( || {
148+ let mut queries_registry = client. queries_registry . write_unchecked ( ) ;
149+
150+ // Create a group of listeners for the given [RegistryEntry] key.
151+ let query_listeners =
152+ queries_registry
153+ . entry ( registry_entry. clone ( ) )
154+ . or_insert ( QueryListeners {
155+ listeners : HashSet :: default ( ) ,
156+ value : QueryValue :: new ( RwLock :: new ( CachedResult :: new (
157+ query. initial_value . unwrap_or_default ( ) ,
158+ ) ) ) ,
159+ query_fn : query. query_fn ,
160+ } ) ;
161+
162+ // Register this listener's scope
163+ query_listeners
164+ . listeners
165+ . insert ( current_scope_id ( ) . unwrap ( ) ) ;
166+
167+ let value = query_listeners. value . clone ( ) ;
168+
169+ // Asynchronously initialize the query value
170+ spawn ( {
171+ to_owned ! [ registry_entry] ;
172+ async move {
173+ client. run_new_query ( & registry_entry) . await ;
174+ }
175+ } ) ;
176+
177+ UseQuery {
172178 client,
173- registry_entry ,
179+ value ,
174180 scope_id : current_scope_id ( ) . unwrap ( ) ,
175- } ) ,
176- }
181+ cleaner : Signal :: new ( UseQueryCleaner {
182+ client,
183+ registry_entry,
184+ scope_id : current_scope_id ( ) . unwrap ( ) ,
185+ } ) ,
186+ }
187+ } )
177188 } )
178189}
179190
@@ -190,8 +201,8 @@ fn use_sync_memo<T: 'static + Clone, D: PartialEq + 'static>(
190201 value : T ,
191202 deps : D ,
192203 }
193- let mut value = use_signal :: < Option < Memoized < T , D > > > ( || None ) ;
194- let mut memoized_value = value. write ( ) ;
204+ let value = use_hook :: < Rc < RefCell < Option < Memoized < T , D > > > > > ( || Rc :: default ( ) ) ;
205+ let mut memoized_value = value. borrow_mut ( ) ;
195206
196207 let deps_have_changed = memoized_value
197208 . as_ref ( )
0 commit comments