gir_ffi 0.8.6 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. checksums.yaml +4 -4
  2. data/Changelog.md +18 -0
  3. data/README.md +3 -4
  4. data/lib/ffi-glib.rb +1 -0
  5. data/lib/ffi-glib/container_class_methods.rb +12 -0
  6. data/lib/ffi-glib/destroy_notify.rb +15 -0
  7. data/lib/ffi-glib/main_loop.rb +23 -4
  8. data/lib/ffi-gobject.rb +4 -2
  9. data/lib/ffi-gobject/object.rb +31 -16
  10. data/lib/ffi-gobject/object_class.rb +4 -0
  11. data/lib/ffi-gobject/value.rb +3 -3
  12. data/lib/ffi-gobject_introspection/i_flags_info.rb +0 -1
  13. data/lib/gir_ffi-base/gobject/lib.rb +10 -0
  14. data/lib/gir_ffi/arg_helper.rb +1 -22
  15. data/lib/gir_ffi/boxed_base.rb +1 -0
  16. data/lib/gir_ffi/builder.rb +7 -1
  17. data/lib/gir_ffi/builders/argument_builder.rb +21 -9
  18. data/lib/gir_ffi/builders/argument_builder_collection.rb +28 -9
  19. data/lib/gir_ffi/builders/base_argument_builder.rb +36 -12
  20. data/lib/gir_ffi/builders/base_method_builder.rb +1 -1
  21. data/lib/gir_ffi/builders/callback_argument_builder.rb +4 -0
  22. data/lib/gir_ffi/builders/closure_to_pointer_convertor.rb +3 -2
  23. data/lib/gir_ffi/builders/constructor_builder.rb +1 -1
  24. data/lib/gir_ffi/builders/enum_builder.rb +4 -4
  25. data/lib/gir_ffi/builders/error_argument_builder.rb +4 -0
  26. data/lib/gir_ffi/builders/field_builder.rb +23 -9
  27. data/lib/gir_ffi/builders/flags_builder.rb +28 -0
  28. data/lib/gir_ffi/builders/full_c_to_ruby_convertor.rb +18 -0
  29. data/lib/gir_ffi/builders/module_builder.rb +1 -0
  30. data/lib/gir_ffi/builders/null_argument_builder.rb +9 -1
  31. data/lib/gir_ffi/builders/object_builder.rb +7 -4
  32. data/lib/gir_ffi/builders/property_builder.rb +2 -2
  33. data/lib/gir_ffi/builders/return_value_builder.rb +4 -4
  34. data/lib/gir_ffi/builders/struct_builder.rb +10 -2
  35. data/lib/gir_ffi/builders/type_builder.rb +12 -9
  36. data/lib/gir_ffi/builders/unintrospectable_boxed_builder.rb +26 -0
  37. data/lib/gir_ffi/builders/user_defined_builder.rb +2 -2
  38. data/lib/gir_ffi/builders/with_layout.rb +1 -1
  39. data/lib/gir_ffi/callback_base.rb +13 -5
  40. data/lib/gir_ffi/core.rb +1 -0
  41. data/lib/gir_ffi/error_argument_info.rb +4 -0
  42. data/lib/gir_ffi/flags_base.rb +63 -0
  43. data/lib/gir_ffi/in_pointer.rb +1 -3
  44. data/lib/gir_ffi/info_ext/i_type_info.rb +6 -0
  45. data/lib/gir_ffi/object_base.rb +9 -1
  46. data/lib/gir_ffi/object_store.rb +26 -0
  47. data/lib/gir_ffi/unintrospectable_boxed_info.rb +31 -0
  48. data/lib/gir_ffi/unintrospectable_type_info.rb +5 -0
  49. data/lib/gir_ffi/user_defined_type_info.rb +19 -0
  50. data/lib/gir_ffi/version.rb +1 -1
  51. data/test/ffi-glib/destroy_notify_test.rb +13 -0
  52. data/test/ffi-glib/main_loop_test.rb +3 -3
  53. data/test/ffi-gobject/object_class_test.rb +8 -0
  54. data/test/ffi-gobject/object_test.rb +23 -5
  55. data/test/ffi-gobject/value_test.rb +19 -5
  56. data/test/ffi-gobject_test.rb +2 -2
  57. data/test/gir_ffi/builders/argument_builder_test.rb +12 -2
  58. data/test/gir_ffi/builders/constructor_builder_test.rb +4 -4
  59. data/test/gir_ffi/builders/function_builder_test.rb +46 -3
  60. data/test/gir_ffi/builders/object_builder_test.rb +25 -0
  61. data/test/gir_ffi/builders/property_builder_test.rb +4 -4
  62. data/test/gir_ffi/builders/struct_builder_test.rb +15 -13
  63. data/test/gir_ffi/builders/unintrospectable_boxed_builder_test.rb +33 -0
  64. data/test/gir_ffi/builders/unintrospectable_builder_test.rb +6 -0
  65. data/test/gir_ffi/builders/user_defined_builder_test.rb +7 -1
  66. data/test/gir_ffi/callback_base_test.rb +12 -2
  67. data/test/gir_ffi/object_base_test.rb +14 -0
  68. data/test/integration/callback_exceptions_test.rb +61 -0
  69. data/test/integration/generated_gimarshallingtests_test.rb +70 -70
  70. data/test/integration/generated_gio_test.rb +1 -1
  71. data/test/integration/generated_gobject_test.rb +1 -1
  72. data/test/integration/generated_gtop_test.rb +5 -1
  73. data/test/integration/generated_regress_test.rb +83 -102
  74. data/test/integration/generated_warnlib_test.rb +2 -2
  75. metadata +42 -4
@@ -1,14 +1,16 @@
1
1
  module GirFFI
2
2
  module Builders
3
- # Class representing the argument and return value builders for a callback
4
- # mapping function or marshaller. Implements collecting the conversion code
5
- # and parameter and variable names for use by function builders.
3
+ # Class representing the argument and return value builders for a method,
4
+ # callback mapping function or marshaller. Implements collecting the
5
+ # conversion code and parameter and variable names for use by function
6
+ # builders.
6
7
  class ArgumentBuilderCollection
7
8
  attr_reader :return_value_builder
8
9
 
9
- def initialize(return_value_builder, argument_builders, options = {})
10
- @receiver_builder = options[:receiver_builder]
11
- @error_argument_builder = options[:error_argument_builder]
10
+ def initialize(return_value_builder, argument_builders,
11
+ receiver_builder: nil, error_argument_builder: nil)
12
+ @receiver_builder = receiver_builder
13
+ @error_argument_builder = error_argument_builder
12
14
  @base_argument_builders = argument_builders
13
15
  @return_value_builder = return_value_builder
14
16
  set_up_argument_relations
@@ -32,7 +34,21 @@ module GirFFI
32
34
  end
33
35
 
34
36
  def method_argument_names
35
- @method_argument_names ||= argument_builders.map(&:method_argument_name).compact
37
+ @method_argument_names ||=
38
+ begin
39
+ base = []
40
+ block = nil
41
+ argument_builders.each do |it|
42
+ name = it.method_argument_name
43
+ if !block && it.block_argument?
44
+ block = "&#{name}"
45
+ else
46
+ base << name
47
+ end
48
+ end
49
+ base << block if block
50
+ base.compact
51
+ end
36
52
  end
37
53
 
38
54
  def return_value_name
@@ -58,8 +74,11 @@ module GirFFI
58
74
 
59
75
  def set_up_argument_relations
60
76
  @base_argument_builders.each do |bldr|
61
- if (idx = bldr.closure) >= 0
62
- @base_argument_builders[idx].closure = true
77
+ if (idx = bldr.closure_idx) >= 0
78
+ @base_argument_builders[idx].closure = bldr
79
+ end
80
+ if (idx = bldr.destroy_idx) >= 0
81
+ @base_argument_builders[idx].mark_as_destroy_notifier bldr
63
82
  end
64
83
  end
65
84
  all_builders.each do |bldr|
@@ -15,23 +15,13 @@ module GirFFI
15
15
  attr_reader :arginfo
16
16
  attr_accessor :length_arg, :array_arg
17
17
 
18
- # TODO: closure unfortunately means two things in GLib: a closure
19
- # argument (user_data), and the Closure class (a callable object). Make
20
- # the distinction more explicit in GirFFI.
21
- def closure?
22
- @is_closure
23
- end
24
-
25
- def closure=(arg)
26
- @is_closure = arg
27
- end
28
-
29
18
  def initialize(var_gen, arginfo)
30
19
  @var_gen = var_gen
31
20
  @arginfo = arginfo
32
21
  @length_arg = nil
33
22
  @array_arg = nil
34
23
  @is_closure = false
24
+ @destroy_notifier = false
35
25
  end
36
26
 
37
27
  def name
@@ -60,10 +50,44 @@ module GirFFI
60
50
  type_info.array_length
61
51
  end
62
52
 
63
- def closure
53
+ def closure_idx
64
54
  arginfo.closure
65
55
  end
66
56
 
57
+ def destroy_idx
58
+ arginfo.destroy
59
+ end
60
+
61
+ # TODO: closure unfortunately means two things in GLib: a closure
62
+ # argument (user_data), and the Closure class (a callable object). Make
63
+ # the distinction more explicit in GirFFI.
64
+ def closure=(arg)
65
+ @is_closure = arg
66
+ end
67
+
68
+ # TODO: Unify relationship set-up methods and improve naming. We
69
+ # currently have length_arg=, array_arg=, closure= and
70
+ # mark_as_destroy_notifier.
71
+ def mark_as_destroy_notifier(callback)
72
+ @destroy_notifier = callback
73
+ end
74
+
75
+ def array_length_parameter?
76
+ @array_arg
77
+ end
78
+
79
+ def closure?
80
+ @is_closure
81
+ end
82
+
83
+ def destroy_notifier?
84
+ @destroy_notifier
85
+ end
86
+
87
+ def helper_argument?
88
+ array_length_parameter? || closure? || destroy_notifier?
89
+ end
90
+
67
91
  def ownership_transfer
68
92
  arginfo.ownership_transfer
69
93
  end
@@ -53,7 +53,7 @@ module GirFFI
53
53
  # Methods used by MethodTemplate
54
54
 
55
55
  def invocation
56
- "#{lib_name}.#{@info.symbol} #{function_call_arguments.join(', ')}"
56
+ "#{lib_name}.#{@info.symbol} #{function_call_arguments.join(', ')}".strip
57
57
  end
58
58
 
59
59
  def method_arguments
@@ -12,6 +12,10 @@ module GirFFI
12
12
  @method_argument_name ||= name || new_variable
13
13
  end
14
14
 
15
+ def block_argument?
16
+ false
17
+ end
18
+
15
19
  def pre_converted_name
16
20
  @pre_converted_name ||= new_variable
17
21
  end
@@ -3,12 +3,13 @@ module GirFFI
3
3
  # Builder that generates code to convert closure arguments ('user data')
4
4
  # from Ruby to C. Used by argument builders.
5
5
  class ClosureToPointerConvertor
6
- def initialize(argument_name)
6
+ def initialize(argument_name, callback_argument)
7
7
  @argument_name = argument_name
8
+ @callback_argument = callback_argument
8
9
  end
9
10
 
10
11
  def conversion
11
- "GirFFI::InPointer.from_closure_data(#{@argument_name})"
12
+ "GirFFI::InPointer.from_closure_data(#{@callback_argument.call_argument_name}.object_id)"
12
13
  end
13
14
  end
14
15
  end
@@ -27,7 +27,7 @@ module GirFFI
27
27
  end
28
28
 
29
29
  def method_arguments
30
- ['*args']
30
+ ['*args', '&block']
31
31
  end
32
32
 
33
33
  def preparation
@@ -21,7 +21,7 @@ module GirFFI
21
21
  end
22
22
 
23
23
  def setup_class
24
- setup_ffi_enum
24
+ setup_ffi_type
25
25
  klass.extend superclass
26
26
  setup_constants
27
27
  stub_methods
@@ -32,8 +32,8 @@ module GirFFI
32
32
  @klass ||= get_or_define_module namespace_module, @classname
33
33
  end
34
34
 
35
- def setup_ffi_enum
36
- @enum = optionally_define_constant klass, :Enum do
35
+ def setup_ffi_type
36
+ optionally_define_constant klass, :Enum do
37
37
  lib.enum(enum_sym, value_spec)
38
38
  end
39
39
  end
@@ -51,7 +51,7 @@ module GirFFI
51
51
  end
52
52
 
53
53
  def superclass
54
- @superclass ||= EnumBase
54
+ EnumBase
55
55
  end
56
56
  end
57
57
  end
@@ -10,6 +10,10 @@ module GirFFI
10
10
  nil
11
11
  end
12
12
 
13
+ def block_argument?
14
+ false
15
+ end
16
+
13
17
  def return_value_name
14
18
  nil
15
19
  end
@@ -9,10 +9,12 @@ module GirFFI
9
9
  # Convertor for fields for field getters. Used when building getter
10
10
  # methods.
11
11
  class GetterArgumentBuilder < BaseArgumentBuilder
12
- def initialize(var_gen, field_argument_info, field_info, options = {})
12
+ def initialize(var_gen, field_argument_info, field_info,
13
+ array_length_idx: -1)
13
14
  super(var_gen, field_argument_info)
14
15
  @field_info = field_info
15
- @length_arg = options.fetch(:length_argument) { NullArgumentBuilder.new }
16
+ @length_arg = NullArgumentBuilder.new
17
+ @array_length_idx = array_length_idx
16
18
  end
17
19
 
18
20
  def pre_conversion
@@ -47,6 +49,10 @@ module GirFFI
47
49
  end
48
50
  end
49
51
 
52
+ def array_length_idx
53
+ @array_length_idx
54
+ end
55
+
50
56
  private
51
57
 
52
58
  def field_offset
@@ -98,6 +104,10 @@ module GirFFI
98
104
  -1
99
105
  end
100
106
 
107
+ def destroy
108
+ -1
109
+ end
110
+
101
111
  def direction
102
112
  :out
103
113
  end
@@ -163,22 +173,26 @@ module GirFFI
163
173
  @argument_builders ||=
164
174
  ArgumentBuilderCollection.new(
165
175
  NullReturnValueBuilder.new,
166
- [getter_argument_builder, length_argument_builder])
176
+ base_argument_builders)
177
+ end
178
+
179
+ def base_argument_builders
180
+ if array_length_field
181
+ [getter_argument_builder, length_argument_builder]
182
+ else
183
+ [getter_argument_builder]
184
+ end
167
185
  end
168
186
 
169
187
  def getter_argument_builder
170
188
  @getter_argument_builder ||=
171
189
  GetterArgumentBuilder.new(var_gen, field_argument_info, @info,
172
- length_argument: length_argument_builder)
190
+ array_length_idx: array_length_field ? 1 : -1)
173
191
  end
174
192
 
175
193
  def length_argument_builder
176
194
  @length_argument_builder ||=
177
- if array_length_field
178
- GetterArgumentBuilder.new(var_gen, length_argument_info, array_length_field)
179
- else
180
- NullArgumentBuilder.new
181
- end
195
+ GetterArgumentBuilder.new(var_gen, length_argument_info, array_length_field)
182
196
  end
183
197
 
184
198
  def array_length_field
@@ -0,0 +1,28 @@
1
+ require 'gir_ffi/builders/enum_builder'
2
+ require 'gir_ffi/flags_base'
3
+
4
+ module GirFFI
5
+ module Builders
6
+ # Implements the creation of a flags type. The type will be
7
+ # attached to the appropriate namespace module, and will be defined
8
+ # as a bit_mask for FFI.
9
+ class FlagsBuilder < EnumBuilder
10
+ def setup_ffi_type
11
+ optionally_define_constant klass, :BitMask do
12
+ lib.bit_mask(enum_sym, value_spec)
13
+ end
14
+ end
15
+
16
+ def value_spec
17
+ info.values.map do|vinfo|
18
+ val = GirFFI::ArgHelper.cast_uint32_to_int32(vinfo.value)
19
+ { vinfo.name.to_sym => val }
20
+ end.reduce(:merge)
21
+ end
22
+
23
+ def superclass
24
+ FlagsBase
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,18 @@
1
+ require 'gir_ffi/builders/c_to_ruby_convertor'
2
+
3
+ module GirFFI
4
+ module Builders
5
+ # Builder that generates code to convert values from C to Ruby, including
6
+ # GValue unpacking. Used by argument builders.
7
+ class FullCToRubyConvertor < CToRubyConvertor
8
+ def conversion
9
+ base = super
10
+ if @type_info.gvalue?
11
+ "#{base}.get_value"
12
+ else
13
+ base
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -83,6 +83,7 @@ module GirFFI
83
83
 
84
84
  def setup_lib_for_ffi
85
85
  lib.extend FFI::Library
86
+ lib.extend FFI::BitMasks
86
87
  lib.ffi_lib_flags :global, :lazy
87
88
  if shared_library_specification
88
89
  lib.ffi_lib(*shared_library_specification.split(/,/))
@@ -32,10 +32,18 @@ module GirFFI
32
32
  nil
33
33
  end
34
34
 
35
- def closure
35
+ def closure_idx
36
36
  -1
37
37
  end
38
38
 
39
+ def destroy_idx
40
+ -1
41
+ end
42
+
43
+ def block_argument?
44
+ false
45
+ end
46
+
39
47
  def post_converted_name
40
48
  nil
41
49
  end
@@ -38,6 +38,13 @@ module GirFFI
38
38
  @ancestor_infos ||= [info] + info.interfaces + parent_ancestor_infos
39
39
  end
40
40
 
41
+ protected
42
+
43
+ def object_class_struct_info
44
+ @object_class_struct_info ||=
45
+ info.class_struct || parent_builder.object_class_struct_info
46
+ end
47
+
41
48
  private
42
49
 
43
50
  def setup_class
@@ -131,10 +138,6 @@ module GirFFI
131
138
  end
132
139
  end
133
140
 
134
- def object_class_struct_info
135
- @object_class_struct_info ||= info.class_struct
136
- end
137
-
138
141
  def seek_in_ancestor_infos
139
142
  ancestor_infos.each do |info|
140
143
  item = yield info
@@ -50,7 +50,7 @@ module GirFFI
50
50
  capture = getter_builder.capture_variable_name
51
51
  <<-CODE.reset_indentation
52
52
  def #{getter_name}
53
- #{capture} = get_property("#{property_name}").get_value_plain
53
+ #{capture} = get_property("#{property_name}")
54
54
  #{getter_builder.post_conversion.join("\n")}
55
55
  #{getter_builder.return_value_name}
56
56
  end
@@ -60,7 +60,7 @@ module GirFFI
60
60
  def simple_getter_def
61
61
  <<-CODE.reset_indentation
62
62
  def #{getter_name}
63
- get_property("#{property_name}").get_value
63
+ get_property("#{property_name}")
64
64
  end
65
65
  CODE
66
66
  end
@@ -1,5 +1,5 @@
1
1
  require 'gir_ffi/builders/base_argument_builder'
2
- require 'gir_ffi/builders/c_to_ruby_convertor'
2
+ require 'gir_ffi/builders/full_c_to_ruby_convertor'
3
3
  require 'gir_ffi/builders/closure_convertor'
4
4
 
5
5
  module GirFFI
@@ -44,9 +44,9 @@ module GirFFI
44
44
  @post_convertor ||= if closure?
45
45
  ClosureConvertor.new(capture_variable_name)
46
46
  else
47
- CToRubyConvertor.new(type_info,
48
- capture_variable_name,
49
- length_argument_name)
47
+ FullCToRubyConvertor.new(type_info,
48
+ capture_variable_name,
49
+ length_argument_name)
50
50
  end
51
51
  end
52
52
 
@@ -9,9 +9,17 @@ module GirFFI
9
9
  FFI::Struct
10
10
  end
11
11
 
12
- private
13
-
14
12
  def superclass
13
+ if info.gtype_struct?
14
+ # HACK: Inheritance chain is not expressed in GObject's code correctly.
15
+ if info.full_type_name == 'GObject::InitiallyUnownedClass'
16
+ return GObject::ObjectClass
17
+ else
18
+ type = fields.first.field_type
19
+ return type.tag_or_class if type.tag == :interface
20
+ end
21
+ end
22
+
15
23
  StructBase
16
24
  end
17
25
  end