Jelajahi Sumber

run hook destructors inside of the scope they were created in

Evan Almloff 1 tahun lalu
induk
melakukan
cdf25f0c14

+ 21 - 4
packages/core/src/runtime.rs

@@ -62,10 +62,27 @@ impl Runtime {
         contexts[id.0] = Some(context);
     }
 
-    pub(crate) fn remove_context(&self, id: ScopeId) {
-        if let Some(_scope) = self.scope_contexts.borrow_mut()[id.0].take() {
-            // todo: some cleanup work
+    pub(crate) fn remove_context(self: &Rc<Self>, id: ScopeId) {
+        {
+            let borrow = self.scope_contexts.borrow();
+            if let Some(scope) = &borrow[id.0] {
+                let _runtime_guard = RuntimeGuard::new(self.clone());
+                // Manually drop tasks, hooks, and contexts inside of the runtime
+                self.on_scope(id, || {
+                    // Drop all spawned tasks
+                    for id in scope.spawned_tasks.take() {
+                        self.remove_task(id);
+                    }
+
+                    // Drop all hooks
+                    scope.hooks.take();
+
+                    // Drop all contexts
+                    scope.shared_contexts.take();
+                });
+            }
         }
+        self.scope_contexts.borrow_mut()[id.0].take();
     }
 
     /// Get the current scope id
@@ -75,7 +92,7 @@ impl Runtime {
 
     /// Call this function with the current scope set to the given scope
     ///
-    /// Useful in a limited number of scenarios, not public.
+    /// Useful in a limited number of scenarios
     pub fn on_scope<O>(&self, id: ScopeId, f: impl FnOnce() -> O) -> O {
         self.scope_stack.borrow_mut().push(id);
         let o = f();

+ 0 - 11
packages/core/src/scope_context.rs

@@ -300,17 +300,6 @@ impl ScopeContext {
     }
 }
 
-impl Drop for ScopeContext {
-    fn drop(&mut self) {
-        // Drop all spawned tasks
-        _ = Runtime::with(|rt| {
-            for id in self.spawned_tasks.borrow().iter() {
-                rt.remove_task(*id);
-            }
-        })
-    }
-}
-
 impl ScopeId {
     /// Get the current scope id
     pub fn current_scope_id(self) -> Option<ScopeId> {

+ 1 - 0
packages/core/tests/miri_simple.rs

@@ -41,6 +41,7 @@ fn contexts_drop() {
         }
     }
 
+    #[allow(non_snake_case)]
     fn ChildComp() -> Element {
         let el = consume_context::<String>();