[pygobject/invoke-rewrite] [gi] add object and interface in marshalling



commit 369a75ba5fb64ff7a7c95d21f8bfe359e639e9ff
Author: John (J5) Palmieri <johnp redhat com>
Date:   Mon Jan 10 17:55:03 2011 -0500

    [gi] add object and interface in marshalling
    
    * also remove the PyGIArgCleanup sinature as GDestroyNotify works just fine

 gi/pygi-argument.c |   15 +++-
 gi/pygi-cache.c    |  182 +++++++++++++++++++++++++++++++++++++++++++++++-----
 gi/pygi-cache.h    |    1 -
 gi/pygi-invoke.c   |    1 +
 4 files changed, 178 insertions(+), 21 deletions(-)
---
diff --git a/gi/pygi-argument.c b/gi/pygi-argument.c
index 126a68f..49d41b5 100644
--- a/gi/pygi-argument.c
+++ b/gi/pygi-argument.c
@@ -2604,7 +2604,7 @@ _pygi_marshal_in_array (PyGIInvokeState   *state,
         if (py_item == NULL) {
             int j;
             if (sequence_cache->item_cache->cleanup != NULL) {
-                PyGIArgCleanupFunc cleanup = sequence_cache->item_cache->cleanup;
+                GDestroyNotify cleanup = sequence_cache->item_cache->cleanup;
                 /*for(j = 0; j < i; j++)
                     cleanup((gpointer)(array_->data[j]));*/
             }
@@ -2754,9 +2754,16 @@ _pygi_marshal_in_interface_object (PyGIInvokeState   *state,
                                    PyObject          *py_arg,
                                    GIArgument        *arg)
 {
-    PyErr_Format(PyExc_NotImplementedError,
-                 "Marshalling for this type is not implemented yet");
-    return FALSE;
+    if (py_arg == Py_None) {
+        (*arg).v_pointer = NULL;
+        return TRUE;
+    }
+
+    (*arg).v_pointer = pygobject_get (py_arg);
+    if (arg_cache->transfer == GI_TRANSFER_EVERYTHING)
+        g_object_ref ((*arg).v_pointer);
+
+    return TRUE;
 }
 
 gboolean
diff --git a/gi/pygi-cache.c b/gi/pygi-cache.c
index 4ab711f..af4f704 100644
--- a/gi/pygi-cache.c
+++ b/gi/pygi-cache.c
@@ -103,7 +103,7 @@ _function_cache_new_from_function_info(GIFunctionInfo *function_info)
     flags = g_function_info_get_flags(function_info);
     fc->is_method = flags & GI_FUNCTION_IS_METHOD;
     fc->is_constructor = flags & GI_FUNCTION_IS_CONSTRUCTOR;
-    fc->n_args = g_callable_info_get_n_args ( (GICallableInfo *) function_info);
+    fc->n_args = g_callable_info_get_n_args ( (GICallableInfo *) function_info) + (fc->is_method ? 1: 0);
     if (fc->n_args > 0)
         fc->args_cache = g_slice_alloc0(fc->n_args * sizeof(PyGIArgCache *));
 
@@ -295,7 +295,7 @@ _arg_cache_new_for_in_filename(GITransfer transfer)
 
 static inline PyGIArgCache *
 _arg_cache_new_for_in_array(GITypeInfo *type_info,
-                                      GITransfer transfer)
+                            GITransfer transfer)
 {
     PyGIArgCache *arg_cache = (PyGIArgCache *)_sequence_cache_new_from_type_info(type_info);
     arg_cache->in_marshaller = _pygi_marshal_in_array;
@@ -305,16 +305,6 @@ _arg_cache_new_for_in_array(GITypeInfo *type_info,
 }
 
 static inline PyGIArgCache *
-_arg_cache_new_for_in_interface(void)
-{
-    PyGIArgCache *arg_cache = NULL;
-    /* TODO: Switch on GI_INFO_TYPE_ to determine caching */
-    PyErr_Format(PyExc_NotImplementedError,
-                 "Caching for this type is not fully implemented yet");
-    return arg_cache;
-}
-
-static inline PyGIArgCache *
 _arg_cache_new_for_in_glist(GITypeInfo *type_info,
                                       GITransfer transfer)
 {
@@ -355,6 +345,125 @@ _arg_cache_new_for_in_gerror(void)
     return arg_cache;
 }
 
+static inline PyGIArgCache *
+_arg_cache_new_for_in_interface_union(void)
+{
+    PyGIArgCache *arg_cache = NULL;
+    /*arg_cache->in_marshaller = _pygi_marshal_in_inteface_union;*/
+    PyErr_Format(PyExc_NotImplementedError,
+                 "Caching for this type is not fully implemented yet");
+    return arg_cache;
+}
+
+static inline PyGIArgCache *
+_arg_cache_new_for_in_interface_struct(void)
+{
+    PyGIArgCache *arg_cache = NULL;
+    /*arg_cache->in_marshaller = _pygi_marshal_in_interface_struct;*/
+    PyErr_Format(PyExc_NotImplementedError,
+                 "Caching for this type is not fully implemented yet");
+    return arg_cache;
+}
+
+static inline PyGIArgCache *
+_arg_cache_new_for_in_interface_object(GITransfer transfer)
+{
+    PyGIArgCache *arg_cache = _arg_cache_new();
+    arg_cache->in_marshaller = _pygi_marshal_in_interface_object;
+    if (transfer == GI_TRANSFER_EVERYTHING)
+        arg_cache->cleanup = (GDestroyNotify)g_object_unref;
+
+    return arg_cache;
+}
+
+static inline PyGIArgCache *
+_arg_cache_new_for_in_interface_boxed(void)
+{
+    PyGIArgCache *arg_cache = NULL;
+    /*arg_cache->in_marshaller = _pygi_marshal_in_boxed;*/
+    PyErr_Format(PyExc_NotImplementedError,
+                 "Caching for this type is not fully implemented yet");
+    return arg_cache;
+}
+
+static inline PyGIArgCache *
+_arg_cache_new_for_in_interface_callback(void)
+{
+    PyGIArgCache *arg_cache = NULL;
+    /*arg_cache->in_marshaller = _pygi_marshal_in_callback;*/
+    PyErr_Format(PyExc_NotImplementedError,
+                 "Caching for this type is not fully implemented yet");
+    return arg_cache;
+}
+
+static inline PyGIArgCache *
+_arg_cache_new_for_in_interface_enum(void)
+{
+    PyGIArgCache *arg_cache = NULL;
+    /*arg_cache->in_marshaller = _pygi_marshal_in_enum;*/
+    PyErr_Format(PyExc_NotImplementedError,
+                 "Caching for this type is not fully implemented yet");
+    return arg_cache;
+}
+
+static inline PyGIArgCache *
+_arg_cache_new_for_in_interface_flags(void)
+{
+    PyGIArgCache *arg_cache = NULL;
+    /*arg_cache->in_marshaller = _pygi_marshal_in_flags;*/
+    PyErr_Format(PyExc_NotImplementedError,
+                 "Caching for this type is not fully implemented yet");
+    return arg_cache;
+}
+
+PyGIArgCache *
+_arg_cache_in_new_from_interface_info (GIInterfaceInfo *iface_info,
+                                       PyGIFunctionCache *function_cache,
+                                       GIInfoType info_type,
+                                       GITransfer transfer,
+                                       GIDirection direction,
+                                       gint c_arg_index,
+                                       gint py_arg_index)
+{
+    PyGIArgCache *arg_cache = NULL;
+
+    switch (info_type) {
+        case GI_INFO_TYPE_UNION:
+            arg_cache = _arg_cache_new_for_in_interface_union();
+            break;
+        case GI_INFO_TYPE_STRUCT:
+            arg_cache = _arg_cache_new_for_in_interface_struct();
+            break;
+        case GI_INFO_TYPE_OBJECT:
+        case GI_INFO_TYPE_INTERFACE:
+            arg_cache = _arg_cache_new_for_in_interface_object(transfer);
+            break;
+        case GI_INFO_TYPE_BOXED:
+            arg_cache = _arg_cache_new_for_in_interface_boxed();
+            break;
+        case GI_INFO_TYPE_CALLBACK:
+            arg_cache = _arg_cache_new_for_in_interface_callback();
+            break;
+        case GI_INFO_TYPE_ENUM:
+            arg_cache = _arg_cache_new_for_in_interface_enum();
+            break;
+        case GI_INFO_TYPE_FLAGS:
+            arg_cache = _arg_cache_new_for_in_interface_flags();
+            break;
+        default:
+            g_assert_not_reached();
+    }
+
+    if (arg_cache != NULL) {
+        arg_cache->direction = direction;
+        arg_cache->transfer = transfer;
+        arg_cache->type_tag = GI_TYPE_TAG_INTERFACE;
+        arg_cache->py_arg_index = py_arg_index;
+        arg_cache->c_arg_index = c_arg_index;
+    }
+}
+
+
 PyGIArgCache *
 _arg_cache_in_new_from_type_info (GITypeInfo *type_info,
                                   PyGIFunctionCache *function_cache,
@@ -420,8 +529,20 @@ _arg_cache_in_new_from_type_info (GITypeInfo *type_info,
                                                    transfer);
            break;
        case GI_TYPE_TAG_INTERFACE:
-           arg_cache = _arg_cache_new_for_in_interface();
-           break;
+           {
+               GIInterfaceInfo *interface_info = g_type_info_get_interface(type_info);
+               GIInfoType info_type = g_base_info_get_type( (GIBaseInfo *) interface_info);
+               arg_cache = _arg_cache_in_new_from_interface_info(interface_info,
+                                                                 function_cache,
+                                                                 info_type,
+                                                                 transfer,
+                                                                 direction,
+                                                                 c_arg_index,
+                                                                 py_arg_index);
+
+               g_base_info_unref( (GIBaseInfo *) interface_info);
+               return arg_cache;
+           }
        case GI_TYPE_TAG_GLIST:
            arg_cache = _arg_cache_new_for_in_glist(type_info,
                                                    transfer);
@@ -453,8 +574,37 @@ static inline gboolean
 _args_cache_generate(GIFunctionInfo *function_info,
                      PyGIFunctionCache *function_cache)
 {
-    int arg_index;
-    for (arg_index = 0; arg_index < function_cache->n_args; arg_index++) {
+    int arg_index = 0;
+    /* first arg is the instance */
+    if (function_cache->is_method) {
+        GIInterfaceInfo *interface_info;
+        PyGIArgCache *instance_cache;
+        GIInfoType info_type;
+
+        interface_info = g_base_info_get_container ( (GIBaseInfo *) function_info);
+        info_type = g_base_info_get_type(interface_info);
+
+        instance_cache =
+            _arg_cache_in_new_from_interface_info(interface_info,
+                                                  function_cache,
+                                                  info_type,
+                                                  GI_TRANSFER_NOTHING,
+                                                  GI_DIRECTION_IN,
+                                                  arg_index,
+                                                  0);
+
+        g_base_info_unref( (GIBaseInfo *) interface_info);
+
+        if (instance_cache == NULL)
+            return FALSE;
+
+        function_cache->args_cache[arg_index] = instance_cache;
+        
+        arg_index++;
+        function_cache->n_in_args++;
+    }
+
+    for (arg_index; arg_index < function_cache->n_args; arg_index++) {
         PyGIArgCache *arg_cache = NULL;
         GIArgInfo *arg_info;
         GITypeInfo *type_info;
diff --git a/gi/pygi-cache.h b/gi/pygi-cache.h
index 7d7aa89..00780db 100644
--- a/gi/pygi-cache.h
+++ b/gi/pygi-cache.h
@@ -39,7 +39,6 @@ typedef gboolean (*PyGIMarshalInFunc) (PyGIInvokeState   *state,
                                        GIArgument        *arg);
 
 typedef gboolean (*PyGIMarshalOutFunc) (void);
-typedef gboolean (*PyGIArgCleanupFunc) (gpointer data);
 
 struct _PyGIArgCache
 {
diff --git a/gi/pygi-invoke.c b/gi/pygi-invoke.c
index 64a4cf9..947d55a 100644
--- a/gi/pygi-invoke.c
+++ b/gi/pygi-invoke.c
@@ -1011,6 +1011,7 @@ _wrap_g_function_info_invoke (PyGIBaseInfo *self, PyObject *py_args)
         if (self->cache == NULL)
             return NULL;
     }
+
     _invoke_state_init_from_function_cache(&state, self->cache, py_args);
     if (!_invoke_marshal_in_args (&state, self->cache))
         goto err;



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