[gjs: 2/3] fundamental: Use value or instance pointer when no get/set funcs are provided
- From: Philip Chimento <pchimento src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gjs: 2/3] fundamental: Use value or instance pointer when no get/set funcs are provided
- Date: Thu, 8 Apr 2021 04:34:20 +0000 (UTC)
commit 696163987e19cf4f6263538915c41256ae08cad1
Author: Marco Trevisan (TreviƱo) <mail 3v1n0 net>
Date: Thu Apr 8 00:12:02 2021 +0200
fundamental: Use value or instance pointer when no get/set funcs are provided
Some fundamental types are providing value set/get functions however
this is not mandatory as the fundamental can be just retrieved from the
GValue pointer or we can build a GValue using the instance and gtype.
A case for this are Gdk4 Events that does not provide such functions,
making impossible to use events signals.
Add tests simulating this, depending on a new gobject-introspection type
that respects this constrain.
Fixes: #398
gi/fundamental.cpp | 13 ++++++++++++-
installed-tests/js/testFundamental.js | 26 ++++++++++++++++++++++++++
2 files changed, 38 insertions(+), 1 deletion(-)
---
diff --git a/gi/fundamental.cpp b/gi/fundamental.cpp
index a4d1e32c..0e83028c 100644
--- a/gi/fundamental.cpp
+++ b/gi/fundamental.cpp
@@ -443,6 +443,11 @@ JSObject* FundamentalInstance::object_for_gvalue(JSContext* cx,
auto* proto_priv = FundamentalPrototype::for_gtype(cx, gtype);
void* fobj;
if (!proto_priv->call_get_value_function(value, &fobj)) {
+ if (G_VALUE_HOLDS(value, gtype) && g_value_fits_pointer(value)) {
+ return FundamentalInstance::object_for_c_ptr(
+ cx, g_value_peek_pointer(value));
+ }
+
gjs_throw(cx, "Failed to convert GValue to a fundamental instance");
return nullptr;
}
@@ -457,7 +462,13 @@ bool FundamentalBase::to_gvalue(JSContext* cx, JS::HandleObject obj,
!priv->check_is_instance(cx, "convert to GValue"))
return false;
- if (!priv->to_instance()->set_value(gvalue)) {
+ auto* instance = priv->to_instance();
+ if (!instance->set_value(gvalue)) {
+ if (g_type_is_a(instance->gtype(), G_VALUE_TYPE(gvalue))) {
+ g_value_set_instance(gvalue, instance->m_ptr);
+ return true;
+ }
+
gjs_throw(cx,
"Fundamental object does not support conversion to a GValue");
return false;
diff --git a/installed-tests/js/testFundamental.js b/installed-tests/js/testFundamental.js
index 19b638a8..3274cf6c 100644
--- a/installed-tests/js/testFundamental.js
+++ b/installed-tests/js/testFundamental.js
@@ -7,6 +7,9 @@ const {GObject, Regress} = imports.gi;
const TestObj = GObject.registerClass({
Signals: {
'test-fundamental-value-funcs': {param_types: [Regress.TestFundamentalSubObject.$gtype]},
+ 'test-fundamental-no-funcs': {param_types:
+ Regress.TestFundamentalObjectNoGetSetFunc
+ ? [Regress.TestFundamentalObjectNoGetSetFunc.$gtype] : []},
},
}, class TestObj extends GObject.Object {});
@@ -21,4 +24,27 @@ describe('Fundamental type support', function () {
obj.emit('test-fundamental-value-funcs', fund);
expect(signalSpy).toHaveBeenCalledWith(obj, fund);
});
+
+ it('can marshal a custom fundamental type into a GValue if contains a pointer and does not provide
setter and getters', function () {
+ const fund = new Regress.TestFundamentalObjectNoGetSetFunc('foo');
+ expect(() => GObject.strdup_value_contents(fund)).not.toThrow();
+
+ const obj = new TestObj();
+ const signalSpy = jasmine.createSpy('signalSpy');
+ obj.connect('test-fundamental-no-funcs', signalSpy);
+ obj.connect('test-fundamental-no-funcs', (_o, f) =>
+ expect(f.get_data()).toBe('foo'));
+ obj.emit('test-fundamental-no-funcs', fund);
+ expect(signalSpy).toHaveBeenCalledWith(obj, fund);
+ }).pend('https://gitlab.gnome.org/GNOME/gobject-introspection/-/merge_requests/268');
+
+ it('cannot marshal a custom fundamental type into a GValue of different gtype', function () {
+ const fund = new Regress.TestFundamentalObjectNoGetSetFunc('foo');
+
+ const obj = new TestObj();
+ const signalSpy = jasmine.createSpy('signalSpy');
+ obj.connect('test-fundamental-value-funcs', signalSpy);
+ expect(() => obj.emit('test-fundamental-value-funcs', fund)).toThrowError(
+ /conversion to a GValue/);
+ }).pend('https://gitlab.gnome.org/GNOME/gobject-introspection/-/merge_requests/268');
});
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]