gobject-introspection 3.4.0 → 3.4.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/ext/gobject-introspection/extconf.rb +1 -4
- data/ext/gobject-introspection/rb-gi-argument.c +10 -3
- data/ext/gobject-introspection/rb-gi-arguments-in.c +82 -122
- data/ext/gobject-introspection/rb-gi-arguments-out.c +31 -11
- data/ext/gobject-introspection/rb-gi-arguments.c +217 -18
- data/ext/gobject-introspection/rb-gi-base-info.c +11 -1
- data/ext/gobject-introspection/rb-gi-callable-info.c +10 -2
- data/ext/gobject-introspection/rb-gi-callback.c +156 -2
- data/ext/gobject-introspection/rb-gi-conversions.h +6 -6
- data/ext/gobject-introspection/rb-gi-interface-info.c +1 -7
- data/ext/gobject-introspection/rb-gi-loader.c +58 -10
- data/ext/gobject-introspection/rb-gi-object-info.c +11 -1
- data/ext/gobject-introspection/rb-gi-private-arguments-in.h +3 -1
- data/ext/gobject-introspection/rb-gi-private-arguments.h +6 -2
- data/ext/gobject-introspection/rb-gi-private-callback.h +6 -3
- data/ext/gobject-introspection/rb-gi-private.h +1 -0
- data/ext/gobject-introspection/rb-gi-repository.c +1 -1
- data/ext/gobject-introspection/rb-gi-struct-info.c +15 -3
- data/ext/gobject-introspection/rb-gi-vfunc-info.c +2 -2
- data/ext/gobject-introspection/rb-gobject-introspection.c +231 -0
- data/lib/gobject-introspection/loader.rb +66 -2
- data/lib/gobject-introspection/type-tag.rb +2 -0
- data/test/gobject-introspection-test-utils.rb +2 -2
- data/test/run-test.rb +18 -25
- data/test/test-base-info.rb +5 -1
- data/test/test-callable-info.rb +16 -2
- data/test/test-loader.rb +53 -7
- data/test/test-object-info.rb +5 -1
- data/test/test-struct-info.rb +6 -1
- metadata +5 -8
- data/ext/gobject-introspection/gobject-introspection-enum-types.c +0 -230
- data/ext/gobject-introspection/gobject-introspection-enum-types.h +0 -42
- data/ext/gobject-introspection/rbgiversion.h +0 -24
@@ -1,6 +1,6 @@
|
|
1
1
|
/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
|
2
2
|
/*
|
3
|
-
* Copyright (C) 2019 Ruby-GNOME Project Team
|
3
|
+
* Copyright (C) 2019-2021 Ruby-GNOME Project Team
|
4
4
|
*
|
5
5
|
* This library is free software; you can redistribute it and/or
|
6
6
|
* modify it under the terms of the GNU Lesser General Public
|
@@ -20,6 +20,8 @@
|
|
20
20
|
|
21
21
|
#pragma once
|
22
22
|
|
23
|
+
G_GNUC_INTERNAL VALUE
|
24
|
+
rb_gi_arguments_in_to_ruby(RBGIArguments *args);
|
23
25
|
G_GNUC_INTERNAL void
|
24
26
|
rb_gi_arguments_in_init(RBGIArguments *args);
|
25
27
|
G_GNUC_INTERNAL void
|
@@ -1,6 +1,6 @@
|
|
1
1
|
/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
|
2
2
|
/*
|
3
|
-
* Copyright (C) 2019 Ruby-GNOME Project Team
|
3
|
+
* Copyright (C) 2019-2021 Ruby-GNOME Project Team
|
4
4
|
*
|
5
5
|
* This library is free software; you can redistribute it and/or
|
6
6
|
* modify it under the terms of the GNU Lesser General Public
|
@@ -40,6 +40,7 @@ typedef void (*RBGIArgFreeFunc)(RBGIArguments *args,
|
|
40
40
|
|
41
41
|
typedef struct {
|
42
42
|
GITypeInfo *info;
|
43
|
+
gboolean pointer_p;
|
43
44
|
GITypeTag tag;
|
44
45
|
GIBaseInfo *interface_info;
|
45
46
|
GIInfoType interface_type;
|
@@ -64,7 +65,6 @@ struct RBGIArgMetadata_ {
|
|
64
65
|
gboolean array_length_p;
|
65
66
|
gboolean interface_p;
|
66
67
|
gboolean may_be_null_p;
|
67
|
-
gboolean pointer_p;
|
68
68
|
gboolean caller_allocates_p;
|
69
69
|
gboolean zero_terminated_p;
|
70
70
|
gboolean output_buffer_p;
|
@@ -101,6 +101,10 @@ G_GNUC_INTERNAL VALUE
|
|
101
101
|
rb_gi_arguments_get_rb_return_value(RBGIArguments *args,
|
102
102
|
GIArgument *return_value);
|
103
103
|
|
104
|
+
G_GNUC_INTERNAL void
|
105
|
+
rb_gi_arguments_fill_raw_out_gerror(RBGIArguments *args,
|
106
|
+
VALUE rb_error);
|
107
|
+
|
104
108
|
G_GNUC_INTERNAL void
|
105
109
|
rb_gi_arguments_fill_raw_results(RBGIArguments *args,
|
106
110
|
VALUE rb_results,
|
@@ -1,6 +1,6 @@
|
|
1
1
|
/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
|
2
2
|
/*
|
3
|
-
* Copyright (C) 2019 Ruby-GNOME Project Team
|
3
|
+
* Copyright (C) 2019-2021 Ruby-GNOME Project Team
|
4
4
|
*
|
5
5
|
* This library is free software; you can redistribute it and/or
|
6
6
|
* modify it under the terms of the GNU Lesser General Public
|
@@ -22,8 +22,8 @@
|
|
22
22
|
|
23
23
|
typedef struct RBGICallback_ {
|
24
24
|
GIArgInfo *arg_info;
|
25
|
-
GITypeInfo *type_info;
|
26
25
|
GICallbackInfo *callback_info;
|
26
|
+
gchar *method_name;
|
27
27
|
ffi_cif cif;
|
28
28
|
ffi_closure *closure;
|
29
29
|
} RBGICallback;
|
@@ -34,8 +34,11 @@ rb_gi_callback_init(VALUE rb_mGI);
|
|
34
34
|
G_GNUC_INTERNAL gpointer
|
35
35
|
rb_gi_callback_find(GIArgInfo *info);
|
36
36
|
|
37
|
+
G_GNUC_INTERNAL RBGICallback *
|
38
|
+
rb_gi_callback_new(GICallbackInfo *callback_info,
|
39
|
+
const gchar *method_name);
|
40
|
+
|
37
41
|
G_GNUC_INTERNAL RBGICallbackData *
|
38
42
|
rb_gi_callback_data_new(RBGIArguments *args,
|
39
43
|
RBGICallback *callback,
|
40
44
|
RBGIArgMetadata *metadata);
|
41
|
-
|
@@ -228,7 +228,7 @@ rg_find(int argc, VALUE *argv, VALUE self)
|
|
228
228
|
VALUE rb_gtype;
|
229
229
|
GType gtype;
|
230
230
|
rb_gtype = argv[0];
|
231
|
-
gtype =
|
231
|
+
gtype = rbgobj_gtype_from_ruby(rb_gtype);
|
232
232
|
info = g_irepository_find_by_gtype(SELF(self), gtype);
|
233
233
|
} else {
|
234
234
|
VALUE rb_namespace, rb_name;
|
@@ -1,6 +1,6 @@
|
|
1
1
|
/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
|
2
2
|
/*
|
3
|
-
* Copyright (C) 2012-
|
3
|
+
* Copyright (C) 2012-2021 Ruby-GNOME Project Team
|
4
4
|
*
|
5
5
|
* This library is free software; you can redistribute it and/or
|
6
6
|
* modify it under the terms of the GNU Lesser General Public
|
@@ -84,7 +84,7 @@ rb_gi_struct_get_raw(VALUE rb_struct, GType gtype)
|
|
84
84
|
if (rb_respond_to(rb_struct_class, rb_intern("gtype"))) {
|
85
85
|
VALUE rb_gtype;
|
86
86
|
rb_gtype = rb_funcall(rb_struct_class, rb_intern("gtype"), 0);
|
87
|
-
gtype =
|
87
|
+
gtype = rbgobj_gtype_from_ruby(rb_gtype);
|
88
88
|
}
|
89
89
|
}
|
90
90
|
if (gtype == G_TYPE_NONE) {
|
@@ -146,7 +146,7 @@ rb_gi_struct_info_to_ruby(GIStructInfo *info,
|
|
146
146
|
GType gtype;
|
147
147
|
|
148
148
|
rb_gtype = rb_funcall(rb_class, rb_intern("gtype"), 0);
|
149
|
-
gtype =
|
149
|
+
gtype = rbgobj_gtype_from_ruby(rb_gtype);
|
150
150
|
return BOXED2RVAL(object, gtype);
|
151
151
|
}
|
152
152
|
|
@@ -194,6 +194,17 @@ rg_get_field(VALUE self, VALUE rb_n)
|
|
194
194
|
return GI_BASE_INFO2RVAL_WITH_UNREF(g_struct_info_get_field(info, n));
|
195
195
|
}
|
196
196
|
|
197
|
+
static VALUE
|
198
|
+
rg_find_field(VALUE self, VALUE rb_name)
|
199
|
+
{
|
200
|
+
GIStructInfo *info;
|
201
|
+
const gchar *name;
|
202
|
+
|
203
|
+
info = SELF(self);
|
204
|
+
name = RVAL2CSTR(rb_name);
|
205
|
+
return GI_BASE_INFO2RVAL_WITH_UNREF(g_struct_info_find_field(info, name));
|
206
|
+
}
|
207
|
+
|
197
208
|
static VALUE
|
198
209
|
rg_get_field_value(VALUE self, VALUE rb_struct, VALUE rb_n)
|
199
210
|
{
|
@@ -308,6 +319,7 @@ rb_gi_struct_info_init(VALUE rb_mGI, VALUE rb_cGIRegisteredTypeInfo)
|
|
308
319
|
|
309
320
|
RG_DEF_METHOD(n_fields, 0);
|
310
321
|
RG_DEF_METHOD(get_field, 1);
|
322
|
+
RG_DEF_METHOD(find_field, 1);
|
311
323
|
RG_DEF_METHOD(get_field_value, 2);
|
312
324
|
RG_DEF_METHOD(set_field_value, 3);
|
313
325
|
RG_DEF_METHOD(n_methods, 0);
|
@@ -1,6 +1,6 @@
|
|
1
1
|
/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
|
2
2
|
/*
|
3
|
-
* Copyright (C) 2012 Ruby-
|
3
|
+
* Copyright (C) 2012-2021 Ruby-GNOME Project Team
|
4
4
|
*
|
5
5
|
* This library is free software; you can redistribute it and/or
|
6
6
|
* modify it under the terms of the GNU Lesser General Public
|
@@ -21,7 +21,7 @@
|
|
21
21
|
#include "rb-gi-private.h"
|
22
22
|
|
23
23
|
#define RG_TARGET_NAMESPACE rb_cGIVFuncInfo
|
24
|
-
#define SELF(self)
|
24
|
+
#define SELF(self) RVAL2GI_VFUNC_INFO(self)
|
25
25
|
|
26
26
|
GType
|
27
27
|
gi_vfunc_info_get_type(void)
|
@@ -22,6 +22,15 @@
|
|
22
22
|
|
23
23
|
#define RG_TARGET_NAMESPACE rb_mGObjectIntrospection
|
24
24
|
|
25
|
+
typedef struct {
|
26
|
+
ID name;
|
27
|
+
GICallableInfo *callable_info;
|
28
|
+
|
29
|
+
ffi_cif cif;
|
30
|
+
ffi_closure *closure;
|
31
|
+
} RBGIVFuncCallbackData;
|
32
|
+
|
33
|
+
static ID id_send;
|
25
34
|
static gboolean is_debug_mode = FALSE;
|
26
35
|
|
27
36
|
gboolean
|
@@ -30,11 +39,231 @@ rb_gi_is_debug_mode(void)
|
|
30
39
|
return is_debug_mode;
|
31
40
|
}
|
32
41
|
|
42
|
+
static void
|
43
|
+
find_vfunc_info (GIBaseInfo *vfunc_info,
|
44
|
+
GType implementor_gtype,
|
45
|
+
gpointer *implementor_vtable_ret,
|
46
|
+
GIFieldInfo **field_info_ret)
|
47
|
+
{
|
48
|
+
GIBaseInfo *ancestor_info = NULL;
|
49
|
+
GIStructInfo *struct_info = NULL;
|
50
|
+
GIFieldInfo *field_info = NULL;
|
51
|
+
|
52
|
+
ancestor_info = g_base_info_get_container(vfunc_info);
|
53
|
+
// ancestor_gtype = g_registered_type_info_get_g_type (
|
54
|
+
// (GIRegisteredTypeInfo *) ancestor_info);
|
55
|
+
struct_info = g_object_info_get_class_struct((GIObjectInfo*) ancestor_info);
|
56
|
+
*implementor_vtable_ret = g_type_class_ref(implementor_gtype);
|
57
|
+
|
58
|
+
field_info = g_struct_info_find_field(
|
59
|
+
struct_info, g_base_info_get_name((GIBaseInfo*) vfunc_info));
|
60
|
+
|
61
|
+
if (field_info != NULL) {
|
62
|
+
GITypeInfo *type_info;
|
63
|
+
|
64
|
+
type_info = g_field_info_get_type (field_info);
|
65
|
+
if (g_type_info_get_tag (type_info) == GI_TYPE_TAG_INTERFACE) {
|
66
|
+
*field_info_ret = field_info;
|
67
|
+
} else {
|
68
|
+
g_base_info_unref (field_info);
|
69
|
+
}
|
70
|
+
g_base_info_unref (type_info);
|
71
|
+
}
|
72
|
+
|
73
|
+
g_base_info_unref (struct_info);
|
74
|
+
}
|
75
|
+
|
76
|
+
static VALUE
|
77
|
+
garg2rval(GIArgument *argument, GITypeTag type_tag)
|
78
|
+
{
|
79
|
+
switch (type_tag) {
|
80
|
+
case GI_TYPE_TAG_INT32:
|
81
|
+
return INT2FIX(argument->v_int32);
|
82
|
+
default:
|
83
|
+
rb_raise(rb_eTypeError, "garg2rval: not implemented");
|
84
|
+
break;
|
85
|
+
}
|
86
|
+
}
|
87
|
+
|
88
|
+
static void
|
89
|
+
rval2garg(VALUE value, GITypeTag type_tag, GIArgument *argument)
|
90
|
+
{
|
91
|
+
switch (type_tag) {
|
92
|
+
case GI_TYPE_TAG_INT32:
|
93
|
+
argument->v_int32 = FIX2INT(value);
|
94
|
+
break;
|
95
|
+
default:
|
96
|
+
rb_raise(rb_eTypeError, "rval2garg: not implemented");
|
97
|
+
break;
|
98
|
+
}
|
99
|
+
}
|
100
|
+
|
101
|
+
static void
|
102
|
+
rval2ffiarg(VALUE value, ffi_arg *arg)
|
103
|
+
{
|
104
|
+
switch (TYPE(value)) {
|
105
|
+
case T_NIL:
|
106
|
+
break;
|
107
|
+
case T_FIXNUM:
|
108
|
+
case T_DATA:
|
109
|
+
*arg = FIX2INT(value);
|
110
|
+
break;
|
111
|
+
default:
|
112
|
+
rb_raise(rb_eTypeError, "rval2ffiarg: not implemented");
|
113
|
+
break;
|
114
|
+
}
|
115
|
+
}
|
116
|
+
|
117
|
+
static void
|
118
|
+
ffi_callback(G_GNUC_UNUSED ffi_cif *cif,
|
119
|
+
void *ret,
|
120
|
+
void **raw_args,
|
121
|
+
void *raw_data)
|
122
|
+
{
|
123
|
+
GIArgument **args = NULL;
|
124
|
+
RBGIVFuncCallbackData *data = NULL;
|
125
|
+
GObject* receiver = NULL;
|
126
|
+
VALUE rb_receiver = 0;
|
127
|
+
gint n_args = 0, n_in_args = 0, n_out_args = 0;
|
128
|
+
size_t i = 0, j = 0;
|
129
|
+
VALUE *in_values = NULL;
|
130
|
+
VALUE rb_ret;
|
131
|
+
GIArgInfo arg_info;
|
132
|
+
GITypeInfo type_info;
|
133
|
+
GITypeTag type_tag;
|
134
|
+
GIDirection direction;
|
135
|
+
gboolean ret_type_is_void;
|
136
|
+
|
137
|
+
args = (GIArgument **) raw_args;
|
138
|
+
data = (RBGIVFuncCallbackData *) raw_data;
|
139
|
+
|
140
|
+
receiver = G_OBJECT(args[0]->v_pointer);
|
141
|
+
rb_receiver = GOBJ2RVAL(receiver);
|
142
|
+
|
143
|
+
n_args = g_callable_info_get_n_args(data->callable_info);
|
144
|
+
in_values = (VALUE *) malloc(n_args * sizeof(VALUE));
|
145
|
+
in_values[0] = data->name;
|
146
|
+
n_in_args++;
|
147
|
+
|
148
|
+
for (i = 1, j = 1; i < n_args; i++) {
|
149
|
+
g_callable_info_load_arg(data->callable_info, i, &arg_info);
|
150
|
+
g_arg_info_load_type(&arg_info, &type_info);
|
151
|
+
type_tag = g_type_info_get_tag(&type_info);
|
152
|
+
direction = g_arg_info_get_direction(&arg_info);
|
153
|
+
|
154
|
+
if (type_tag == GI_TYPE_TAG_VOID) continue;
|
155
|
+
|
156
|
+
if (direction == GI_DIRECTION_OUT || direction == GI_DIRECTION_INOUT)
|
157
|
+
n_out_args++;
|
158
|
+
|
159
|
+
if (direction == GI_DIRECTION_OUT) continue;
|
160
|
+
|
161
|
+
in_values[j] = garg2rval(args[i], type_tag);
|
162
|
+
j++; n_in_args++;
|
163
|
+
}
|
164
|
+
|
165
|
+
// result = rb_funcall(rb_receiver, id_send, 1, data->name);
|
166
|
+
rb_ret = rb_funcallv(rb_receiver, id_send, n_in_args, in_values);
|
167
|
+
|
168
|
+
g_callable_info_load_return_type(data->callable_info, &type_info);
|
169
|
+
ret_type_is_void = g_type_info_get_tag(&type_info) == GI_TYPE_TAG_VOID;
|
170
|
+
|
171
|
+
if (n_out_args == 0 && ret_type_is_void) {
|
172
|
+
// do nothing
|
173
|
+
} else if (n_out_args == 0) {
|
174
|
+
rval2ffiarg(rb_ret, ret);
|
175
|
+
} else if (n_out_args == 1 && ret_type_is_void) {
|
176
|
+
for (i = 1; i < n_args; i++) {
|
177
|
+
g_callable_info_load_arg(data->callable_info, i, &arg_info);
|
178
|
+
g_arg_info_load_type(&arg_info, &type_info);
|
179
|
+
type_tag = g_type_info_get_tag(&type_info);
|
180
|
+
direction = g_arg_info_get_direction(&arg_info);
|
181
|
+
|
182
|
+
if (type_tag == GI_TYPE_TAG_VOID || direction == GI_DIRECTION_IN)
|
183
|
+
continue;
|
184
|
+
|
185
|
+
rval2garg(rb_ret, type_tag, *(GIArgument **) args[i]);
|
186
|
+
break;
|
187
|
+
}
|
188
|
+
} else {
|
189
|
+
if (TYPE(rb_ret) != T_ARRAY) {
|
190
|
+
rb_raise(rb_eTypeError, "return type should be Array");
|
191
|
+
}
|
192
|
+
|
193
|
+
for (i = 1, j = 0; i < n_args; i++) {
|
194
|
+
g_callable_info_load_arg(data->callable_info, i, &arg_info);
|
195
|
+
g_arg_info_load_type(&arg_info, &type_info);
|
196
|
+
type_tag = g_type_info_get_tag(&type_info);
|
197
|
+
direction = g_arg_info_get_direction(&arg_info);
|
198
|
+
|
199
|
+
if (type_tag == GI_TYPE_TAG_VOID || direction == GI_DIRECTION_IN)
|
200
|
+
continue;
|
201
|
+
|
202
|
+
rval2garg(rb_ary_entry(rb_ret, j), type_tag, *(GIArgument **) args[i]);
|
203
|
+
j++;
|
204
|
+
}
|
205
|
+
}
|
206
|
+
|
207
|
+
free(in_values);
|
208
|
+
}
|
209
|
+
|
210
|
+
static VALUE
|
211
|
+
rb_gi_hook_up_vfunc(G_GNUC_UNUSED VALUE self,
|
212
|
+
VALUE rb_name,
|
213
|
+
VALUE rb_vfunc_info,
|
214
|
+
VALUE rb_gtype)
|
215
|
+
{
|
216
|
+
GIVFuncInfo *vfunc_info = NULL;
|
217
|
+
GType gtype = 0;
|
218
|
+
gpointer implementor_vtable = NULL;
|
219
|
+
GIFieldInfo *field_info = NULL;
|
220
|
+
|
221
|
+
vfunc_info = RVAL2GI_BASE_INFO(rb_vfunc_info);
|
222
|
+
gtype = NUM2LONG(rb_gtype);
|
223
|
+
g_assert(G_TYPE_IS_CLASSED(gtype));
|
224
|
+
|
225
|
+
find_vfunc_info(vfunc_info, gtype, &implementor_vtable, &field_info);
|
226
|
+
|
227
|
+
if (field_info != NULL) {
|
228
|
+
GITypeInfo *type_info = NULL;
|
229
|
+
GIBaseInfo *interface_info = NULL;
|
230
|
+
RBGIVFuncCallbackData *data = NULL;
|
231
|
+
gint offset = 0;
|
232
|
+
gpointer *method_ptr = NULL;
|
233
|
+
|
234
|
+
type_info = g_field_info_get_type(field_info);
|
235
|
+
|
236
|
+
interface_info = g_type_info_get_interface(type_info);
|
237
|
+
g_assert(g_base_info_get_type(interface_info) == GI_INFO_TYPE_CALLBACK);
|
238
|
+
|
239
|
+
data = ALLOC(RBGIVFuncCallbackData);
|
240
|
+
data->name = rb_name;
|
241
|
+
data->callable_info = g_base_info_ref(interface_info);
|
242
|
+
data->closure = g_callable_info_prepare_closure(
|
243
|
+
interface_info, &(data->cif), ffi_callback, data);
|
244
|
+
|
245
|
+
if (data->closure) {
|
246
|
+
offset = g_field_info_get_offset(field_info);
|
247
|
+
method_ptr = G_STRUCT_MEMBER_P(implementor_vtable, offset);
|
248
|
+
|
249
|
+
*method_ptr = data->closure;
|
250
|
+
}
|
251
|
+
|
252
|
+
g_base_info_unref (interface_info);
|
253
|
+
g_base_info_unref (type_info);
|
254
|
+
g_base_info_unref (field_info);
|
255
|
+
}
|
256
|
+
|
257
|
+
return Qnil;
|
258
|
+
}
|
259
|
+
|
33
260
|
void
|
34
261
|
Init_gobject_introspection(void)
|
35
262
|
{
|
36
263
|
VALUE RG_TARGET_NAMESPACE;
|
37
264
|
|
265
|
+
id_send = rb_intern("__send__");
|
266
|
+
|
38
267
|
{
|
39
268
|
const char *rb_gi_debug_env = getenv("RB_GI_DEBUG");
|
40
269
|
if (rb_gi_debug_env && strcmp(rb_gi_debug_env, "yes") == 0) {
|
@@ -59,4 +288,6 @@ Init_gobject_introspection(void)
|
|
59
288
|
rb_gi_loader_init(RG_TARGET_NAMESPACE);
|
60
289
|
|
61
290
|
rb_gi_callback_init(RG_TARGET_NAMESPACE);
|
291
|
+
|
292
|
+
rb_define_module_function(RG_TARGET_NAMESPACE, "hook_up_vfunc", rb_gi_hook_up_vfunc, 3);
|
62
293
|
}
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (C) 2012-
|
1
|
+
# Copyright (C) 2012-2021 Ruby-GNOME Project Team
|
2
2
|
#
|
3
3
|
# This library is free software; you can redistribute it and/or
|
4
4
|
# modify it under the terms of the GNU Lesser General Public
|
@@ -216,6 +216,7 @@ module GObjectIntrospection
|
|
216
216
|
klass = self.class.define_class(info.gtype,
|
217
217
|
rubyish_class_name(info),
|
218
218
|
@base_module)
|
219
|
+
load_virtual_functions(info, klass)
|
219
220
|
load_fields(info, klass)
|
220
221
|
load_methods(info, klass)
|
221
222
|
end
|
@@ -338,6 +339,20 @@ module GObjectIntrospection
|
|
338
339
|
end
|
339
340
|
end
|
340
341
|
|
342
|
+
def load_virtual_functions(info, klass)
|
343
|
+
klass.extend(VirtualFunctionImplementable)
|
344
|
+
gtype_prefix = rubyish_gtype_name(klass.gtype.name)
|
345
|
+
implementor = VirtualFunctionImplementor.new(self.class,
|
346
|
+
gtype_prefix,
|
347
|
+
info.vfuncs)
|
348
|
+
klass.__send__(:initialize_virtual_function_implementable,
|
349
|
+
implementor)
|
350
|
+
end
|
351
|
+
|
352
|
+
def rubyish_gtype_name(name)
|
353
|
+
name.scan(/[A-Z]+[a-z\d]+/).collect(&:downcase).join("_")
|
354
|
+
end
|
355
|
+
|
341
356
|
def initialize_post(object)
|
342
357
|
end
|
343
358
|
|
@@ -546,6 +561,7 @@ module GObjectIntrospection
|
|
546
561
|
self.class.define_interface(info.gtype,
|
547
562
|
rubyish_class_name(info),
|
548
563
|
@base_module)
|
564
|
+
load_virtual_functions(info, interface_module)
|
549
565
|
load_methods(info, interface_module)
|
550
566
|
end
|
551
567
|
|
@@ -681,10 +697,10 @@ module GObjectIntrospection
|
|
681
697
|
def normalize_arguments!(arguments, abort_tag)
|
682
698
|
arguments.size.times do |i|
|
683
699
|
argument = arguments[i]
|
684
|
-
next if argument.nil?
|
685
700
|
type = @in_arg_types[i]
|
686
701
|
converted_argument = type.try_convert(argument)
|
687
702
|
if converted_argument.nil?
|
703
|
+
next if argument.nil?
|
688
704
|
if abort_tag
|
689
705
|
throw(abort_tag)
|
690
706
|
elsif @on_invalid == :fallback
|
@@ -708,5 +724,53 @@ module GObjectIntrospection
|
|
708
724
|
"#{@full_method_name}: wrong number of arguments (#{detail})"
|
709
725
|
end
|
710
726
|
end
|
727
|
+
|
728
|
+
class VirtualFunctionImplementor
|
729
|
+
def initialize(loader_class, gtype_prefix, infos)
|
730
|
+
@loader_class = loader_class
|
731
|
+
@gtype_prefix = gtype_prefix
|
732
|
+
@infos = {}
|
733
|
+
prefix = GLib::VIRTUAL_FUNCTION_IMPLEMENTATION_PREFIX
|
734
|
+
infos.each do |info|
|
735
|
+
name = info.name
|
736
|
+
@infos[:"#{prefix}#{name}"] = info
|
737
|
+
@infos[:"#{prefix}#{gtype_prefix}_#{name}"] = info
|
738
|
+
end
|
739
|
+
end
|
740
|
+
|
741
|
+
def implement(implementor_gtype, name)
|
742
|
+
info = @infos[name]
|
743
|
+
return false if info.nil?
|
744
|
+
container = info.container
|
745
|
+
vtable_gtype = container.gtype
|
746
|
+
if container.respond_to?(:class_struct)
|
747
|
+
struct = container.class_struct
|
748
|
+
else
|
749
|
+
return false unless implementor_gtype.type_is_a?(vtable_gtype)
|
750
|
+
struct = container.iface_struct
|
751
|
+
end
|
752
|
+
field = struct.find_field(info.name)
|
753
|
+
@loader_class.implement_virtual_function(field,
|
754
|
+
implementor_gtype,
|
755
|
+
vtable_gtype,
|
756
|
+
name.to_s)
|
757
|
+
true
|
758
|
+
end
|
759
|
+
end
|
760
|
+
|
761
|
+
module VirtualFunctionImplementable
|
762
|
+
def initialize_virtual_function_implementable(implementor)
|
763
|
+
@virtual_function_implementor = implementor
|
764
|
+
end
|
765
|
+
|
766
|
+
def implement_virtual_function(implementor_class, name)
|
767
|
+
unless instance_variable_defined?(:@virtual_function_implementor)
|
768
|
+
return false
|
769
|
+
end
|
770
|
+
@virtual_function_implementor.implement(implementor_class.gtype,
|
771
|
+
name)
|
772
|
+
true
|
773
|
+
end
|
774
|
+
end
|
711
775
|
end
|
712
776
|
end
|