Browse Source

JS Event Handling

Josh Engebretson 10 years ago
parent
commit
1faf82de6c

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

@@ -6,15 +6,20 @@ var view = new Atomic.UIView();
 
 var mainframe = new UIWidget();
 
-mainframe.load("AtomicEditor/editor/ui/mainframe.tb.txt");
 mainframe.setSize(graphics.width, graphics.height);
 
-var handleEvent = function() {
+mainframe.subscribeToEvent("ScreenMode", function(data) {
+
+  mainframe.setSize(data.width, data.height);
+
+});
 
-  print("Got Event");
+mainframe.subscribeToEvent("WidgetLoaded", function(data) {
 
-}
+  print("Widget Loaded", data.widget == mainframe);
 
-mainframe.subscribeToEvent("ScreenMode", handleEvent);
+});
+
+mainframe.load("AtomicEditor/editor/ui/mainframe.tb.txt");
 
 view.addChild(mainframe);

+ 3 - 0
Source/AtomicJS/JSBind/JSBHeaderVisitor.h

@@ -66,6 +66,9 @@ public:
             NamedType* ntype = type->asNamedType();
             String classname = getNameString(ntype->name());
 
+            if (classname.StartsWith("Atomic::"))
+                classname.Replace("Atomic::", "");
+
             if (classname == "String")
             {
                 jtype = new JSBStringType();

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

@@ -147,4 +147,84 @@ void js_setup_prototype(JSVM* vm, const char* classname, const char* basename, b
     assert (top == duk_get_top(ctx));
 }
 
+void js_push_variant(duk_context *ctx, const Variant& v)
+{
+    VariantType type = v.GetType();
+    RefCounted* ref;
+    Object* object;
+    Vector2& vector2 = (Vector2&) Vector2::ZERO;
+    Vector3& vector3 = (Vector3&) Vector3::ZERO;
+
+    switch (type)
+    {
+    case VAR_PTR:
+
+        ref = v.GetPtr();
+
+        if (!ref || !ref->IsObject())
+        {
+            duk_push_null(ctx);
+            break;
+        }
+
+        object = (Object*) ref;
+
+        // check that class is supported
+        duk_get_global_string(ctx, "Atomic");
+
+        // will not handle renamed classes!
+        duk_get_prop_string(ctx, -1, object->GetTypeName().CString());
+
+        if (!duk_is_function(ctx, -1))
+            object = NULL;
+
+        duk_pop_n(ctx, 2);
+
+        if (object)
+            js_push_class_object_instance(ctx, object);
+        else
+            duk_push_undefined(ctx);
+        break;
+
+    case VAR_BOOL:
+        duk_push_boolean(ctx, v.GetBool() ? 1 : 0);
+        break;
+    case VAR_INT:
+        duk_push_number(ctx, v.GetInt());
+        break;
+    case VAR_FLOAT:
+        duk_push_number(ctx, v.GetFloat());
+        break;
+    case VAR_STRING:
+        duk_push_string(ctx, v.GetString().CString());
+        break;
+    case VAR_VECTOR2:
+        vector2 = v.GetVector2();
+        duk_push_array(ctx);
+        duk_push_number(ctx, vector2.x_);
+        duk_put_prop_index(ctx, -1, 0);
+        duk_push_number(ctx, vector2.y_);
+        duk_put_prop_index(ctx, -1, 1);
+        break;
+    case VAR_VECTOR3:
+        vector3 = v.GetVector3();
+        duk_push_array(ctx);
+        duk_push_number(ctx, vector3.x_);
+        duk_put_prop_index(ctx, -1, 0);
+        duk_push_number(ctx, vector3.y_);
+        duk_put_prop_index(ctx, -1, 1);
+        duk_push_number(ctx, vector3.z_);
+        duk_put_prop_index(ctx, -1, 1);
+        break;
+
+    default:
+        duk_push_undefined(ctx);
+        break;
+    }
+
+
 }
+
+
+}
+

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

@@ -28,4 +28,7 @@ void js_setup_prototype(JSVM* vm, const char* classname, const char* basename, b
 void js_class_push_propertyobject(JSVM* vm, const char* classname);
 void js_class_get_prototype(duk_context* ctx, const char *classname);
 
+/// Pushes variant value or undefined if can't be pushed
+void js_push_variant(duk_context* ctx, const Variant &v);
+
 }

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

@@ -9,6 +9,33 @@
 namespace Atomic
 {
 
+static int EventHandler_Property_Get(duk_context* ctx)
+{
+    // targ, key, recv
+
+    if (duk_is_string(ctx, 1))
+    {
+        const char* cstr = duk_to_string(ctx, 1);
+        StringHash key = cstr;
+
+        JSEventHelper* helper = js_to_class_instance<JSEventHelper>(ctx, 0, 0);
+        VariantMap& data = helper->GetCurrentData();
+
+        if (!data.Contains(key))
+        {
+            duk_push_undefined(ctx);
+            return 1;
+        }
+
+        js_push_variant(ctx, data[key]);
+        return 1;
+    }
+
+    duk_push_undefined(ctx);
+    return 1;
+
+}
+
 static int Object_SubscribeToEvent(duk_context* ctx)
 {
     duk_push_this(ctx); // stack 2
@@ -24,6 +51,18 @@ static int Object_SubscribeToEvent(duk_context* ctx)
         // construct a new event helper
         js_push_class_object_instance(ctx, new JSEventHelper(object->GetContext()));
 
+        // proxy support
+        duk_get_global_string(ctx, "Proxy");
+
+        duk_dup(ctx, -2);
+
+        // setup property handler
+        duk_push_object(ctx);
+        duk_push_c_function(ctx, EventHandler_Property_Get, 3);
+        duk_put_prop_string(ctx, -2, "get");
+        duk_new(ctx, 2);
+        duk_put_prop_string(ctx, -2, "__eventHelperProxy");
+
         duk_push_object(ctx);
         duk_put_prop_string(ctx, -2, "__eventHelperFunctions");
 
@@ -58,7 +97,6 @@ void jsapi_init_core(JSVM* vm)
     js_class_get_prototype(ctx, "AObject");
     duk_push_c_function(ctx, Object_SubscribeToEvent, 2);
     duk_put_prop_string(ctx, -2, "subscribeToEvent");
-
     duk_pop(ctx);
 }
 

+ 9 - 3
Source/AtomicJS/Javascript/JSEventHelper.cpp

@@ -6,13 +6,14 @@ namespace Atomic
 {
 
 JSEventHelper::JSEventHelper(Context* context) :
-    Object(context)
+    Object(context),
+    currentData_((VariantMap&) Variant::emptyVariantMap)
 {
 }
 
 JSEventHelper::~JSEventHelper()
 {
-    LOGINFO("Boom");
+
 }
 
 void JSEventHelper::AddEventHandler(StringHash eventType)
@@ -37,7 +38,12 @@ void JSEventHelper::HandleEvent(StringHash eventType, VariantMap& eventData)
 
     if (duk_is_function(ctx, -1))
     {
-        if (duk_pcall(ctx, 0) != 0)
+        currentData_ = (const VariantMap&) eventData;
+        // pass in event helper proxy
+        duk_get_prop_string(ctx, -3, "__eventHelperProxy");
+        assert(duk_is_object(ctx, -1));
+
+        if (duk_pcall(ctx, 1) != 0)
         {
             vm->SendJSErrorEvent();
         }

+ 4 - 0
Source/AtomicJS/Javascript/JSEventHelper.h

@@ -18,10 +18,14 @@ public:
 
     void AddEventHandler(StringHash eventType);
 
+    VariantMap& GetCurrentData() { return currentData_; }
+
 private:
 
     void HandleEvent(StringHash eventType, VariantMap& eventData);
 
+    VariantMap& currentData_;
+
 };