Browse Source

JSComponent improvements

Josh Engebretson 10 years ago
parent
commit
4e3997a015

+ 5 - 26
Source/AtomicJS/Javascript/JSComponent.cpp

@@ -61,7 +61,7 @@ public:
     SharedPtr<Object> CreateObject()
     SharedPtr<Object> CreateObject()
     {
     {
         SharedPtr<Object> ptr;
         SharedPtr<Object> ptr;
-        bool scriptClass = false;
+
         Variant& v = context_->GetVar("__JSComponent_ComponentFile");
         Variant& v = context_->GetVar("__JSComponent_ComponentFile");
 
 
         // __JSComponent_ComponentFile will only be set when coming from XML
         // __JSComponent_ComponentFile will only be set when coming from XML
@@ -81,26 +81,9 @@ public:
 
 
                 JSComponentFile* componentFile = cache->GetResource<JSComponentFile>(split[1]);
                 JSComponentFile* componentFile = cache->GetResource<JSComponentFile>(split[1]);
 
 
-                if (componentFile && componentFile->GetScriptClass())
+                if (componentFile)
                 {
                 {
-                    scriptClass = true;
-                    JSVM* vm = JSVM::GetJSVM(NULL);
-                    duk_context* ctx = vm->GetJSContext();
-
-                    componentFile->PushModule();
-
-                    duk_new(ctx, 0);
-                    if (duk_is_object(ctx, -1))
-                    {
-                        JSComponent* component = js_to_class_instance<JSComponent>(ctx, -1, 0);
-                        component->scriptClassInstance_ = true;
-                        // store reference below so pop doesn't gc the component
-                        component->UpdateReferences();
-                        ptr = component;
-
-                    }
-
-                    duk_pop(ctx);
+                    ptr = componentFile->CreateJSComponent();
                 }
                 }
 
 
             }
             }
@@ -110,11 +93,6 @@ public:
         if (ptr.Null())
         if (ptr.Null())
         {
         {
             ptr = new JSComponent(context_);
             ptr = new JSComponent(context_);
-
-            if (scriptClass)
-            {
-                LOGERRORF("Failed to create script class from component file");
-            }
         }
         }
 
 
         return ptr;
         return ptr;
@@ -204,7 +182,8 @@ void JSComponent::UpdateReferences(bool remove)
 
 
 void JSComponent::ApplyAttributes()
 void JSComponent::ApplyAttributes()
 {
 {
-    InitInstance();
+    if (!started_)
+        InitInstance();
 }
 }
 
 
 void JSComponent::InitInstance(bool hasArgs, int argIdx)
 void JSComponent::InitInstance(bool hasArgs, int argIdx)

+ 1 - 0
Source/AtomicJS/Javascript/JSComponent.h

@@ -39,6 +39,7 @@ class JSVM;
 class ATOMIC_API JSComponent : public Component
 class ATOMIC_API JSComponent : public Component
 {
 {
     friend class JSComponentFactory;
     friend class JSComponentFactory;
+    friend class JSComponentFile;
 
 
     enum EventFlags
     enum EventFlags
     {
     {

+ 43 - 0
Source/AtomicJS/Javascript/JSComponentFile.cpp

@@ -28,6 +28,7 @@
 #include <Atomic/IO/Serializer.h>
 #include <Atomic/IO/Serializer.h>
 
 
 #include "JSComponentFile.h"
 #include "JSComponentFile.h"
+#include "JSComponent.h"
 #include "JSVM.h"
 #include "JSVM.h"
 
 
 namespace Atomic
 namespace Atomic
@@ -115,6 +116,48 @@ bool JSComponentFile::PushModule()
 
 
 }
 }
 
 
+JSComponent* JSComponentFile::CreateJSComponent()
+{
+    JSComponent* component = NULL;
+
+    if (!scriptClass_)
+    {
+        component =  new JSComponent(context_);
+    }
+    else
+    {
+
+        JSVM* vm = JSVM::GetJSVM(NULL);
+        duk_context* ctx = vm->GetJSContext();
+
+        PushModule();
+
+        duk_new(ctx, 0);
+
+        if (duk_is_object(ctx, -1))
+        {
+            component = js_to_class_instance<JSComponent>(ctx, -1, 0);
+            component->scriptClassInstance_ = true;
+            // store reference below so pop doesn't gc the component
+            component->UpdateReferences();
+        }
+
+        duk_pop(ctx);
+
+    }
+
+    if (!component)
+    {
+        LOGERRORF("Failed to create script class from component file %s", GetName().CString());
+        component =  new JSComponent(context_);
+    }
+
+    component->SetComponentFile(this);
+
+    return component;
+
+}
+
 bool JSComponentFile::InitModule()
 bool JSComponentFile::InitModule()
 {
 {
     if (context_->GetEditorContext())
     if (context_->GetEditorContext())

+ 3 - 0
Source/AtomicJS/Javascript/JSComponentFile.h

@@ -28,6 +28,8 @@
 namespace Atomic
 namespace Atomic
 {
 {
 
 
+class JSComponent;
+
 /// Script document resource.
 /// Script document resource.
 class ATOMIC_API JSComponentFile : public Resource
 class ATOMIC_API JSComponentFile : public Resource
 {
 {
@@ -50,6 +52,7 @@ public:
 
 
     bool GetScriptClass() { return scriptClass_; }
     bool GetScriptClass() { return scriptClass_; }
 
 
+    JSComponent* CreateJSComponent();
     bool PushModule();
     bool PushModule();
     void GetDefaultFieldValue(const String& name, Variant& v);
     void GetDefaultFieldValue(const String& name, Variant& v);
 
 

+ 12 - 3
Source/AtomicJS/Javascript/JSScene.cpp

@@ -30,12 +30,21 @@ static int Node_CreateJSComponent(duk_context* ctx)
 
 
     duk_push_this(ctx);
     duk_push_this(ctx);
     Node* node = js_to_class_instance<Node>(ctx, -1, 0);
     Node* node = js_to_class_instance<Node>(ctx, -1, 0);
-    JSComponent* jsc = node->CreateComponent<JSComponent>();
 
 
-    ResourceCache* cache = node->GetContext()->GetSubsystem<ResourceCache>();
+    ResourceCache* cache = node->GetContext()->GetSubsystem<ResourceCache>();    
     JSComponentFile* file = cache->GetResource<JSComponentFile>(path);
     JSComponentFile* file = cache->GetResource<JSComponentFile>(path);
 
 
-    jsc->SetComponentFile(file);
+    if (!file)
+    {
+        LOGERRORF("Unable to load component file %s", path.CString());
+        duk_push_undefined(ctx);
+        return 1;
+    }
+
+    JSComponent* jsc = file->CreateJSComponent();
+
+    node->AddComponent(jsc, jsc->GetID(), LOCAL);
+
     jsc->InitInstance(hasArgs, argIdx);
     jsc->InitInstance(hasArgs, argIdx);
 
 
     js_push_class_object_instance(ctx, jsc, "JSComponent");
     js_push_class_object_instance(ctx, jsc, "JSComponent");