[gjs] object: Use AutoGValueVector to build a list of GValue signal arguments



commit ed1cdae2edaeb0c880d643c60693029bd13b0ed4
Author: Marco Trevisan (TreviƱo) <mail 3v1n0 net>
Date:   Fri May 14 18:15:10 2021 +0200

    object: Use AutoGValueVector to build a list of GValue signal arguments
    
    We can handle the cleanups better and as bonus point we avoid allocating
    the return gvalue when not needed.

 gi/object.cpp | 58 +++++++++++++++++++++-------------------------------------
 1 file changed, 21 insertions(+), 37 deletions(-)
---
diff --git a/gi/object.cpp b/gi/object.cpp
index 5eeb651a..12fe6e8d 100644
--- a/gi/object.cpp
+++ b/gi/object.cpp
@@ -2054,9 +2054,7 @@ ObjectInstance::emit_impl(JSContext          *context,
     guint signal_id;
     GQuark signal_detail;
     GSignalQuery signal_query;
-    GValue rvalue = G_VALUE_INIT;
     unsigned int i;
-    bool failed;
 
     gjs_debug_gsignal("emit obj %p priv %p argc %d", m_wrapper.get(), this,
                       argv.length());
@@ -2091,49 +2089,35 @@ ObjectInstance::emit_impl(JSContext          *context,
         return false;
     }
 
-    if (signal_query.return_type != G_TYPE_NONE) {
-        g_value_init(&rvalue, signal_query.return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE);
-    }
-
-    GjsAutoPointer<GValue> instance_and_args =
-        g_new0(GValue, signal_query.n_params + 1);
-    g_value_init(&instance_and_args[0], gtype());
-    g_value_set_instance(&instance_and_args[0], m_ptr);
+    AutoGValueVector instance_and_args;
+    instance_and_args.reserve(signal_query.n_params + 1);
+    Gjs::AutoGValue& instance = instance_and_args.emplace_back(gtype());
+    g_value_set_instance(&instance, m_ptr);
 
-    failed = false;
     for (i = 0; i < signal_query.n_params; ++i) {
-        GValue *value;
-        value = &instance_and_args[i + 1];
-
-        g_value_init(value, signal_query.param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE);
-        if ((signal_query.param_types[i] & G_SIGNAL_TYPE_STATIC_SCOPE) != 0)
-            failed = !gjs_value_to_g_value_no_copy(context, argv[i + 1], value);
-        else
-            failed = !gjs_value_to_g_value(context, argv[i + 1], value);
-
-        if (failed)
-            break;
-    }
-
-    if (!failed) {
-        g_signal_emitv(instance_and_args, signal_id, signal_detail,
-                       &rvalue);
+        GType gtype = signal_query.param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE;
+        Gjs::AutoGValue& value = instance_and_args.emplace_back(gtype);
+        if ((signal_query.param_types[i] & G_SIGNAL_TYPE_STATIC_SCOPE) != 0) {
+            if (!gjs_value_to_g_value_no_copy(context, argv[i + 1], &value))
+                return false;
+        } else {
+            if (!gjs_value_to_g_value(context, argv[i + 1], &value))
+                return false;
+        }
     }
 
-    if (signal_query.return_type != G_TYPE_NONE) {
-        if (!gjs_value_from_g_value(context, argv.rval(), &rvalue))
-            failed = true;
-
-        g_value_unset(&rvalue);
-    } else {
+    if (signal_query.return_type == G_TYPE_NONE) {
+        g_signal_emitv(instance_and_args.data(), signal_id, signal_detail,
+                       nullptr);
         argv.rval().setUndefined();
+        return true;
     }
 
-    for (i = 0; i < (signal_query.n_params + 1); ++i) {
-        g_value_unset(&instance_and_args[i]);
-    }
+    GType gtype = signal_query.return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE;
+    Gjs::AutoGValue rvalue(gtype);
+    g_signal_emitv(instance_and_args.data(), signal_id, signal_detail, &rvalue);
 
-    return !failed;
+    return gjs_value_from_g_value(context, argv.rval(), &rvalue);
 }
 
 bool ObjectInstance::signal_match_arguments_from_object(


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