[gjs/wip/carlosg/arrays-in-signals] WIP: [RFC] value: Introspect element-type in arrays
- From: Carlos Garnacho <carlosg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gjs/wip/carlosg/arrays-in-signals] WIP: [RFC] value: Introspect element-type in arrays
- Date: Mon, 15 Feb 2021 23:13:45 +0000 (UTC)
commit 98bc0c0f63f280cea8fe9fe4e47abbd72f663088
Author: Carlos Garnacho <carlosg gnome org>
Date: Mon Feb 15 23:51:53 2021 +0100
WIP: [RFC] value: Introspect element-type in arrays
A few things have to combine ATM here:
- Of all compound types, it has to be an array
- Of all element-types it has to be a struct/union/boxed
It will succeed then, fail otherwise.
Fixes: https://gitlab.gnome.org/GNOME/gjs/-/issues/377
gi/value.cpp | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 56 insertions(+)
---
diff --git a/gi/value.cpp b/gi/value.cpp
index 26a679f3..44d1b110 100644
--- a/gi/value.cpp
+++ b/gi/value.cpp
@@ -11,6 +11,7 @@
#include <glib-object.h>
#include <glib.h>
+#include <js/Array.h>
#include <js/CharacterEncoding.h>
#include <js/Conversions.h>
#include <js/GCVector.h> // for RootedVector
@@ -840,6 +841,61 @@ gjs_value_from_g_value_internal(JSContext *context,
gjs_throw(context, "Failed to convert strv to array");
return false;
}
+ } else if (g_type_is_a(gtype, G_TYPE_PTR_ARRAY)) {
+ GIArgInfo *arg_info;
+ GISignalInfo *signal_info;
+ GITypeInfo type_info;
+
+ signal_info = get_signal_info_if_available(signal_query);
+ if (!signal_info) {
+ gjs_throw(context, "Unknown signal.");
+ return false;
+ }
+
+ /* Look for element-type */
+ arg_info = g_callable_info_get_arg(signal_info, arg_n - 1);
+ g_arg_info_load_type(arg_info, &type_info);
+
+ GITypeInfo *element_info = g_type_info_get_param_type (&type_info, 0);
+ GjsAutoBaseInfo interface_info =
+ g_type_info_get_interface(element_info);
+ GType gtype;
+
+ guint i;
+ JS::RootedValueVector elems(context);
+ GPtrArray *ptr_array = (GPtrArray*) g_value_get_boxed (gvalue);
+
+ for (i = 0; i < ptr_array->len; i++) {
+ if (!elems.growBy(1)) {
+ JS_ReportOutOfMemory(context);
+ return false;
+ }
+
+ gtype = g_registered_type_info_get_g_type(interface_info);
+
+ if (g_base_info_get_type(interface_info) == GI_INFO_TYPE_STRUCT ||
+ g_base_info_get_type(interface_info) == GI_INFO_TYPE_UNION ||
+ g_base_info_get_type(interface_info) == GI_INFO_TYPE_BOXED) {
+ GjsAutoBaseInfo info = g_irepository_find_by_gtype(nullptr, gtype);
+ JSObject *obj;
+
+ obj = BoxedInstance::new_for_c_struct(context, info, g_ptr_array_index (ptr_array, i));
+ if (!obj)
+ return false;
+ elems[i].setObject(*obj);
+ } else {
+ gjs_throw(context,
+ "Unable to introspect non-boxed array");
+ return false;
+ }
+ }
+
+ JS::RootedObject obj(context, JS::NewArrayObject(context, elems));
+ if (!obj)
+ return false;
+
+ value_p.setObject(*obj);
+ return true;
} else if (g_type_is_a(gtype, G_TYPE_HASH_TABLE) ||
g_type_is_a(gtype, G_TYPE_ARRAY) ||
g_type_is_a(gtype, G_TYPE_BYTE_ARRAY) ||
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]