[gjs] gi: arg: use instance's gtype rather than the introspection data



commit 6cfbeed1e48696c333d585364428f4e90e0a1667
Author: Lionel Landwerlin <llandwerlin gmail com>
Date:   Tue Apr 8 14:58:23 2014 +0100

    gi: arg: use instance's gtype rather than the introspection data
    
    When converting a native object to it's JavaScript proxy, we want to
    be as precise as possible to map that native object.
    Right now we handle different kinds of proxy for native types :
          * GObject proxies
          * GBoxed proxies
          * GParam proxies
          * GError proxies
          * Function proxies
          * Unions proxies
          * GI proxies
          * Fundamental proxies
          * basic types
    
    The introspection data can provide information that helps us map a
    GType to one of the items listed above. But there is a case that is
    rather painful to deal with : interfaces.
    
    In GObject interfaces can be attached to different kind of GTypes
    (that includes GObjects and custom fundamental types and maybe more, I
    haven't checked all the twisted cases). Although there is a way to add
    a prerequisite for an interface, not all interface properly use this
    feature.
    
    In this particular case (native -> JS) we can use the native object's
    gtype to figure out the most appropriate proxy, which what this patch
    implements.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=727824

 gi/arg.cpp                              |    8 ++++++++
 installed-tests/js/testGIMarshalling.js |    7 +++++++
 2 files changed, 15 insertions(+), 0 deletions(-)
---
diff --git a/gi/arg.cpp b/gi/arg.cpp
index ba86c23..1da4fe6 100644
--- a/gi/arg.cpp
+++ b/gi/arg.cpp
@@ -2598,6 +2598,10 @@ gjs_value_from_g_argument (JSContext  *context,
             }
 
             gtype = g_registered_type_info_get_g_type((GIRegisteredTypeInfo*)interface_info);
+            if (G_TYPE_IS_INSTANTIATABLE(gtype) ||
+                G_TYPE_IS_INTERFACE(gtype))
+                gtype = G_TYPE_FROM_INSTANCE(arg->v_pointer);
+
             gjs_debug_marshal(GJS_DEBUG_GFUNCTION,
                               "gtype of INTERFACE is %s", g_type_name(gtype));
 
@@ -2903,6 +2907,10 @@ gjs_g_arg_release_internal(JSContext  *context,
                 goto out;
 
             gtype = g_registered_type_info_get_g_type((GIRegisteredTypeInfo*)interface_info);
+            if (G_TYPE_IS_INSTANTIATABLE(gtype) ||
+                G_TYPE_IS_INTERFACE(gtype))
+                gtype = G_TYPE_FROM_INSTANCE(arg->v_pointer);
+
             gjs_debug_marshal(GJS_DEBUG_GFUNCTION,
                               "gtype of INTERFACE is %s", g_type_name(gtype));
 
diff --git a/installed-tests/js/testGIMarshalling.js b/installed-tests/js/testGIMarshalling.js
index 4000f9f..a2e8e35 100644
--- a/installed-tests/js/testGIMarshalling.js
+++ b/installed-tests/js/testGIMarshalling.js
@@ -401,4 +401,11 @@ function testVFuncs() {
     assertEquals(50, c);
 }
 
+function testInterfaces() {
+    let ifaceImpl = new GIMarshallingTests.InterfaceImpl();
+    let itself = ifaceImpl.get_as_interface();
+
+    assertEquals(ifaceImpl, itself);
+}
+
 gjstestRun();


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]