Просмотр исходного кода

JSBind method exclusions, JSScriptObject, variant map from object conversion, etc

Josh Engebretson 10 лет назад
Родитель
Сommit
3b7aed0057

+ 38 - 0
Source/AtomicJS/Javascript/JSAPI.cpp

@@ -164,6 +164,44 @@ void js_setup_prototype(JSVM* vm, const char* package, const char* classname, co
     assert (top == duk_get_top(ctx));
 }
 
+void js_object_to_variantmap(duk_context* ctx, int objIdx, VariantMap &v)
+{
+    v.Clear();
+
+    duk_enum(ctx, objIdx, DUK_ENUM_OWN_PROPERTIES_ONLY);
+
+    while (duk_next(ctx, -1 /*enum_index*/, 1 /*get_value*/)) {
+
+        /* [ ... enum key ] */
+
+        const char* key = duk_to_string(ctx, -2);
+
+        if (duk_is_number(ctx, -1)) {
+
+            v[key] = (float) duk_to_number(ctx, -1);
+
+        } else if (duk_is_boolean(ctx, -1)) {
+
+            v[key] = duk_to_boolean(ctx, -1) ? true : false;
+
+        }
+        else if (duk_is_string(ctx, -1)) {
+
+            v[key] = duk_to_string(ctx, -1);
+
+        } else if (duk_get_heapptr(ctx, -1)) {
+
+            v[key] = js_to_class_instance<Object*>(ctx, -1, 0);
+
+        }
+
+        duk_pop_2(ctx);  /* pop_key & value*/
+    }
+
+    duk_pop(ctx);  /* pop enum object */
+
+}
+
 void js_push_variant(duk_context *ctx, const Variant& v)
 {
     VariantType type = v.GetType();

+ 2 - 0
Source/AtomicJS/Javascript/JSAPI.h

@@ -39,4 +39,6 @@ void js_class_get_prototype(duk_context* ctx, const char* package, const char *c
 /// Pushes variant value or undefined if can't be pushed
 void js_push_variant(duk_context* ctx, const Variant &v);
 
+void js_object_to_variantmap(duk_context* ctx, int objIdx, VariantMap &v);
+
 }

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

@@ -45,7 +45,6 @@ static int Object_SubscribeToEvent(duk_context* ctx)
 
     StringHash eventType = StringHash::ZERO;
 
-
     if ( top == 2 ) // General notification: subscribeToEvent("ScreenMode", function() {});
     {
         if (duk_is_string(ctx, 0) && duk_is_function(ctx, 1))
@@ -121,6 +120,37 @@ static int Object_SubscribeToEvent(duk_context* ctx)
     return 0;
 }
 
+// so we don't keep allocating these
+static VariantMap sendEventVMap;
+static int Object_SendEvent(duk_context* ctx)
+{
+    int top = duk_get_top(ctx);
+
+    duk_push_this(ctx);
+
+    // event sender
+    Object* sender = js_to_class_instance<Object>(ctx, -1, 0);
+
+    if (top == 1)
+    {
+        sender->SendEvent(duk_to_string(ctx, 0));
+    }
+    else if (top == 2)
+    {
+        if (duk_is_object(ctx, 1)) {
+
+            js_object_to_variantmap(ctx, 1, sendEventVMap);
+
+            sender->SendEvent(duk_to_string(ctx, 0), sendEventVMap);
+
+        }
+
+    }
+
+    return 0;
+
+}
+
 void jsapi_init_core(JSVM* vm)
 {
     duk_context* ctx = vm->GetJSContext();
@@ -128,6 +158,8 @@ void jsapi_init_core(JSVM* vm)
     js_class_get_prototype(ctx, "Atomic", "AObject");
     duk_push_c_function(ctx, Object_SubscribeToEvent, DUK_VARARGS);
     duk_put_prop_string(ctx, -2, "subscribeToEvent");
+    duk_push_c_function(ctx, Object_SendEvent, DUK_VARARGS);
+    duk_put_prop_string(ctx, -2, "sendEvent");
     duk_pop(ctx);
 }
 

+ 16 - 0
Source/AtomicJS/Javascript/JSScriptObject.cpp

@@ -0,0 +1,16 @@
+
+#include "JSScriptObject.h"
+
+namespace Atomic
+{
+
+JSScriptObject::JSScriptObject(Context* context) : Object(context)
+{
+
+}
+
+JSScriptObject::~JSScriptObject()
+{
+
+}
+}

+ 24 - 0
Source/AtomicJS/Javascript/JSScriptObject.h

@@ -0,0 +1,24 @@
+
+#pragma once
+
+#include <Atomic/Core/Object.h>
+
+namespace Atomic
+{
+
+/// ScriptObject makes it possible for script classes to inherit "directly" from
+/// Object (which is abstract) and use the event system, etc
+class JSScriptObject : public Object
+{
+
+    OBJECT(JSScriptObject);
+
+public:
+    /// Construct.
+    JSScriptObject(Context* context);
+    /// Destruct.
+    virtual ~JSScriptObject();
+
+};
+
+}

+ 5 - 0
Source/AtomicJS/Packages/Atomic/Core.json

@@ -4,5 +4,10 @@
 	"classes" : ["Context", "Object"],
 	"classes_rename" : {
 		"Object" : "AObject"
+	},
+	"excludes" : {
+		"Object" : {
+			"SendEvent" : ["StringHash"]
+		}
 	}
 }

+ 1 - 1
Source/AtomicJS/Packages/Atomic/Javascript.json

@@ -1,5 +1,5 @@
 {
 	"name" : "Javascript",
 	"sources" : ["Source/AtomicJS/Javascript"],
-	"classes" : ["JSVM", "JSComponent", "JSMetrics", "JSEventHelper"]
+	"classes" : ["JSVM", "JSComponent", "JSMetrics", "JSEventHelper", "JSScriptObject"]
 }

+ 94 - 69
Source/ToolCore/JSBind/JSBClass.cpp

@@ -10,13 +10,13 @@
 namespace ToolCore
 {
 
-JSBFunctionOverride::JSBFunctionOverride(const String &name, const Vector<String>& sig) : parsed_(false)
+JSBFunctionSignature::JSBFunctionSignature(const String &name, const Vector<String>& sig) : parsed_(false)
 {
     name_ = name;
     sig_ = sig;
 }
 
-void JSBFunctionOverride::Parse()
+void JSBFunctionSignature::Parse()
 {
     if (parsed_)
         return;
@@ -35,6 +35,71 @@ void JSBFunctionOverride::Parse()
 
 }
 
+bool JSBFunctionSignature::Match(JSBFunction* function)
+{
+
+    if (name_ != function->GetName())
+        return false;
+
+    Vector<JSBFunctionType*>& parameters = function->GetParameters();
+
+    if (types_.Size() != parameters.Size())
+        return false;
+
+    for (unsigned x = 0; x < parameters.Size(); x++)
+    {
+        JSBType* ot = types_[x];
+        JSBType* pt = parameters[x]->type_;
+
+        // should add an == operator
+        if ((ot->asPrimitiveType() == NULL) != (pt->asPrimitiveType() == NULL) ||
+                (ot->asClassType() == NULL) != (pt->asClassType() == NULL) )
+        {
+            return false;
+        }
+
+        if (ot->asPrimitiveType())
+        {
+            JSBPrimitiveType* pot = ot->asPrimitiveType();
+            JSBPrimitiveType* ppt = pt->asPrimitiveType();
+
+            if (pot->kind_ != ppt->kind_)
+            {
+                return false;
+            }
+        }
+        if (ot->asClassType())
+        {
+            JSBClassType* cot = ot->asClassType();
+            JSBClassType* cpt = pt->asClassType();
+
+            if (cot->class_ != cpt->class_)
+            {
+                return false;
+            }
+        }
+        if (ot->asStringType())
+        {
+            if (!pt->asStringType())
+            {
+                return false;
+            }
+        }
+        if (ot->asStringHashType())
+        {
+            if (!pt->asStringHashType())
+            {
+                return false;
+            }
+        }
+
+
+    }
+
+    return true;
+
+}
+
 JSBClass::JSBClass(Context* context, JSBModule *module, const String& name, const String& nativeName) : Object(context),
     module_(module), name_(name), nativeName_(nativeName),
     isAbstract_(false), isObject_(false),
@@ -153,6 +218,28 @@ void JSBClass::Process()
         overrides_.At(j)->Parse();
     }
 
+    for (unsigned j = 0; j < excludes_.Size(); j++)
+    {
+        excludes_.At(j)->Parse();
+    }
+
+
+    // detect skips
+
+    for (unsigned j = 0; j < functions_.Size(); j++)
+    {
+
+        for (unsigned k = 0; k < excludes_.Size(); k++)
+        {
+            if (excludes_[k]->Match(functions_[j]))
+            {
+                functions_[j]->SetSkip(true);
+                break;
+            }
+
+        }
+    }
+
     // detect overridden functions, only works for in class atm (not baseclasses)
     for (unsigned j = 0; j < functions_.Size(); j++)
     {
@@ -211,77 +298,15 @@ void JSBClass::Process()
         if (function->IsOverride())
         {
             for (unsigned k = 0; k < overrides_.Size(); k++)
-            {
-                JSBFunctionOverride* override =  overrides_[k];
+            {                
+                JSBFunctionSignature* override =  overrides_[k];
 
-                if (override->name_ != function->GetName())
+                if (!override->Match(function))
                     continue;
 
-                Vector<JSBFunctionType*>& parameters = function->GetParameters();
-
-                if (override->types_.Size() != parameters.Size())
-                    continue;
+                function->SetSkip(false);
 
-                bool match = true;
-                for (unsigned x = 0; x < parameters.Size(); x++)
-                {
-                    JSBType* ot = override->types_[x];
-                    JSBType* pt = parameters[x]->type_;
-
-                    // should add an == operator
-                    if ((ot->asPrimitiveType() == NULL) != (pt->asPrimitiveType() == NULL) ||
-                            (ot->asClassType() == NULL) != (pt->asClassType() == NULL) )
-                    {
-                        match = false;
-                        break;
-                    }
-
-                    if (ot->asPrimitiveType())
-                    {
-                        JSBPrimitiveType* pot = ot->asPrimitiveType();
-                        JSBPrimitiveType* ppt = pt->asPrimitiveType();
-
-                        if (pot->kind_ != ppt->kind_)
-                        {
-                            match = false;
-                            break;
-                        }
-                    }
-                    if (ot->asClassType())
-                    {
-                        JSBClassType* cot = ot->asClassType();
-                        JSBClassType* cpt = pt->asClassType();
-
-                        if (cot->class_ != cpt->class_)
-                        {
-                            match = false;
-                            break;
-                        }
-                    }
-                    if (ot->asStringType())
-                    {
-                        if (!pt->asStringType())
-                        {
-                            match = false;
-                            break;
-                        }
-                    }
-                    if (ot->asStringHashType())
-                    {
-                        if (!pt->asStringHashType())
-                        {
-                            match = false;
-                            break;
-                        }
-                    }
-
-
-                }
-                if (match)
-                {
-                    function->SetSkip(false);
-                    break;
-                }
+                break;
 
             }
 

+ 8 - 5
Source/ToolCore/JSBind/JSBClass.h

@@ -16,21 +16,22 @@ class JSBFunction;
 class JSBType;
 
 // chosen function overrides
-class JSBFunctionOverride
+class JSBFunctionSignature
 {
 
 public:
 
-    JSBFunctionOverride(const String& name, const Vector<String>& sig);
+    JSBFunctionSignature(const String& name, const Vector<String>& sig);
 
     String name_;
     Vector<String> sig_;
     Vector<JSBType*> types_;
 
+    bool Match(JSBFunction* function);
+
     void Parse() ;
 
     bool parsed_;
-
 };
 
 class JSBProperty
@@ -100,7 +101,8 @@ public:
 
     void SetSkipFunction(const String& name, bool skip = true);
     void AddFunction(JSBFunction* function);
-    void AddFunctionOverride(JSBFunctionOverride* override) { overrides_.Push(override); }
+    void AddFunctionOverride(JSBFunctionSignature* override) { overrides_.Push(override); }
+    void AddFunctionExclude(JSBFunctionSignature* exclude) { excludes_.Push(exclude); }
     void AddPropertyFunction(JSBFunction* function);
 
     void Preprocess();
@@ -122,7 +124,8 @@ private:
     PODVector<JSBFunction*> functions_;
     PODVector<JSBClass*> baseClasses_;
 
-    PODVector<JSBFunctionOverride*> overrides_;
+    PODVector<JSBFunctionSignature*> overrides_;
+    PODVector<JSBFunctionSignature*> excludes_;
 
     bool isAbstract_;
     bool isObject_;

+ 52 - 1
Source/ToolCore/JSBind/JSBModule.cpp

@@ -64,6 +64,7 @@ void JSBModule::VisitHeaders()
     }
 
     ProcessOverloads();
+    ProcessExcludes();
 
 }
 
@@ -139,7 +140,7 @@ void JSBModule::ProcessOverloads()
                     values.Push(sig.GetString(x));
                 }
 
-                JSBFunctionOverride* fo = new JSBFunctionOverride(functionNames[k], values);
+                JSBFunctionSignature* fo = new JSBFunctionSignature(functionNames[k], values);
                 klass->AddFunctionOverride(fo);
 
             }
@@ -147,6 +148,56 @@ void JSBModule::ProcessOverloads()
     }
 }
 
+void JSBModule::ProcessExcludes()
+{
+    // excludes
+
+    JSONValue root = moduleJSON_->GetRoot();
+
+    JSONValue excludes = root.GetChild("excludes");
+
+    if (excludes.IsObject())
+    {
+        Vector<String> childNames = excludes.GetChildNames();
+
+        for (unsigned j = 0; j < childNames.Size(); j++)
+        {
+            String classname = childNames.At(j);
+
+            JSBClass* klass = GetClass(classname);
+
+            if (!klass)
+            {
+                ErrorExit("Bad overload klass");
+            }
+
+            JSONValue classexcludes = excludes.GetChild(classname);
+
+            Vector<String> functionNames = classexcludes.GetChildNames();
+
+            for (unsigned k = 0; k < functionNames.Size(); k++)
+            {
+                JSONValue sig = classexcludes.GetChild(functionNames[k]);
+
+                if (!sig.IsArray())
+                {
+                    ErrorExit("Bad exclude defintion");
+                }
+
+                Vector<String> values;
+                for (unsigned x = 0; x < sig.GetSize(); x++)
+                {
+                    values.Push(sig.GetString(x));
+                }
+
+                JSBFunctionSignature* fe = new JSBFunctionSignature(functionNames[k], values);
+                klass->AddFunctionExclude(fe);
+
+            }
+        }
+    }
+}
+
 void JSBModule::ScanHeaders()
 {
     JSBind* jsbind = GetSubsystem<JSBind>();

+ 1 - 0
Source/ToolCore/JSBind/JSBModule.h

@@ -61,6 +61,7 @@ public:
 private:
 
     void ProcessOverloads();
+    void ProcessExcludes();
 
     void ScanHeaders();