Browse Source

Recursive node and scene cleanup

Josh Engebretson 10 years ago
parent
commit
93c19e5817
1 changed files with 60 additions and 34 deletions
  1. 60 34
      Source/AtomicJS/Javascript/JSAtomic.cpp

+ 60 - 34
Source/AtomicJS/Javascript/JSAtomic.cpp

@@ -142,58 +142,84 @@ static int js_atomic_script(duk_context* ctx)
     return 1;
     return 1;
 }
 }
 
 
-
-static int js_atomic_destroy(duk_context* ctx)
+static void js_atomic_destroy_node(Node* node, duk_context* ctx, bool root = false)
 {
 {
-    if (!duk_is_object(ctx, 0))
-        return 0;
 
 
-    Object* obj = js_to_class_instance<Object>(ctx, 0, 0);
+    if (root)
+    {
+        PODVector<Node*> children;
+        node->GetChildren(children, true);
 
 
-    if (!obj)
-        return 0;
+        for (unsigned i = 0; i < children.Size(); i++)
+        {
+            if (children.At(i)->JSGetHeapPtr())
+                js_atomic_destroy_node(children.At(i), ctx);
+        }
+    }
 
 
-    if (obj->GetType() == Node::GetTypeStatic())
+    const Vector<SharedPtr<Component> >& components = node->GetComponents();
+
+    for (unsigned i = 0; i < components.Size(); i++)
     {
     {
+         Component* component = components[i];
 
 
-        Node* node = (Node*) obj;
+         if (component->GetType() == JSComponent::GetTypeStatic())
+         {
+             JSComponent* jscomponent = (JSComponent*) component;
+             jscomponent->SetDestroyed();
+         }
 
 
-        const Vector<SharedPtr<Component> >& components = node->GetComponents();
+         component->UnsubscribeFromAllEvents();
+    }
 
 
-        for (unsigned i = 0; i < components.Size(); i++)
-        {
-             Component* component = components[i];
+    node->RemoveAllComponents();
+    node->UnsubscribeFromAllEvents();
 
 
-             if (component->GetType() == JSComponent::GetTypeStatic())
-             {
-                 JSComponent* jscomponent = (JSComponent*) component;
-                 jscomponent->SetDestroyed();
-             }
+    if (node->GetParent())
+    {
+        assert(node->Refs() >= 2);
+        node->Remove();
+    }
 
 
-             component->UnsubscribeFromAllEvents();
-        }
+    int top = duk_get_top(ctx);
+    duk_push_global_stash(ctx);
+    duk_get_prop_index(ctx, -1, JS_GLOBALSTASH_INDEX_NODE_REGISTRY);
+    duk_push_pointer(ctx, (void*) node);
+    duk_del_prop(ctx, -2);
+    duk_pop_2(ctx);
+    assert(top = duk_get_top(ctx));
+}
 
 
-        node->RemoveAllComponents();
-        node->UnsubscribeFromAllEvents();
+static void js_atomic_destroy_scene(Scene* scene, duk_context* ctx)
+{
+    js_atomic_destroy_node(scene, ctx, true);
+}
 
 
-        if (node->GetParent())
-        {
-            assert(node->Refs() >= 2);
-            node->Remove();
-        }
+static int js_atomic_destroy(duk_context* ctx)
+{
+    if (!duk_is_object(ctx, 0))
+        return 0;
 
 
-        int top = duk_get_top(ctx);
-        duk_push_global_stash(ctx);
-        duk_get_prop_index(ctx, -1, JS_GLOBALSTASH_INDEX_NODE_REGISTRY);
-        duk_push_pointer(ctx, (void*) node);
-        duk_del_prop(ctx, -2);
-        duk_pop_2(ctx);
-        assert(top = duk_get_top(ctx));
+    Object* obj = js_to_class_instance<Object>(ctx, 0, 0);
 
 
+    if (!obj)
+        return 0;
+
+    if (obj->GetType() == Node::GetTypeStatic())
+    {
+        Node* node = (Node*) obj;
+        js_atomic_destroy_node(node, ctx, true);
+        return 0;
+    }
+    if (obj->GetType() == Scene::GetTypeStatic())
+    {
+        Scene* scene = (Scene*) obj;
+        js_atomic_destroy_scene(scene, ctx);
         return 0;
         return 0;
     }
     }
     else if (obj->GetType() == JSComponent::GetTypeStatic())
     else if (obj->GetType() == JSComponent::GetTypeStatic())
     {
     {
+        // FIXME: want to be able to destroy a single component
         assert(0);
         assert(0);
         JSComponent* component = (JSComponent*) obj;
         JSComponent* component = (JSComponent*) obj;
         component->UnsubscribeFromAllEvents();
         component->UnsubscribeFromAllEvents();