Browse Source

Support for bound packages

Josh Engebretson 10 years ago
parent
commit
a594826f8e

+ 2 - 2
Data/AtomicEditor/Resources/EditorData/AtomicEditor/javascript/main.js

@@ -1,11 +1,11 @@
 
 var ui = require("./ui/ui");
 
-var env = Atomic.getToolEnvironment();
+var env = ToolCore.getToolEnvironment();
 
 print(env.rootSourceDir);
 
-var system = Atomic.getToolSystem();
+var system = ToolCore.getToolSystem();
 
 system.loadProject("/Users/josh/Dev/atomic/AtomicExamples/NewSpaceGame");
 

+ 1 - 1
Data/AtomicEditor/Resources/EditorData/AtomicEditor/javascript/ui/mainframe.js

@@ -45,7 +45,7 @@ mainframe.handleMenuAtomicEditor = function(data) {
 
     if (data.refid == "edit play") {
 
-      new Atomic.PlayCmd().run();
+      new ToolCore.PlayCmd().run();
 
       return true;
 

+ 1 - 0
Source/Atomic/Core/Object.h

@@ -107,6 +107,7 @@ public:
     const String& GetCategory() const;
 
     virtual bool IsObject() const { return true; }
+    static const Atomic::String& GetTypeNameStatic() { static const Atomic::String typeNameStatic("Object"); return typeNameStatic; }
     
 protected:
     /// Execution context.

+ 0 - 4
Source/AtomicJS/CMakeLists.txt

@@ -1,8 +1,4 @@
 
-if (NOT IOS AND NOT ANDROID AND NOT EMSCRIPTEN)
-    add_subdirectory(JSBind)
-endif()
-
 include_directories(${CMAKE_CURRENT_SOURCE_DIR}
                     ${CMAKE_SOURCE_DIR}/Source/ThirdParty
                     ${CMAKE_SOURCE_DIR}/Source/ThirdParty/rapidjson/include

+ 45 - 17
Source/AtomicJS/Javascript/JSAPI.cpp

@@ -26,19 +26,19 @@
 namespace Atomic
 {
 
-void js_class_get_prototype(duk_context* ctx, const char* classname)
+void js_class_get_prototype(duk_context* ctx, const char* package, const char *classname)
 {
-    duk_get_global_string(ctx, "Atomic");
+    duk_get_global_string(ctx, package);
     duk_get_prop_string(ctx, -1, classname);
     duk_get_prop_string(ctx, -1, "prototype");
     duk_remove(ctx, -2); // remove class object
     duk_remove(ctx, -2); // remove Atomic object
 }
 
-void js_constructor_basecall(duk_context* ctx, const char* baseclass)
+void js_constructor_basecall(duk_context* ctx, const char* package, const char* baseclass)
 {
     int top = duk_get_top(ctx);
-    duk_get_global_string(ctx, "Atomic");
+    duk_get_global_string(ctx, package);
     duk_get_prop_string(ctx, -1, baseclass);
     assert(duk_is_function(ctx, -1));
     duk_push_this(ctx);
@@ -47,31 +47,46 @@ void js_constructor_basecall(duk_context* ctx, const char* baseclass)
     assert (top == duk_get_top(ctx));
 }
 
-void js_class_declare(JSVM* vm, const char* classname, duk_c_function constructor)
+void js_class_declare_internal(JSVM* vm, void* uniqueClassID, const char* package, const char* classname, duk_c_function constructor)
 {
     duk_context* ctx = vm->GetJSContext();
-    duk_get_global_string(ctx, "Atomic");
+
+    // stash a lookup from the uniqueID to the package name
+    // (NULL) == non-object, so core "Atomic" package
+
+    if (uniqueClassID)
+    {
+        duk_push_heap_stash(ctx);
+        duk_push_pointer(ctx, uniqueClassID);
+        duk_push_string(ctx, package);
+        duk_put_prop(ctx, -3);
+        duk_pop(ctx);
+    }
+    else
+    {
+        assert(String("Atomic") == package );
+    }
+
+    duk_get_global_string(ctx, package);
     duk_push_c_function(ctx, constructor, DUK_VARARGS);
     duk_put_prop_string(ctx, -2, classname);
     duk_pop(ctx);
 }
 
-void js_class_push_propertyobject(JSVM* vm, const char* classname)
+void js_class_push_propertyobject(JSVM* vm, const char* package, const char* classname)
 {
     duk_context* ctx = vm->GetJSContext();
     String pname;
     pname.AppendWithFormat("__%s__Properties", classname);
 
-    duk_get_global_string(ctx, "Atomic");
+    duk_get_global_string(ctx, package);
     duk_push_object(ctx);
     duk_dup(ctx, -1);
     duk_put_prop_string(ctx, -3, pname.CString());
     duk_remove(ctx, -2); // remove Atomic object
 }
 
-
-
-void js_setup_prototype(JSVM* vm, const char* classname, const char* basename, bool hasProperties)
+void js_setup_prototype(JSVM* vm, const char* package, const char* classname, const char* basePackage, const char* basename, bool hasProperties)
 {
     duk_context* ctx = vm->GetJSContext();
 
@@ -80,7 +95,7 @@ void js_setup_prototype(JSVM* vm, const char* classname, const char* basename, b
 
     int top = duk_get_top(ctx);
 
-    duk_get_global_string(ctx, "Atomic");
+    duk_get_global_string(ctx,package);
     duk_get_prop_string(ctx, -1, classname);
     assert(duk_is_c_function(ctx, -1));
 
@@ -108,7 +123,7 @@ void js_setup_prototype(JSVM* vm, const char* classname, const char* basename, b
 
     duk_remove(ctx, -2); // remove Object
 
-    duk_get_global_string(ctx, "Atomic");
+    duk_get_global_string(ctx, basePackage);
     duk_get_prop_string(ctx, -1, basename);
     assert(duk_is_function(ctx, -1));
     duk_get_prop_string(ctx, -1, "prototype");
@@ -120,13 +135,15 @@ void js_setup_prototype(JSVM* vm, const char* classname, const char* basename, b
     int numargs = 1;
     if (hasProperties)
     {
-        duk_get_prop_string(ctx, -2, pname.CString());
+        duk_get_global_string(ctx, package);
+        duk_get_prop_string(ctx, -1, pname.CString());
         assert(duk_is_object(ctx, -1));
-        duk_remove(ctx, -3); // remove Atomic
+        duk_remove(ctx, -2);
+        duk_remove(ctx, -3); // remove package
         numargs++;
     }
     else
-        duk_remove(ctx, -2); // remove Atomic
+        duk_remove(ctx, -2); // remove package
 
     duk_call(ctx, numargs);
 
@@ -154,6 +171,8 @@ void js_push_variant(duk_context *ctx, const Variant& v)
     Object* object;
     Vector2& vector2 = (Vector2&) Vector2::ZERO;
     Vector3& vector3 = (Vector3&) Vector3::ZERO;
+    void* uniqueClassID = NULL;
+    const char* package = NULL;
 
     switch (type)
     {
@@ -169,8 +188,17 @@ void js_push_variant(duk_context *ctx, const Variant& v)
 
         object = (Object*) ref;
 
+
+        // check that class is supported
+        uniqueClassID = (void *) object->GetTypeName().CString();
+        duk_push_heap_stash(ctx);
+        duk_push_pointer(ctx, uniqueClassID);
+        duk_get_prop(ctx, -2);
+        package = duk_to_string(ctx, -1);
+        duk_pop_2(ctx);
+
         // check that class is supported
-        duk_get_global_string(ctx, "Atomic");
+        duk_get_global_string(ctx, package);
 
         // will not handle renamed classes!
         duk_get_prop_string(ctx, -1, object->GetTypeName().CString());

+ 13 - 5
Source/AtomicJS/Javascript/JSAPI.h

@@ -22,11 +22,19 @@ namespace Atomic
 class JSVM;
 class Object;
 
-void js_constructor_basecall(duk_context* ctx, const char* baseclass);
-void js_class_declare(JSVM* vm, const char* classname, duk_c_function constructor);
-void js_setup_prototype(JSVM* vm, const char* classname, const char* basename, bool hasProperties = false);
-void js_class_push_propertyobject(JSVM* vm, const char* classname);
-void js_class_get_prototype(duk_context* ctx, const char *classname);
+void js_class_declare_internal(JSVM* vm, void* uniqueClassID, const char* package, const char* classname, duk_c_function constructor);
+
+template<typename T>
+void js_class_declare(JSVM* vm, const char* package, const char* classname, duk_c_function constructor)
+{
+    void* uniqueID = (void*) T::GetTypeNameStatic().CString();
+    js_class_declare_internal(vm, uniqueID, package, classname, constructor);
+}
+
+void js_constructor_basecall(duk_context* ctx, const char* package, const char* baseclass);
+void js_setup_prototype(JSVM* vm, const char* package, const char* classname, const char* basePackage, const char* basename, bool hasProperties = false);
+void js_class_push_propertyobject(JSVM* vm, const char* package, const char* classname);
+void js_class_get_prototype(duk_context* ctx, const char* package, const char *classname);
 
 /// Pushes variant value or undefined if can't be pushed
 void js_push_variant(duk_context* ctx, const Variant &v);

+ 1 - 1
Source/AtomicJS/Javascript/JSCore.cpp

@@ -125,7 +125,7 @@ void jsapi_init_core(JSVM* vm)
 {
     duk_context* ctx = vm->GetJSContext();
 
-    js_class_get_prototype(ctx, "AObject");
+    js_class_get_prototype(ctx, "Atomic", "AObject");
     duk_push_c_function(ctx, Object_SubscribeToEvent, DUK_VARARGS);
     duk_put_prop_string(ctx, -2, "subscribeToEvent");
     duk_pop(ctx);

+ 1 - 1
Source/AtomicJS/Javascript/JSGraphics.cpp

@@ -55,7 +55,7 @@ void jsapi_init_graphics(JSVM* vm)
 {
     duk_context* ctx = vm->GetJSContext();
 
-    js_class_get_prototype(ctx, "Light");
+    js_class_get_prototype(ctx, "Atomic", "Light");
     duk_push_c_function(ctx, Light_SetShadowCascade, DUK_VARARGS);
     duk_put_prop_string(ctx, -2, "setShadowCascade");
     duk_push_c_function(ctx, Light_SetShadowBias, 2);

+ 2 - 2
Source/AtomicJS/Javascript/JSIO.cpp

@@ -59,12 +59,12 @@ void jsapi_init_io(JSVM* vm)
 {
     duk_context* ctx = vm->GetJSContext();
 
-    js_class_get_prototype(ctx, "File");
+    js_class_get_prototype(ctx, "Atomic", "File");
     duk_push_c_function(ctx, File_ReadText, 0);
     duk_put_prop_string(ctx, -2, "readText");
     duk_pop(ctx);
 
-    js_class_get_prototype(ctx, "FileSystem");
+    js_class_get_prototype(ctx, "Atomic", "FileSystem");
     duk_push_c_function(ctx, FileSystem_ScanDir, 4);
     duk_put_prop_string(ctx, -2, "scanDir");
     duk_pop(ctx);

+ 2 - 2
Source/AtomicJS/Javascript/JSScene.cpp

@@ -112,7 +112,7 @@ void jsapi_init_scene(JSVM* vm)
 {
     duk_context* ctx = vm->GetJSContext();
 
-    js_class_get_prototype(ctx, "Node");
+    js_class_get_prototype(ctx, "Atomic", "Node");
     duk_push_c_function(ctx, Node_GetChildrenWithComponent, DUK_VARARGS);
     duk_put_prop_string(ctx, -2, "getChildrenWithComponent");
     duk_push_c_function(ctx, Node_GetChildrenWithName, DUK_VARARGS);
@@ -121,7 +121,7 @@ void jsapi_init_scene(JSVM* vm)
     duk_put_prop_string(ctx, -2, "createJSComponent");
     duk_pop(ctx);
 
-    js_class_get_prototype(ctx, "Scene");
+    js_class_get_prototype(ctx, "Atomic", "Scene");
     duk_push_c_function(ctx, Scene_LoadXML, 1);
     duk_put_prop_string(ctx, -2, "loadXML");
     duk_pop(ctx);

+ 2 - 2
Source/AtomicJS/Javascript/JSUIAPI.cpp

@@ -307,12 +307,12 @@ void jsapi_init_ui(JSVM* vm)
 
     duk_pop(ctx);
 
-    js_class_get_prototype(ctx, "UIButton");
+    js_class_get_prototype(ctx, "Atomic", "UIButton");
     duk_push_c_function(ctx, UIButton_Popup, 2);
     duk_put_prop_string(ctx, -2, "popup");
     duk_pop(ctx);
 
-    js_class_get_prototype(ctx, "UIWindow");
+    js_class_get_prototype(ctx, "Atomic", "UIWindow");
     duk_push_c_function(ctx, UIWindow_GetResizeToFitContentRect, 0);
     duk_put_prop_string(ctx, -2, "getResizeToFitContentRect");
     duk_pop(ctx);

+ 14 - 2
Source/AtomicJS/Javascript/JSVM.h

@@ -226,15 +226,27 @@ inline bool js_push_class_object_instance(duk_context* ctx, const RefCounted *in
         return true;
     }
 
-    duk_get_global_string(ctx, "Atomic");
-
     // will not handle renamed classes
     if (instance->IsObject())
+    {
+        Object *obj = (Object*) instance;
+
+        void* uniqueClassID = (void *) obj->GetTypeName().CString();
+        duk_push_heap_stash(ctx);
+        duk_push_pointer(ctx, uniqueClassID);
+        duk_get_prop(ctx, -2);
+        const char* package = duk_require_string(ctx, -1);
+        duk_pop_2(ctx);
+
+        duk_get_global_string(ctx, package);
         duk_get_prop_string(ctx, -1, ((Object*)instance)->GetTypeName().CString());
+    }
     else
     {
+        duk_get_global_string(ctx, "Atomic");
         duk_get_prop_string(ctx, -1, classname);
     }
+
     duk_push_pointer(ctx, (void*) instance);
     duk_new(ctx, 1);
     duk_remove(ctx, -2); // remove Atomic object

+ 3 - 1
Source/ToolCore/JSBind/JSBClassWriter.cpp

@@ -49,9 +49,11 @@ void JSBClassWriter::GenerateSource(String& sourceOut)
 
     WriteFunctions(source);
 
+    String packageName = klass_->GetModule()->GetPackage()->GetName();
+
     source.AppendWithFormat("static void jsb_class_define_%s(JSVM* vm)\n{\n", klass_->GetName().CString());
     source.Append("duk_context* ctx = vm->GetJSContext();\n");
-    source.AppendWithFormat("js_class_get_prototype(ctx, \"%s\");\n", klass_->GetName().CString());
+    source.AppendWithFormat("js_class_get_prototype(ctx, \"%s\", \"%s\");\n", packageName.CString(), klass_->GetName().CString());
 
     for (unsigned i = 0; i < klass_->functions_.Size(); i++)
     {

+ 2 - 1
Source/ToolCore/JSBind/JSBFunctionWriter.cpp

@@ -288,7 +288,8 @@ void JSBFunctionWriter::WriteConstructor(String& source)
 
     if (base)
     {
-        source.AppendWithFormat("   js_constructor_basecall(ctx, \"%s\");\n", base->GetName().CString());
+        String basePackage = base->GetModule()->GetPackage()->GetName();
+        source.AppendWithFormat("   js_constructor_basecall(ctx, \"%s\", \"%s\");\n", basePackage.CString(), base->GetName().CString());
     }
 
     if (function_->name_ == "RefCounted")

+ 8 - 3
Source/ToolCore/JSBind/JSBModuleWriter.cpp

@@ -43,6 +43,8 @@ void JSBModuleWriter::WriteClassDeclaration(String& source)
 
     source += "duk_context* ctx = vm->GetJSContext();\n";
 
+    String packageName = module_->GetPackage()->GetName();
+
     for (unsigned i = 0; i < classes.Size(); i++)
     {
         JSBClass* klass = classes.At(i);
@@ -50,12 +52,15 @@ void JSBModuleWriter::WriteClassDeclaration(String& source)
         if (klass->IsNumberArray())
             continue;
 
-        source.AppendWithFormat("   js_class_declare(vm, \"%s\", jsb_constructor_%s);\n", klass->GetName().CString(), klass->GetName().CString());
+        if (klass->IsObject())
+            source.AppendWithFormat("   js_class_declare<%s>(vm, \"%s\", \"%s\", jsb_constructor_%s);\n", klass->GetNativeName().CString(), packageName.CString(), klass->GetName().CString(), klass->GetName().CString());
+        else
+            source.AppendWithFormat("   js_class_declare_internal(vm, NULL, \"%s\", \"%s\", jsb_constructor_%s);\n", packageName.CString(), klass->GetName().CString(), klass->GetName().CString());
+
 
         if (klass->HasProperties())
         {
-            source.AppendWithFormat("js_class_push_propertyobject(vm, \"%s\");\n", klass->GetName().CString());
-
+            source.AppendWithFormat("js_class_push_propertyobject(vm, \"%s\", \"%s\");\n", packageName.CString(), klass->GetName().CString());
 
             Vector<String> pnames;
             klass->GetPropertyNames(pnames);

+ 8 - 2
Source/ToolCore/JSBind/JSBPackageWriter.cpp

@@ -42,9 +42,15 @@ void JSBPackageWriter::WriteProtoTypeRecursive(String &source, JSBClass* klass,
 
         if (module->Requires("3D"))
             source += "\n#ifdef ATOMIC_3D\n";
-        source.AppendWithFormat("   js_setup_prototype(vm, \"%s\", \"%s\", %s);\n",
-                                klass->GetName().CString(), base ? base->GetName().CString() : "",
+
+        String packageName =  klass->GetModule()->GetPackage()->GetName();
+        String basePackage =  base ? base->GetModule()->GetPackage()->GetName() : "";
+
+        source.AppendWithFormat("   js_setup_prototype(vm, \"%s\", \"%s\", \"%s\", \"%s\", %s);\n",
+                                packageName.CString(), klass->GetName().CString(),
+                                base ? basePackage.CString() : "", base ? base->GetName().CString() : "",
                                 klass->HasProperties() ? "true" : "false");
+
         if (module->Requires("3D"))
             source += "#endif\n\n";
     }

+ 6 - 3
Source/ToolCoreJS/ToolCoreJS.cpp

@@ -31,11 +31,14 @@ static int js_atomic_GetToolSystem(duk_context* ctx)
 
 void jsapi_init_toolcore(JSVM* vm)
 {
-    jsb_package_toolcore_init(vm);
-
     duk_context* ctx = vm->GetJSContext();
 
-    duk_get_global_string(ctx, "Atomic");
+    duk_push_object(ctx);
+    duk_put_global_string(ctx, "ToolCore");
+
+    jsb_package_toolcore_init(vm);
+
+    duk_get_global_string(ctx, "ToolCore");
 
     duk_push_c_function(ctx, js_atomic_GetToolEnvironment, 0);
     duk_put_prop_string(ctx, -2, "getToolEnvironment");