gir_ffi 0.10.2 → 0.11.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Changelog.md +13 -0
- data/Gemfile +9 -4
- data/README.md +3 -2
- data/Rakefile +2 -1
- data/lib/ffi-glib/byte_array.rb +1 -1
- data/lib/ffi-glib/main_loop.rb +2 -1
- data/lib/ffi-glib/strv.rb +5 -2
- data/lib/ffi-glib/variant.rb +3 -5
- data/lib/ffi-glib.rb +4 -0
- data/lib/ffi-gobject/closure.rb +8 -10
- data/lib/ffi-gobject/object.rb +9 -6
- data/lib/ffi-gobject/param_spec.rb +4 -0
- data/lib/ffi-gobject/value.rb +13 -16
- data/lib/ffi-gobject_introspection/gobject_type_init.rb +18 -0
- data/lib/ffi-gobject_introspection/i_callable_info.rb +1 -5
- data/lib/ffi-gobject_introspection/i_constant_info.rb +3 -3
- data/lib/ffi-gobject_introspection/i_repository.rb +3 -47
- data/lib/ffi-gobject_introspection/i_vfunc_info.rb +3 -11
- data/lib/ffi-gobject_introspection/lib.rb +8 -31
- data/lib/{gir_ffi-base/glib → ffi-gobject_introspection}/strv.rb +9 -13
- data/lib/ffi-gobject_introspection.rb +47 -2
- data/lib/gir_ffi/allocation_helper.rb +1 -19
- data/lib/gir_ffi/arg_helper.rb +36 -26
- data/lib/{gir_ffi-base/glib → gir_ffi}/boolean.rb +7 -5
- data/lib/gir_ffi/boxed_base.rb +5 -23
- data/lib/gir_ffi/builder.rb +3 -3
- data/lib/gir_ffi/builders/argument_builder.rb +7 -8
- data/lib/gir_ffi/builders/base_argument_builder.rb +0 -1
- data/lib/gir_ffi/builders/callback_argument_builder.rb +2 -2
- data/lib/gir_ffi/builders/callback_return_value_builder.rb +21 -13
- data/lib/gir_ffi/builders/field_builder.rb +4 -10
- data/lib/gir_ffi/builders/module_builder.rb +6 -4
- data/lib/gir_ffi/builders/object_builder.rb +16 -16
- data/lib/gir_ffi/builders/struct_builder.rb +4 -6
- data/lib/gir_ffi/builders/struct_like.rb +1 -1
- data/lib/gir_ffi/builders/user_defined_builder.rb +83 -23
- data/lib/gir_ffi/builders/vfunc_argument_builder.rb +12 -17
- data/lib/gir_ffi/class_base.rb +0 -4
- data/lib/gir_ffi/core.rb +16 -13
- data/lib/gir_ffi/enum_base.rb +2 -41
- data/lib/gir_ffi/enum_like_base.rb +48 -0
- data/lib/gir_ffi/ffi_ext/pointer.rb +1 -1
- data/lib/gir_ffi/flags_base.rb +2 -41
- data/lib/gir_ffi/in_out_pointer.rb +1 -1
- data/lib/gir_ffi/in_pointer.rb +4 -4
- data/lib/gir_ffi/info_ext/i_type_info.rb +14 -5
- data/lib/gir_ffi/info_ext/i_vfunc_info.rb +8 -0
- data/lib/gir_ffi/module_base.rb +4 -0
- data/lib/gir_ffi/receiver_argument_info.rb +1 -1
- data/lib/gir_ffi/sized_array.rb +6 -6
- data/lib/gir_ffi/struct_base.rb +1 -6
- data/lib/gir_ffi/struct_like_base.rb +54 -45
- data/lib/gir_ffi/type_map.rb +6 -7
- data/lib/gir_ffi/union_base.rb +1 -1
- data/lib/gir_ffi/{user_defined_type_info.rb → user_defined_object_info.rb} +1 -2
- data/lib/gir_ffi/user_defined_property_info.rb +80 -2
- data/lib/gir_ffi/version.rb +1 -1
- data/lib/gir_ffi-base/gobject/lib.rb +0 -1
- data/lib/gir_ffi-base/gobject.rb +3 -5
- data/lib/gir_ffi-base.rb +3 -8
- data/tasks/test.rake +17 -3
- data/test/base_test_helper.rb +39 -23
- data/test/ffi-glib/closure_test.rb +37 -0
- data/test/ffi-glib/main_loop_test.rb +24 -0
- data/test/ffi-glib/ruby_closure_test.rb +0 -5
- data/test/ffi-gobject/object_test.rb +6 -10
- data/test/ffi-gobject/param_spec_test.rb +17 -5
- data/test/ffi-gobject/value_test.rb +15 -6
- data/test/ffi-gobject_introspection/gobject_type_init_test.rb +25 -0
- data/test/ffi-gobject_introspection/i_base_info_test.rb +1 -1
- data/test/ffi-gobject_introspection/i_repository_test.rb +18 -0
- data/test/ffi-gobject_introspection/i_vfunc_info_test.rb +40 -0
- data/test/{gir_ffi-base/glib → ffi-gobject_introspection}/strv_test.rb +8 -8
- data/test/gir_ffi/allocation_helper_test.rb +35 -0
- data/test/gir_ffi/arg_helper_test.rb +102 -7
- data/test/gir_ffi/boolean_test.rb +34 -0
- data/test/gir_ffi/boxed_base_test.rb +46 -6
- data/test/gir_ffi/builder_test.rb +88 -29
- data/test/gir_ffi/builders/argument_builder_test.rb +19 -0
- data/test/gir_ffi/builders/callback_argument_builder_test.rb +17 -0
- data/test/gir_ffi/builders/callback_return_value_builder_test.rb +1 -1
- data/test/gir_ffi/builders/field_builder_test.rb +2 -1
- data/test/gir_ffi/builders/struct_builder_test.rb +42 -25
- data/test/gir_ffi/builders/user_defined_builder_test.rb +365 -17
- data/test/gir_ffi/builders/vfunc_argument_builder_test.rb +100 -0
- data/test/gir_ffi/builders/vfunc_builder_test.rb +5 -3
- data/test/{gir_ffi_test.rb → gir_ffi/core_test.rb} +8 -6
- data/test/gir_ffi/in_out_pointer_test.rb +1 -1
- data/test/gir_ffi/receiver_argument_info_test.rb +32 -0
- data/test/gir_ffi/sized_array_test.rb +34 -0
- data/test/gir_ffi/struct_base_test.rb +4 -32
- data/test/gir_ffi/struct_like_base_test.rb +164 -0
- data/test/gir_ffi/union_base_test.rb +4 -20
- data/test/gir_ffi/{user_defined_type_info_test.rb → user_defined_object_info_test.rb} +10 -10
- data/test/gir_ffi/user_defined_property_info_test.rb +22 -5
- data/test/gir_ffi/version_test.rb +1 -1
- data/test/integration/callback_exceptions_test.rb +2 -0
- data/test/integration/derived_classes_test.rb +2 -0
- data/test/integration/generated_everything_test.rb +22 -0
- data/test/integration/generated_gimarshallingtests_test.rb +23 -21
- data/test/integration/generated_gio_test.rb +2 -0
- data/test/integration/generated_glib_test.rb +2 -0
- data/test/integration/generated_gst_test.rb +2 -0
- data/test/integration/generated_gtop_test.rb +2 -0
- data/test/integration/generated_regress_test.rb +113 -29
- data/test/integration/generated_secret_test.rb +2 -0
- data/test/integration/generated_warnlib_test.rb +2 -0
- data/test/integration/method_lookup_test.rb +2 -0
- data/test/introspection_test_helper.rb +15 -0
- metadata +21 -27
- data/lib/gir_ffi-base/glib.rb +0 -8
- data/test/gir_ffi-base/glib/boolean_test.rb +0 -34
data/lib/gir_ffi/arg_helper.rb
CHANGED
@@ -10,45 +10,28 @@ module GirFFI
|
|
10
10
|
module ArgHelper
|
11
11
|
OBJECT_STORE = ObjectStore.new
|
12
12
|
|
13
|
-
def self.ptr_to_utf8_length(ptr, len)
|
14
|
-
ptr.null? ? nil : ptr.read_string(len)
|
15
|
-
end
|
16
|
-
|
17
13
|
def self.check_error(errpp)
|
18
14
|
err = GLib::Error.wrap(errpp.read_pointer)
|
19
15
|
raise GLibError, err if err
|
20
16
|
end
|
21
17
|
|
22
18
|
def self.check_fixed_array_size(size, arr, name)
|
23
|
-
unless arr.size
|
19
|
+
unless arr.size.equal? size
|
24
20
|
raise ArgumentError, "#{name} should have size #{size}"
|
25
21
|
end
|
26
22
|
end
|
27
23
|
|
28
|
-
|
24
|
+
# NOTE: Only used in List, SList and HashTable classes.
|
25
|
+
# TODO: Stop using basic types and instead cast type to an ITypeInfo
|
26
|
+
# look-alike.
|
27
|
+
def self.cast_from_pointer(type, ptr)
|
29
28
|
case type
|
30
|
-
when
|
31
|
-
|
32
|
-
when :gint32, :gint8
|
33
|
-
cast_pointer_to_int32 it
|
29
|
+
when Symbol
|
30
|
+
cast_from_simple_type_pointer(type, ptr)
|
34
31
|
when Class
|
35
|
-
type.wrap
|
36
|
-
when :guint32
|
37
|
-
it.address
|
32
|
+
type.wrap ptr
|
38
33
|
when Array
|
39
|
-
|
40
|
-
raise "Unexpected main type #{main_type}" if main_type != :pointer
|
41
|
-
case subtype
|
42
|
-
when Array
|
43
|
-
container_type, *element_type = *subtype
|
44
|
-
raise "Unexpected container type #{container_type}" if container_type != :ghash
|
45
|
-
GLib::HashTable.wrap(element_type, it)
|
46
|
-
else
|
47
|
-
raise "Unexpected subtype #{subtype}"
|
48
|
-
end
|
49
|
-
|
50
|
-
else
|
51
|
-
raise "Don't know how to cast #{type}"
|
34
|
+
cast_from_complex_type_pointer(type, ptr)
|
52
35
|
end
|
53
36
|
end
|
54
37
|
|
@@ -67,5 +50,32 @@ module GirFFI
|
|
67
50
|
def self.store(obj)
|
68
51
|
OBJECT_STORE.store(obj)
|
69
52
|
end
|
53
|
+
|
54
|
+
def self.cast_from_simple_type_pointer(type, ptr)
|
55
|
+
case type
|
56
|
+
when :utf8, :filename
|
57
|
+
ptr.to_utf8
|
58
|
+
when :gint32, :gint8
|
59
|
+
cast_pointer_to_int32 ptr
|
60
|
+
when :guint32
|
61
|
+
ptr.address
|
62
|
+
else
|
63
|
+
raise "Don't know how to cast #{type}"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def self.cast_from_complex_type_pointer(type, ptr)
|
68
|
+
main_type, (container_type, *element_type) = *type
|
69
|
+
case main_type
|
70
|
+
when :pointer
|
71
|
+
case container_type
|
72
|
+
when :ghash
|
73
|
+
return GLib::HashTable.wrap(element_type, ptr)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
raise "Don't know how to cast #{type}"
|
77
|
+
end
|
78
|
+
|
79
|
+
private_class_method :cast_from_complex_type_pointer, :cast_from_simple_type_pointer
|
70
80
|
end
|
71
81
|
end
|
@@ -1,19 +1,21 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
require 'ffi'
|
3
|
-
require 'gir_ffi-base/glib'
|
4
3
|
|
5
|
-
module
|
6
|
-
#
|
4
|
+
module GirFFI
|
5
|
+
# Class representing a boolean (natively, an int).
|
7
6
|
class Boolean
|
8
7
|
extend FFI::DataConverter
|
9
8
|
native_type FFI::Type::INT
|
10
9
|
|
10
|
+
FROM_NATIVE = { 0 => false, 1 => true }.freeze
|
11
|
+
TO_NATIVE = FROM_NATIVE.invert
|
12
|
+
|
11
13
|
def self.from_native(value, _context)
|
12
|
-
value
|
14
|
+
FROM_NATIVE.fetch(value)
|
13
15
|
end
|
14
16
|
|
15
17
|
def self.to_native(value, _context)
|
16
|
-
value
|
18
|
+
TO_NATIVE.fetch(value)
|
17
19
|
end
|
18
20
|
|
19
21
|
def self.size
|
data/lib/gir_ffi/boxed_base.rb
CHANGED
@@ -5,50 +5,32 @@ module GirFFI
|
|
5
5
|
# Base class for generated classes representing boxed types.
|
6
6
|
class BoxedBase < StructBase
|
7
7
|
def initialize
|
8
|
-
store_pointer(
|
8
|
+
store_pointer(nil)
|
9
9
|
end
|
10
10
|
|
11
|
-
def self.make_finalizer(struct
|
11
|
+
def self.make_finalizer(struct)
|
12
12
|
proc do
|
13
13
|
if struct.owned?
|
14
|
-
struct.owned =
|
14
|
+
struct.owned = nil
|
15
15
|
GObject.boxed_free gtype, struct.to_ptr
|
16
16
|
end
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
|
-
# Wrap value and take ownership of it
|
21
|
-
def self.wrap_own(val)
|
22
|
-
wrap(val).tap { |it| it && it.struct.owned = true }
|
23
|
-
end
|
24
|
-
|
25
|
-
# Create an unowned copy of the struct represented by val
|
26
|
-
def self.copy_from(val)
|
27
|
-
copy from(val)
|
28
|
-
end
|
29
|
-
|
30
|
-
# Wrap an owned copy of the struct represented by val
|
31
|
-
def self.wrap_copy(val)
|
32
|
-
# TODO: Is this needed? We may get away with just copying on transfer away from us.
|
33
|
-
copy(wrap(val)).tap { |it| it && it.struct.owned = true }
|
34
|
-
end
|
35
|
-
|
36
20
|
def self.copy(val)
|
37
|
-
return unless val
|
38
21
|
ptr = GObject.boxed_copy(gtype, val)
|
39
22
|
wrap(ptr)
|
40
23
|
end
|
41
24
|
|
42
25
|
private
|
43
26
|
|
44
|
-
def store_pointer(
|
27
|
+
def store_pointer(*)
|
45
28
|
super
|
46
29
|
make_finalizer
|
47
30
|
end
|
48
31
|
|
49
32
|
def make_finalizer
|
50
|
-
|
51
|
-
ObjectSpace.define_finalizer self, self.class.make_finalizer(@struct, gtype)
|
33
|
+
ObjectSpace.define_finalizer self, self.class.make_finalizer(struct)
|
52
34
|
end
|
53
35
|
end
|
54
36
|
end
|
data/lib/gir_ffi/builder.rb
CHANGED
@@ -29,9 +29,9 @@ module GirFFI
|
|
29
29
|
end
|
30
30
|
|
31
31
|
def self.build_module(namespace, version = nil)
|
32
|
-
module_name = namespace.
|
33
|
-
if
|
34
|
-
modul =
|
32
|
+
module_name = namespace.sub(/\A./, &:upcase)
|
33
|
+
if const_defined? module_name
|
34
|
+
modul = const_get module_name
|
35
35
|
unless modul.const_defined? :GIR_FFI_BUILDER
|
36
36
|
raise "The module #{module_name} was already defined elsewhere"
|
37
37
|
end
|
@@ -14,7 +14,6 @@ module GirFFI
|
|
14
14
|
name if has_input_value? && !helper_argument?
|
15
15
|
end
|
16
16
|
|
17
|
-
# TODO: Improve this so each method can only have one block argument.
|
18
17
|
def block_argument?
|
19
18
|
specialized_type_tag == :callback
|
20
19
|
end
|
@@ -90,7 +89,7 @@ module GirFFI
|
|
90
89
|
base = pointer_to_value_method_call call_argument_name, type_spec
|
91
90
|
if needs_out_conversion?
|
92
91
|
outgoing_convertor(base).conversion
|
93
|
-
elsif allocated_by_them?
|
92
|
+
elsif allocated_by_them? && specialized_type_tag != :void
|
94
93
|
pointer_to_value_method_call base, sub_type_spec
|
95
94
|
else
|
96
95
|
base
|
@@ -98,7 +97,7 @@ module GirFFI
|
|
98
97
|
end
|
99
98
|
|
100
99
|
def outgoing_convertor(base)
|
101
|
-
FullCToRubyConvertor.new(
|
100
|
+
FullCToRubyConvertor.new(type_info, base, length_argument_name,
|
102
101
|
ownership_transfer: @arginfo.ownership_transfer)
|
103
102
|
end
|
104
103
|
|
@@ -111,11 +110,11 @@ module GirFFI
|
|
111
110
|
end
|
112
111
|
|
113
112
|
def needs_out_conversion?
|
114
|
-
|
113
|
+
type_info.needs_c_to_ruby_conversion_for_functions?
|
115
114
|
end
|
116
115
|
|
117
116
|
def gvalue?
|
118
|
-
|
117
|
+
type_info.gvalue?
|
119
118
|
end
|
120
119
|
|
121
120
|
# Check if an out argument needs to be allocated by them, the callee. Since
|
@@ -123,7 +122,7 @@ module GirFFI
|
|
123
122
|
# is a pointer. For example, an out parameter of type gint8* will always
|
124
123
|
# be allocated by the caller (that's us).
|
125
124
|
def allocated_by_them?
|
126
|
-
!@arginfo.caller_allocates? &&
|
125
|
+
!@arginfo.caller_allocates? && type_info.pointer?
|
127
126
|
end
|
128
127
|
|
129
128
|
def length_argument_name
|
@@ -197,8 +196,8 @@ module GirFFI
|
|
197
196
|
NullConvertor.new(DESTROY_NOTIFIER)
|
198
197
|
elsif closure?
|
199
198
|
ClosureToPointerConvertor.new(pre_convertor_argument, @is_closure)
|
200
|
-
elsif
|
201
|
-
RubyToCConvertor.new(
|
199
|
+
elsif type_info.needs_ruby_to_c_conversion_for_functions?
|
200
|
+
RubyToCConvertor.new(type_info, pre_convertor_argument,
|
202
201
|
ownership_transfer: ownership_transfer)
|
203
202
|
else
|
204
203
|
NullConvertor.new(pre_convertor_argument)
|
@@ -144,8 +144,8 @@ module GirFFI
|
|
144
144
|
|
145
145
|
def out_parameter_preparation
|
146
146
|
value = if allocated_by_us?
|
147
|
-
ffi_type = TypeMap.type_specification_to_ffi_type type_spec
|
148
|
-
"
|
147
|
+
ffi_type = TypeMap.type_specification_to_ffi_type type_spec.last
|
148
|
+
"FFI::MemoryPointer.new(#{ffi_type.inspect})" \
|
149
149
|
".tap { |ptr| #{method_argument_name}.put_pointer 0, ptr }"
|
150
150
|
else
|
151
151
|
method_argument_name
|
@@ -9,16 +9,14 @@ module GirFFI
|
|
9
9
|
class CallbackReturnValueBuilder < BaseReturnValueBuilder
|
10
10
|
def post_conversion
|
11
11
|
if has_post_conversion?
|
12
|
-
|
13
|
-
["#{post_converted_name} = #{post_convertor.conversion}.to_ptr"]
|
14
|
-
else
|
15
|
-
["#{post_converted_name} = #{post_convertor.conversion}"]
|
16
|
-
end
|
12
|
+
optional_outgoing_ref + base_post_conversion
|
17
13
|
else
|
18
14
|
[]
|
19
15
|
end
|
20
16
|
end
|
21
17
|
|
18
|
+
private
|
19
|
+
|
22
20
|
def has_post_conversion?
|
23
21
|
relevant? && needs_ruby_to_c_conversion?
|
24
22
|
end
|
@@ -27,19 +25,29 @@ module GirFFI
|
|
27
25
|
type_info.needs_ruby_to_c_conversion_for_callbacks?
|
28
26
|
end
|
29
27
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
28
|
+
def optional_outgoing_ref
|
29
|
+
if outgoing_ref_needed?
|
30
|
+
["#{capture_variable_name}.ref"]
|
31
|
+
else
|
32
|
+
[]
|
33
|
+
end
|
34
34
|
end
|
35
35
|
|
36
|
-
def
|
37
|
-
if
|
38
|
-
"#{
|
36
|
+
def base_post_conversion
|
37
|
+
if specialized_type_tag == :object
|
38
|
+
["#{post_converted_name} = #{post_convertor.conversion}.to_ptr"]
|
39
39
|
else
|
40
|
-
|
40
|
+
["#{post_converted_name} = #{post_convertor.conversion}"]
|
41
41
|
end
|
42
42
|
end
|
43
|
+
|
44
|
+
def post_convertor
|
45
|
+
@post_convertor ||= RubyToCConvertor.new(type_info, capture_variable_name)
|
46
|
+
end
|
47
|
+
|
48
|
+
def outgoing_ref_needed?
|
49
|
+
ownership_transfer == :everything && specialized_type_tag == :object
|
50
|
+
end
|
43
51
|
end
|
44
52
|
end
|
45
53
|
end
|
@@ -229,8 +229,9 @@ module GirFFI
|
|
229
229
|
|
230
230
|
attr_reader :info
|
231
231
|
|
232
|
-
def initialize(field_info)
|
232
|
+
def initialize(field_info, container_class)
|
233
233
|
@info = field_info
|
234
|
+
@container_class = container_class
|
234
235
|
end
|
235
236
|
|
236
237
|
def build
|
@@ -285,13 +286,7 @@ module GirFFI
|
|
285
286
|
@field_type_tag ||= field_type.tag_or_class
|
286
287
|
end
|
287
288
|
|
288
|
-
|
289
|
-
@container_class ||= container_module.const_get(container_info.safe_name)
|
290
|
-
end
|
291
|
-
|
292
|
-
def container_module
|
293
|
-
@container_module ||= Object.const_get(container_info.safe_namespace)
|
294
|
-
end
|
289
|
+
attr_reader :container_class
|
295
290
|
|
296
291
|
def container_info
|
297
292
|
@container_info ||= info.container
|
@@ -310,9 +305,8 @@ module GirFFI
|
|
310
305
|
field_argument_info)
|
311
306
|
end
|
312
307
|
|
313
|
-
# rubocop:disable Style/ZeroLengthPredicate
|
314
308
|
def hidden_struct_type?
|
315
|
-
field_type.
|
309
|
+
field_type.hidden_struct_type?
|
316
310
|
end
|
317
311
|
end
|
318
312
|
end
|
@@ -32,6 +32,10 @@ module GirFFI
|
|
32
32
|
true
|
33
33
|
end
|
34
34
|
|
35
|
+
def method_available?(method)
|
36
|
+
function_introspection_data(method.to_s) and true
|
37
|
+
end
|
38
|
+
|
35
39
|
def build_namespaced_class(classname)
|
36
40
|
info = find_namespaced_class_info(classname)
|
37
41
|
Builder.build_class info
|
@@ -109,11 +113,9 @@ module GirFFI
|
|
109
113
|
end
|
110
114
|
|
111
115
|
def gir
|
112
|
-
|
113
|
-
@
|
114
|
-
@gir.require @namespace, @version
|
116
|
+
@gir ||= GObjectIntrospection::IRepository.default.tap do |it|
|
117
|
+
it.require @namespace, @version
|
115
118
|
end
|
116
|
-
@gir
|
117
119
|
end
|
118
120
|
end
|
119
121
|
end
|
@@ -79,12 +79,7 @@ module GirFFI
|
|
79
79
|
end
|
80
80
|
|
81
81
|
def parent_info
|
82
|
-
|
83
|
-
@parent_info = if (parent = info.parent) && parent != info
|
84
|
-
parent
|
85
|
-
end
|
86
|
-
end
|
87
|
-
@parent_info
|
82
|
+
info.parent
|
88
83
|
end
|
89
84
|
|
90
85
|
def superclass
|
@@ -105,7 +100,7 @@ module GirFFI
|
|
105
100
|
|
106
101
|
def setup_field_accessors
|
107
102
|
eligible_fields.each do |finfo|
|
108
|
-
FieldBuilder.new(finfo).build
|
103
|
+
FieldBuilder.new(finfo, klass).build
|
109
104
|
end
|
110
105
|
end
|
111
106
|
|
@@ -119,9 +114,7 @@ module GirFFI
|
|
119
114
|
# TODO: Create object responsible for creating these invokers
|
120
115
|
def setup_vfunc_invokers
|
121
116
|
info.vfuncs.each do |vfinfo|
|
122
|
-
|
123
|
-
define_vfunc_invoker vfinfo.name, invoker.name
|
124
|
-
end
|
117
|
+
define_vfunc_invoker vfinfo.name, vfinfo.invoker_name if vfinfo.has_invoker?
|
125
118
|
end
|
126
119
|
end
|
127
120
|
|
@@ -137,12 +130,19 @@ module GirFFI
|
|
137
130
|
def provide_initializer
|
138
131
|
return if info.find_method 'new'
|
139
132
|
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
133
|
+
if info.abstract?
|
134
|
+
klass.class_eval <<-END
|
135
|
+
def initialize(*)
|
136
|
+
raise NoMethodError
|
137
|
+
end
|
138
|
+
END
|
139
|
+
else
|
140
|
+
klass.class_eval <<-END
|
141
|
+
def initialize(properties = {})
|
142
|
+
base_initialize(properties)
|
143
|
+
end
|
144
|
+
END
|
145
|
+
end
|
146
146
|
end
|
147
147
|
|
148
148
|
def setup_interfaces
|
@@ -16,12 +16,10 @@ module GirFFI
|
|
16
16
|
def superclass
|
17
17
|
if info.gtype_struct?
|
18
18
|
# HACK: Inheritance chain is not expressed in GObject's code correctly.
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
return type.tag_or_class if type.tag == :interface
|
24
|
-
end
|
19
|
+
type_name = info.full_type_name
|
20
|
+
return GObject::ObjectClass if type_name == 'GObject::InitiallyUnownedClass'
|
21
|
+
type = fields.first.field_type
|
22
|
+
return type.tag_or_class if type.tag == :interface
|
25
23
|
end
|
26
24
|
|
27
25
|
if GObject.type_fundamental(info.gtype) == GObject::TYPE_BOXED
|
@@ -11,8 +11,8 @@ module GirFFI
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def setup_class
|
14
|
-
register_type
|
15
14
|
setup_layout
|
15
|
+
register_type
|
16
16
|
setup_constants
|
17
17
|
setup_property_accessors
|
18
18
|
setup_constructor
|
@@ -86,8 +86,10 @@ module GirFFI
|
|
86
86
|
|
87
87
|
def instance_size
|
88
88
|
size = parent_gtype.instance_size
|
89
|
-
|
90
|
-
|
89
|
+
alignment = struct_class.alignment
|
90
|
+
properties.each do |prop|
|
91
|
+
type_size = FFI.type_size(prop.ffi_type)
|
92
|
+
size += [type_size, alignment].max
|
91
93
|
end
|
92
94
|
size
|
93
95
|
end
|
@@ -109,13 +111,13 @@ module GirFFI
|
|
109
111
|
|
110
112
|
def property_getter
|
111
113
|
proc do |object, _property_id, value, pspec|
|
112
|
-
value.set_value object.send(pspec.
|
114
|
+
value.set_value object.send(pspec.accessor_name)
|
113
115
|
end
|
114
116
|
end
|
115
117
|
|
116
118
|
def property_setter
|
117
119
|
proc do |object, _property_id, value, pspec|
|
118
|
-
object.send("#{pspec.
|
120
|
+
object.send("#{pspec.accessor_name}=", value.get_value)
|
119
121
|
end
|
120
122
|
end
|
121
123
|
|
@@ -167,34 +169,92 @@ module GirFFI
|
|
167
169
|
end
|
168
170
|
|
169
171
|
def layout_specification
|
170
|
-
parent_spec = [:parent, superclass::Struct
|
171
|
-
offset =
|
172
|
-
|
173
|
-
|
174
|
-
|
172
|
+
parent_spec = [:parent, superclass::Struct]
|
173
|
+
offset = parent_gtype.instance_size
|
174
|
+
|
175
|
+
alignment = superclass::Struct.alignment
|
176
|
+
fields_spec = properties.flat_map do |param_info|
|
177
|
+
field_name = param_info.accessor_name
|
178
|
+
ffi_type = param_info.ffi_type
|
179
|
+
type_size = FFI.type_size(ffi_type)
|
180
|
+
spec = [field_name, ffi_type, offset]
|
181
|
+
offset += [type_size, alignment].max
|
175
182
|
spec
|
176
183
|
end
|
177
184
|
parent_spec + fields_spec
|
178
185
|
end
|
179
186
|
|
180
|
-
|
181
|
-
|
182
|
-
|
187
|
+
# TODO: Move this to its own file.
|
188
|
+
# TODO: See if this or FieldTypeInfo can be merged with with
|
189
|
+
# UserDefinedPropertyInfo.
|
190
|
+
class UserDefinedPropertyFieldInfo
|
191
|
+
# Field info for user-defined property
|
192
|
+
class FieldTypeInfo
|
193
|
+
include InfoExt::ITypeInfo
|
194
|
+
|
195
|
+
def initialize(property_info)
|
196
|
+
@property_info = property_info
|
197
|
+
end
|
198
|
+
|
199
|
+
def tag
|
200
|
+
@property_info.type_tag
|
201
|
+
end
|
202
|
+
|
203
|
+
def pointer?
|
204
|
+
@property_info.pointer_type?
|
205
|
+
end
|
206
|
+
|
207
|
+
def interface_type
|
208
|
+
@property_info.interface_type_tag if tag == :interface
|
209
|
+
end
|
210
|
+
|
211
|
+
def hidden_struct_type?
|
212
|
+
false
|
213
|
+
end
|
214
|
+
|
215
|
+
def interface_class
|
216
|
+
Builder.build_by_gtype @property_info.value_type if tag == :interface
|
217
|
+
end
|
218
|
+
|
219
|
+
def interface_class_name
|
220
|
+
interface_class.name if tag == :interface
|
221
|
+
end
|
183
222
|
end
|
184
|
-
end
|
185
223
|
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
@struct[:#{field_name}]
|
224
|
+
def initialize(property_info, container, offset)
|
225
|
+
@property_info = property_info
|
226
|
+
@container = container
|
227
|
+
@offset = offset
|
191
228
|
end
|
192
|
-
|
193
|
-
|
229
|
+
|
230
|
+
attr_reader :container, :offset
|
231
|
+
|
232
|
+
def name
|
233
|
+
@property_info.accessor_name
|
194
234
|
end
|
195
|
-
CODE
|
196
235
|
|
197
|
-
|
236
|
+
def field_type
|
237
|
+
@field_type ||= FieldTypeInfo.new @property_info
|
238
|
+
end
|
239
|
+
|
240
|
+
def related_array_length_field
|
241
|
+
nil
|
242
|
+
end
|
243
|
+
|
244
|
+
def writable?
|
245
|
+
@property_info.writable?
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
249
|
+
def setup_property_accessors
|
250
|
+
offset = parent_gtype.instance_size
|
251
|
+
alignment = struct_class.alignment
|
252
|
+
properties.each do |param_info|
|
253
|
+
field_info = UserDefinedPropertyFieldInfo.new(param_info, info, offset)
|
254
|
+
type_size = FFI.type_size(param_info.ffi_type)
|
255
|
+
offset += [type_size, alignment].max
|
256
|
+
FieldBuilder.new(field_info, klass).build
|
257
|
+
end
|
198
258
|
end
|
199
259
|
|
200
260
|
def method_introspection_data(_method)
|
@@ -7,8 +7,16 @@ module GirFFI
|
|
7
7
|
# argument mapper for vfuncs.
|
8
8
|
class VFuncArgumentBuilder < CallbackArgumentBuilder
|
9
9
|
def pre_conversion
|
10
|
-
if ingoing_ref_needed
|
11
|
-
super + [
|
10
|
+
if ingoing_ref_needed?
|
11
|
+
super + ["#{pre_converted_name}.ref"]
|
12
|
+
else
|
13
|
+
super
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def post_conversion
|
18
|
+
if outgoing_ref_needed?
|
19
|
+
["#{result_name}.ref"] + super
|
12
20
|
else
|
13
21
|
super
|
14
22
|
end
|
@@ -16,26 +24,13 @@ module GirFFI
|
|
16
24
|
|
17
25
|
private
|
18
26
|
|
19
|
-
def ingoing_ref_needed
|
27
|
+
def ingoing_ref_needed?
|
20
28
|
direction == :in &&
|
21
29
|
ownership_transfer == :nothing &&
|
22
30
|
specialized_type_tag == :object
|
23
31
|
end
|
24
32
|
|
25
|
-
def
|
26
|
-
"#{pre_converted_name}.ref"
|
27
|
-
end
|
28
|
-
|
29
|
-
# SMELL: Override private method
|
30
|
-
def post_convertor_argument
|
31
|
-
if outgoing_ref_needed
|
32
|
-
"#{super}.ref"
|
33
|
-
else
|
34
|
-
super
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
def outgoing_ref_needed
|
33
|
+
def outgoing_ref_needed?
|
39
34
|
direction == :out &&
|
40
35
|
ownership_transfer == :everything &&
|
41
36
|
specialized_type_tag == :object
|
data/lib/gir_ffi/class_base.rb
CHANGED
@@ -31,10 +31,6 @@ module GirFFI
|
|
31
31
|
other.class == self.class && to_ptr.address == other.to_ptr.address
|
32
32
|
end
|
33
33
|
|
34
|
-
def initialize
|
35
|
-
raise NoMethodError
|
36
|
-
end
|
37
|
-
|
38
34
|
def self.setup_and_call(method, arguments, &block)
|
39
35
|
method_name = try_in_ancestors(:setup_method, method.to_s)
|
40
36
|
|