[gjs/ewlsh/gvalue-arguments] gi: Allow GObject.Value boxed type in nested contexts
- From: Evan Welsh <ewlsh src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gjs/ewlsh/gvalue-arguments] gi: Allow GObject.Value boxed type in nested contexts
- Date: Sat, 15 Jan 2022 19:37:40 +0000 (UTC)
commit 1980ebd44adb88918c9b61c640cfb5a3e56bd542
Author: Evan Welsh <contact evanwelsh com>
Date: Sat Jan 15 11:36:59 2022 -0800
gi: Allow GObject.Value boxed type in nested contexts
Previously we only handled this conversion in the arg cache. This
enables passing GObject.Value in arrays and other nested
structures.
gi/value.cpp | 41 +++++++++++++++++++++++++++++++++
installed-tests/js/testGIMarshalling.js | 16 +++++++++++++
2 files changed, 57 insertions(+)
---
diff --git a/gi/value.cpp b/gi/value.cpp
index af1f6702..d9e0bc5d 100644
--- a/gi/value.cpp
+++ b/gi/value.cpp
@@ -360,6 +360,47 @@ gjs_value_to_g_value_internal(JSContext *context,
gtype = G_VALUE_TYPE(gvalue);
+ if (value.isObject()) {
+ JS::RootedObject obj(context, &value.toObject());
+ GType boxed_gtype;
+
+ if (!gjs_gtype_get_actual_gtype(context, obj, &boxed_gtype))
+ return false;
+
+ // Don't unbox GValue if the GValue's gtype is GObject.Value
+ if (g_type_is_a(boxed_gtype, G_TYPE_VALUE) && gtype != G_TYPE_VALUE) {
+ if (no_copy) {
+ gjs_throw(
+ context,
+ "Cannot convert GObject.Value object without copying.");
+ return false;
+ }
+
+ GValue* source = BoxedBase::to_c_ptr<GValue>(context, obj);
+ // Only initialize the value if it doesn't have a type
+ // and our source GValue has been initialized
+ GType source_gtype = G_VALUE_TYPE(source);
+ if (gtype == 0) {
+ if (source_gtype == 0) {
+ gjs_throw(context,
+ "GObject.Value is not initialized with a type");
+ return false;
+ }
+ g_value_init(gvalue, source_gtype);
+ }
+
+ GType dest_gtype = G_VALUE_TYPE(gvalue);
+ if (!g_value_type_compatible(source_gtype, dest_gtype)) {
+ gjs_throw(context, "GObject.Value expected GType %s, found %s",
+ g_type_name(dest_gtype), g_type_name(source_gtype));
+ return false;
+ }
+
+ g_value_copy(source, gvalue);
+ return true;
+ }
+ }
+
if (gtype == 0) {
if (!gjs_value_guess_g_type(context, value, >ype))
return false;
diff --git a/installed-tests/js/testGIMarshalling.js b/installed-tests/js/testGIMarshalling.js
index 7d524919..22e1b973 100644
--- a/installed-tests/js/testGIMarshalling.js
+++ b/installed-tests/js/testGIMarshalling.js
@@ -814,6 +814,22 @@ describe('GValue', function () {
.not.toThrow();
});
+ it('array of boxed type GValues can be passed into a function', function () {
+ const value0 = new GObject.Value();
+ value0.init(GObject.TYPE_INT);
+ value0.set_int(42);
+ const value1 = new GObject.Value();
+ value1.init(String);
+ value1.set_string('42');
+ const value2 = new GObject.Value();
+ value2.init(Boolean);
+ value2.set_boolean(true);
+
+ const values = [value0, value1, value2];
+ expect(() => GIMarshallingTests.gvalue_flat_array(values))
+ .not.toThrow();
+ });
+
it('array can be passed as an out argument and unpacked', function () {
expect(GIMarshallingTests.return_gvalue_flat_array())
.toEqual([42, '42', true]);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]