gir_ffi 0.10.2 → 0.11.0
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/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
|
|