gir_ffi 0.7.5 → 0.7.6

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.
Files changed (96) hide show
  1. checksums.yaml +4 -4
  2. data/Changelog.md +17 -1
  3. data/README.md +1 -1
  4. data/Rakefile +0 -7
  5. data/examples/main_loop.rb +12 -0
  6. data/lib/ffi-glib/array.rb +18 -5
  7. data/lib/ffi-glib/array_methods.rb +1 -1
  8. data/lib/ffi-glib/list.rb +1 -1
  9. data/lib/ffi-glib/list_methods.rb +1 -1
  10. data/lib/ffi-glib/main_loop.rb +51 -0
  11. data/lib/ffi-glib/ptr_array.rb +2 -2
  12. data/lib/ffi-glib/s_list.rb +1 -1
  13. data/lib/ffi-glib/variant.rb +3 -3
  14. data/lib/ffi-glib.rb +1 -0
  15. data/lib/ffi-gobject/initially_unowned.rb +1 -1
  16. data/lib/ffi-gobject/object.rb +14 -12
  17. data/lib/ffi-gobject/ruby_closure.rb +3 -2
  18. data/lib/ffi-gobject/value.rb +12 -16
  19. data/lib/ffi-gobject.rb +4 -21
  20. data/lib/ffi-gobject_introspection/i_base_info.rb +3 -3
  21. data/lib/ffi-gobject_introspection/i_interface_info.rb +1 -1
  22. data/lib/ffi-gobject_introspection/i_repository.rb +1 -1
  23. data/lib/ffi-gobject_introspection/lib.rb +1 -1
  24. data/lib/gir_ffi/arg_helper.rb +2 -2
  25. data/lib/gir_ffi/builder.rb +1 -1
  26. data/lib/gir_ffi/builders/argument_builder.rb +19 -17
  27. data/lib/gir_ffi/builders/argument_builder_collection.rb +51 -16
  28. data/lib/gir_ffi/builders/base_argument_builder.rb +20 -10
  29. data/lib/gir_ffi/builders/base_type_builder.rb +6 -5
  30. data/lib/gir_ffi/builders/callback_argument_builder.rb +5 -5
  31. data/lib/gir_ffi/builders/callback_builder.rb +0 -4
  32. data/lib/gir_ffi/builders/callback_return_value_builder.rb +11 -11
  33. data/lib/gir_ffi/builders/constant_builder.rb +2 -4
  34. data/lib/gir_ffi/builders/enum_builder.rb +7 -7
  35. data/lib/gir_ffi/builders/error_argument_builder.rb +16 -4
  36. data/lib/gir_ffi/builders/field_builder.rb +5 -17
  37. data/lib/gir_ffi/builders/function_builder.rb +36 -86
  38. data/lib/gir_ffi/builders/interface_builder.rb +2 -7
  39. data/lib/gir_ffi/builders/mapping_method_builder.rb +42 -33
  40. data/lib/gir_ffi/builders/marshalling_method_builder.rb +44 -33
  41. data/lib/gir_ffi/builders/method_template.rb +81 -0
  42. data/lib/gir_ffi/builders/module_builder.rb +5 -5
  43. data/lib/gir_ffi/builders/object_builder.rb +44 -25
  44. data/lib/gir_ffi/builders/property_builder.rb +6 -2
  45. data/lib/gir_ffi/builders/registered_type_builder.rb +1 -5
  46. data/lib/gir_ffi/builders/return_value_builder.rb +20 -15
  47. data/lib/gir_ffi/builders/signal_closure_builder.rb +3 -6
  48. data/lib/gir_ffi/builders/type_builder.rb +1 -1
  49. data/lib/gir_ffi/builders/unintrospectable_builder.rb +1 -5
  50. data/lib/gir_ffi/builders/user_defined_builder.rb +17 -21
  51. data/lib/gir_ffi/builders/vfunc_builder.rb +3 -6
  52. data/lib/gir_ffi/builders/with_layout.rb +2 -6
  53. data/lib/gir_ffi/callback_base.rb +10 -5
  54. data/lib/gir_ffi/class_base.rb +4 -7
  55. data/lib/gir_ffi/enum_base.rb +1 -1
  56. data/lib/gir_ffi/g_type.rb +21 -19
  57. data/lib/gir_ffi/in_out_pointer.rb +2 -4
  58. data/lib/gir_ffi/in_pointer.rb +9 -8
  59. data/lib/gir_ffi/info_ext/i_field_info.rb +1 -3
  60. data/lib/gir_ffi/info_ext/i_signal_info.rb +4 -4
  61. data/lib/gir_ffi/info_ext/i_type_info.rb +6 -6
  62. data/lib/gir_ffi/module_base.rb +3 -2
  63. data/lib/gir_ffi/object_base.rb +1 -1
  64. data/lib/gir_ffi/struct_base.rb +1 -1
  65. data/lib/gir_ffi/type_base.rb +2 -2
  66. data/lib/gir_ffi/unintrospectable_type_info.rb +2 -0
  67. data/lib/gir_ffi/version.rb +1 -1
  68. data/lib/gir_ffi/zero_terminated.rb +1 -1
  69. data/lib/gir_ffi-base/glib/strv.rb +2 -2
  70. data/lib/gir_ffi.rb +1 -1
  71. data/test/ffi-glib/array_test.rb +28 -0
  72. data/test/ffi-glib/byte_array_test.rb +1 -1
  73. data/test/ffi-glib/bytes_test.rb +1 -1
  74. data/test/ffi-gobject/object_test.rb +11 -1
  75. data/test/ffi-gobject/value_test.rb +12 -1
  76. data/test/ffi-gobject_introspection/i_base_info_test.rb +14 -0
  77. data/test/ffi-gobject_introspection/i_object_info_test.rb +8 -6
  78. data/test/ffi-gobject_introspection/i_registered_type_info_test.rb +24 -0
  79. data/test/ffi-gobject_introspection/i_type_info_test.rb +17 -0
  80. data/test/gir_ffi/builder_test.rb +3 -2
  81. data/test/gir_ffi/builders/argument_builder_test.rb +2 -2
  82. data/test/gir_ffi/builders/function_builder_test.rb +27 -27
  83. data/test/gir_ffi/builders/object_builder_test.rb +10 -0
  84. data/test/gir_ffi/builders/return_value_builder_test.rb +3 -3
  85. data/test/gir_ffi/builders/signal_closure_builder_test.rb +6 -6
  86. data/test/gir_ffi/in_out_pointer_test.rb +0 -2
  87. data/test/gir_ffi/info_ext/i_type_info_test.rb +1 -1
  88. data/test/gir_ffi_test_helper.rb +0 -4
  89. data/test/integration/generated_gimarshallingtests_test.rb +1 -1
  90. data/test/integration/generated_regress_test.rb +2 -2
  91. data/test/integration/idle_loop_test.rb +25 -0
  92. data/test/minitest/stats_plugin.rb +26 -0
  93. metadata +13 -62
  94. data/lib/gir_ffi/builders/null_argument_builder.rb +0 -12
  95. data/lib/gir_ffi/builders/null_builder.rb +0 -12
  96. data/tasks/yard.rake +0 -6
@@ -1,10 +1,10 @@
1
+ require 'gir_ffi/variable_name_generator'
1
2
  require 'gir_ffi/builders/argument_builder'
2
3
  require 'gir_ffi/return_value_info'
3
4
  require 'gir_ffi/error_argument_info'
4
5
  require 'gir_ffi/builders/return_value_builder'
5
6
  require 'gir_ffi/builders/error_argument_builder'
6
- require 'gir_ffi/builders/null_argument_builder'
7
- require 'gir_ffi/variable_name_generator'
7
+ require 'gir_ffi/builders/method_template'
8
8
 
9
9
  module GirFFI
10
10
  module Builders
@@ -13,116 +13,66 @@ module GirFFI
13
13
  class FunctionBuilder
14
14
  def initialize info
15
15
  @info = info
16
- end
17
-
18
- def generate
19
16
  vargen = GirFFI::VariableNameGenerator.new
20
- @argument_builders = @info.args.map {|arg| ArgumentBuilder.new vargen, arg }
17
+ @argument_builders = @info.args.map { |arg| ArgumentBuilder.new vargen, arg }
18
+ return_value_info = ReturnValueInfo.new(@info.return_type, @info.skip_return?)
21
19
  @return_value_builder = ReturnValueBuilder.new(vargen,
22
- ReturnValueInfo.new(@info.return_type, @info.skip_return?),
20
+ return_value_info,
23
21
  @info.constructor?)
24
-
25
- set_up_argument_relations
26
- setup_error_argument vargen
27
-
28
- filled_out_template
29
- end
30
-
31
- private
32
-
33
- def lib_module_name
34
- "#{@info.safe_namespace}::Lib"
35
- end
36
-
37
- def set_up_argument_relations
38
- alldata = @argument_builders.dup << @return_value_builder
39
-
40
- alldata.each do |data|
41
- if (idx = data.array_length_idx) >= 0
42
- other_data = @argument_builders[idx]
43
- data.length_arg = other_data
44
- other_data.array_arg = data
45
- end
46
- end
47
-
48
- @argument_builders.each do |data|
49
- if (idx = data.arginfo.closure) >= 0
50
- @argument_builders[idx].is_closure = true
51
- end
52
- end
22
+ @argument_builder_collection = ArgumentBuilderCollection.new(
23
+ @return_value_builder, @argument_builders,
24
+ error_argument_builder: error_argument(vargen))
25
+ @template = MethodTemplate.new(self, @argument_builder_collection)
53
26
  end
54
27
 
55
- def setup_error_argument vargen
56
- @errarg = if @info.throws?
57
- ErrorArgumentBuilder.new vargen, ErrorArgumentInfo.new
58
- else
59
- NullArgumentBuilder.new
60
- end
61
- end
62
-
63
- def filled_out_template
64
- meta = @info.method? ? '' : "self."
65
-
66
- code = "def #{meta}#{@info.safe_name} #{method_arguments.join(', ')}\n"
67
- code << method_body
68
- code << "\nend\n"
69
- end
70
-
71
- def method_body
72
- lines = preparation << function_call << post_processing
73
- lines << "return #{return_values.join(', ')}" if has_return_values?
74
- lines.flatten.join("\n").indent
28
+ def generate
29
+ @template.method_definition
75
30
  end
76
31
 
77
- def function_call
78
- "#{capture}#{lib_module_name}.#{@info.symbol} #{function_call_arguments.join(', ')}"
32
+ def method_name
33
+ @info.safe_name
79
34
  end
80
35
 
81
36
  def method_arguments
82
- @argument_builders.map(&:method_argument_name).compact
37
+ @argument_builder_collection.method_argument_names
83
38
  end
84
39
 
85
- def function_call_arguments
86
- ca = @argument_builders.map(&:callarg)
87
- ca << @errarg.callarg
88
- ca.unshift "self" if @info.method?
89
- ca.compact
40
+ def preparation
41
+ []
90
42
  end
91
43
 
92
- def preparation
93
- pr = @argument_builders.map(&:pre_conversion)
94
- pr << @errarg.pre
95
- pr.flatten
44
+ def invocation
45
+ "#{lib_name}.#{@info.symbol} #{function_call_arguments.join(', ')}"
96
46
  end
97
47
 
98
- def capture
99
- if has_capture?
100
- "#{@return_value_builder.capture_variable_name} = "
48
+ def result
49
+ if @argument_builder_collection.has_return_values?
50
+ ["return #{@argument_builder_collection.return_value_names.join(', ')}"]
101
51
  else
102
- ""
52
+ []
103
53
  end
104
54
  end
105
55
 
106
- def post_processing
107
- # FIXME: Sorting knows too much about internals of ArgumentBuilder.
108
- args = @argument_builders.sort_by {|arg| arg.type_info.array_length}
109
-
110
- result = args.map {|arg| arg.post_conversion}
111
- result.unshift @errarg.post
112
- result << @return_value_builder.post_conversion
56
+ def singleton_method?
57
+ !@info.method?
113
58
  end
114
59
 
115
- def return_values
116
- @return_values ||= ([@return_value_builder.return_value_name] +
117
- @argument_builders.map(&:return_value_name)).compact
60
+ private
61
+
62
+ def lib_name
63
+ "#{@info.safe_namespace}::Lib"
118
64
  end
119
65
 
120
- def has_return_values?
121
- !return_values.empty?
66
+ def error_argument vargen
67
+ if @info.throws?
68
+ ErrorArgumentBuilder.new vargen, ErrorArgumentInfo.new if @info.throws?
69
+ end
122
70
  end
123
71
 
124
- def has_capture?
125
- @return_value_builder.is_relevant?
72
+ def function_call_arguments
73
+ ca = @argument_builder_collection.call_argument_names
74
+ ca.unshift "self" if @info.method?
75
+ ca
126
76
  end
127
77
  end
128
78
  end
@@ -11,17 +11,12 @@ module GirFFI
11
11
 
12
12
  private
13
13
 
14
- # FIXME: The word 'class' is not really correct.
15
- def instantiate_class
16
- klass
17
- setup_module unless already_set_up
18
- end
19
-
20
14
  def klass
21
15
  @klass ||= get_or_define_module namespace_module, @classname
22
16
  end
23
17
 
24
- def setup_module
18
+ # FIXME: The word 'class' is not really correct.
19
+ def setup_class
25
20
  klass.extend InterfaceBase
26
21
  setup_constants
27
22
  stub_methods
@@ -1,6 +1,8 @@
1
+ require 'gir_ffi/variable_name_generator'
1
2
  require 'gir_ffi/builders/callback_argument_builder'
2
3
  require 'gir_ffi/builders/callback_return_value_builder'
3
4
  require 'gir_ffi/builders/argument_builder_collection'
5
+ require 'gir_ffi/builders/method_template'
4
6
 
5
7
  module GirFFI
6
8
  module Builders
@@ -9,43 +11,47 @@ module GirFFI
9
11
  # result from Ruby to C.
10
12
  class MappingMethodBuilder
11
13
  def self.for_callback argument_infos, return_value_info
12
- vargen = VariableNameGenerator.new
13
-
14
- argument_builders = argument_infos.map {|arg| CallbackArgumentBuilder.new vargen, arg }
15
- return_value_builder = CallbackReturnValueBuilder.new(vargen, return_value_info)
16
-
17
- new ArgumentBuilderCollection.new(return_value_builder, argument_builders)
14
+ new argument_infos, return_value_info
18
15
  end
19
16
 
20
17
  def self.for_vfunc receiver_info, argument_infos, return_value_info
21
- vargen = VariableNameGenerator.new
18
+ new receiver_info, argument_infos, return_value_info
19
+ end
22
20
 
23
- receiver_builder = CallbackArgumentBuilder.new vargen, receiver_info
24
- argument_builders = argument_infos.map {|arg| CallbackArgumentBuilder.new vargen, arg }
25
- return_value_builder = CallbackReturnValueBuilder.new(vargen, return_value_info)
21
+ def initialize receiver_info = nil, argument_infos, return_value_info
22
+ receiver_builder = make_argument_builder receiver_info if receiver_info
23
+ argument_builders = argument_infos.map { |info| make_argument_builder info }
24
+ return_value_builder =
25
+ CallbackReturnValueBuilder.new(variable_generator, return_value_info)
26
26
 
27
- new ArgumentBuilderCollection.new(return_value_builder, argument_builders,
28
- receiver_builder: receiver_builder)
27
+ @argument_builder_collection =
28
+ ArgumentBuilderCollection.new(return_value_builder, argument_builders,
29
+ receiver_builder: receiver_builder)
30
+ @template = MethodTemplate.new(self, @argument_builder_collection)
29
31
  end
30
32
 
31
- def initialize argument_builder_collection
32
- @argument_builder_collection = argument_builder_collection
33
+ def method_definition
34
+ @template.method_definition
33
35
  end
34
36
 
35
- def method_definition
36
- code = "def self.call_with_argument_mapping(#{method_arguments.join(', ')})"
37
- method_lines.each { |line| code << "\n #{line}" }
38
- code << "\nend\n"
37
+ def method_name
38
+ "call_with_argument_mapping"
39
+ end
40
+
41
+ def method_arguments
42
+ @method_arguments ||=
43
+ @argument_builder_collection.method_argument_names.dup.unshift('_proc')
44
+ end
45
+
46
+ def preparation
47
+ []
39
48
  end
40
49
 
41
- def method_lines
42
- @argument_builder_collection.parameter_preparation +
43
- call_to_proc +
44
- @argument_builder_collection.return_value_conversion +
45
- return_value
50
+ def invocation
51
+ "_proc.call(#{call_argument_list})"
46
52
  end
47
53
 
48
- def return_value
54
+ def result
49
55
  if (name = @argument_builder_collection.return_value_name)
50
56
  ["return #{name}"]
51
57
  else
@@ -53,19 +59,22 @@ module GirFFI
53
59
  end
54
60
  end
55
61
 
56
- def call_to_proc
57
- ["#{capture}_proc.call(#{@argument_builder_collection.call_argument_names.join(', ')})"]
62
+ def singleton_method?
63
+ true
58
64
  end
59
65
 
60
- def capture
61
- @capture ||= begin
62
- names = @argument_builder_collection.capture_variable_names
63
- names.any? ? "#{names.join(", ")} = " : ""
64
- end
66
+ private
67
+
68
+ def call_argument_list
69
+ @argument_builder_collection.call_argument_names.join(', ')
65
70
  end
66
71
 
67
- def method_arguments
68
- @method_arguments ||= @argument_builder_collection.method_argument_names.dup.unshift('_proc')
72
+ def variable_generator
73
+ @variable_generator ||= VariableNameGenerator.new
74
+ end
75
+
76
+ def make_argument_builder argument_info
77
+ CallbackArgumentBuilder.new variable_generator, argument_info
69
78
  end
70
79
  end
71
80
  end
@@ -1,6 +1,8 @@
1
+ require 'gir_ffi/variable_name_generator'
1
2
  require 'gir_ffi/builders/closure_argument_builder'
2
3
  require 'gir_ffi/builders/callback_return_value_builder'
3
4
  require 'gir_ffi/builders/argument_builder_collection'
5
+ require 'gir_ffi/builders/method_template'
4
6
 
5
7
  module GirFFI
6
8
  module Builders
@@ -9,35 +11,46 @@ module GirFFI
9
11
  # result from Ruby to C.
10
12
  class MarshallingMethodBuilder
11
13
  def self.for_signal receiver_info, argument_infos, return_value_info
12
- vargen = VariableNameGenerator.new
14
+ new receiver_info, argument_infos, return_value_info
15
+ end
13
16
 
14
- receiver_builder = ClosureArgumentBuilder.new vargen, receiver_info
15
- argument_builders = argument_infos.map {|arg| ClosureArgumentBuilder.new vargen, arg }
16
- return_value_builder = CallbackReturnValueBuilder.new(vargen, return_value_info)
17
+ def initialize receiver_info, argument_infos, return_value_info
18
+ receiver_builder = make_argument_builder receiver_info
19
+ argument_builders = argument_infos.map { |arg| make_argument_builder arg }
20
+ return_value_builder =
21
+ CallbackReturnValueBuilder.new(variable_generator, return_value_info)
17
22
 
18
- new ArgumentBuilderCollection.new(return_value_builder, argument_builders,
19
- receiver_builder: receiver_builder)
23
+ @argument_builder_collection =
24
+ ArgumentBuilderCollection.new(return_value_builder, argument_builders,
25
+ receiver_builder: receiver_builder)
26
+ @template = MethodTemplate.new(self, @argument_builder_collection)
20
27
  end
21
28
 
22
- def initialize argument_builder_collection
23
- @argument_builder_collection = argument_builder_collection
29
+ def method_definition
30
+ @template.method_definition
24
31
  end
25
32
 
26
- def method_definition
27
- code = "def self.marshaller(#{marshaller_arguments.join(', ')})"
28
- method_lines.each { |line| code << "\n #{line}" }
29
- code << "\nend\n"
33
+ def method_name
34
+ "marshaller"
35
+ end
36
+
37
+ def method_arguments
38
+ %w(closure return_value param_values _invocation_hint _marshal_data)
30
39
  end
31
40
 
32
- def method_lines
33
- param_values_unpack +
34
- @argument_builder_collection.parameter_preparation +
35
- call_to_closure +
36
- @argument_builder_collection.return_value_conversion +
37
- return_value
41
+ def preparation
42
+ if param_names.size == 1
43
+ ["#{param_names.first} = param_values.first.get_value_plain"]
44
+ else
45
+ ["#{param_names.join(", ")} = param_values.map(&:get_value_plain)"]
46
+ end
47
+ end
48
+
49
+ def invocation
50
+ "wrap(closure.to_ptr).invoke_block(#{call_argument_list})"
38
51
  end
39
52
 
40
- def return_value
53
+ def result
41
54
  if (name = @argument_builder_collection.return_value_name)
42
55
  ["return_value.set_value #{name}"]
43
56
  else
@@ -45,28 +58,26 @@ module GirFFI
45
58
  end
46
59
  end
47
60
 
48
- def call_to_closure
49
- ["#{capture}wrap(closure.to_ptr).invoke_block(#{@argument_builder_collection.call_argument_names.join(', ')})"]
61
+ def singleton_method?
62
+ true
50
63
  end
51
64
 
52
- def param_values_unpack
53
- ["#{method_arguments.join(", ")} = param_values.map(&:get_value_plain)" ]
65
+ private
66
+
67
+ def call_argument_list
68
+ @argument_builder_collection.call_argument_names.join(', ')
54
69
  end
55
70
 
56
- def capture
57
- @capture ||= begin
58
- names = @argument_builder_collection.capture_variable_names
59
- names.any? ? "#{names.join(", ")} = " : ""
60
- end
71
+ def param_names
72
+ @param_names ||= @argument_builder_collection.method_argument_names
61
73
  end
62
74
 
63
- def method_arguments
64
- # FIXME: Don't add _ if method_argument_names has more than one element
65
- @method_arguments ||= @argument_builder_collection.method_argument_names.dup.push('_')
75
+ def variable_generator
76
+ @variable_generator ||= VariableNameGenerator.new
66
77
  end
67
78
 
68
- def marshaller_arguments
69
- %w(closure return_value param_values _invocation_hint _marshal_data)
79
+ def make_argument_builder argument_info
80
+ ClosureArgumentBuilder.new variable_generator, argument_info
70
81
  end
71
82
  end
72
83
  end
@@ -0,0 +1,81 @@
1
+ module GirFFI
2
+ module Builders
3
+ # Encapsulates the general structure of generated methods, consisting of a
4
+ # preparation phase where arguments are converted to the form needed by the
5
+ # main call of the method, the main call itself, a post-processing phase
6
+ # where the return values and any 'out' arguments of the main call are
7
+ # converted into a form suitable for returning, and finally the returning
8
+ # of said values to the caller.
9
+ #
10
+ # The different method builders collaborate with MethodTemplate to build
11
+ # the desired method.
12
+ class MethodTemplate
13
+ def initialize builder, argument_builder_collection
14
+ @builder = builder
15
+ @argument_builder_collection = argument_builder_collection
16
+ end
17
+
18
+ def method_definition
19
+ code = "def #{qualified_method_name}"
20
+ code << "(#{method_arguments.join(', ')})" if method_arguments.any?
21
+ method_lines.each { |line| code << "\n #{line}" }
22
+ code << "\nend\n"
23
+ end
24
+
25
+ private
26
+
27
+ def qualified_method_name
28
+ "#{@builder.singleton_method? ? 'self.' : ''}#{@builder.method_name}"
29
+ end
30
+
31
+ def method_arguments
32
+ @builder.method_arguments
33
+ end
34
+
35
+ def method_lines
36
+ method_preparation +
37
+ parameter_preparation +
38
+ invocation +
39
+ return_value_conversion +
40
+ result
41
+ end
42
+
43
+ def method_preparation
44
+ @builder.preparation
45
+ end
46
+
47
+ def parameter_preparation
48
+ @argument_builder_collection.parameter_preparation
49
+ end
50
+
51
+ def invocation
52
+ if result_name_list.empty?
53
+ plain_invocation
54
+ else
55
+ capturing_invocation
56
+ end
57
+ end
58
+
59
+ def return_value_conversion
60
+ @argument_builder_collection.return_value_conversion
61
+ end
62
+
63
+ def result
64
+ @builder.result
65
+ end
66
+
67
+ def result_name_list
68
+ @result_name_list ||=
69
+ @argument_builder_collection.capture_variable_names.join(", ")
70
+ end
71
+
72
+ def capturing_invocation
73
+ ["#{result_name_list} = #{@builder.invocation}"]
74
+ end
75
+
76
+ def plain_invocation
77
+ [@builder.invocation]
78
+ end
79
+ end
80
+ end
81
+ end
@@ -10,11 +10,11 @@ module GirFFI
10
10
  class ModuleBuilder
11
11
  include BuilderHelper
12
12
 
13
- def initialize namespace, version=nil
13
+ def initialize namespace, version = nil
14
14
  @namespace = namespace
15
15
  @version = version
16
16
  # FIXME: Pass safe namespace as an argument
17
- @safe_namespace = @namespace.gsub(/^(.)/) { $1.upcase }
17
+ @safe_namespace = @namespace.gsub(/^./, &:upcase)
18
18
  end
19
19
 
20
20
  def generate
@@ -34,8 +34,8 @@ module GirFFI
34
34
  def build_namespaced_class classname
35
35
  info = gir.find_by_name @namespace, classname.to_s
36
36
  unless info
37
- raise NameError.new(
38
- "Class #{classname} not found in namespace #{@namespace}")
37
+ raise NameError,
38
+ "Class #{classname} not found in namespace #{@namespace}"
39
39
  end
40
40
  Builder.build_class info
41
41
  end
@@ -70,7 +70,7 @@ module GirFFI
70
70
  end
71
71
 
72
72
  def already_set_up
73
- @module.respond_to? :method_missing
73
+ @module.const_defined? :GIR_FFI_BUILDER
74
74
  end
75
75
 
76
76
  def setup_lib_for_ffi
@@ -9,18 +9,24 @@ module GirFFI
9
9
  class ObjectBuilder < RegisteredTypeBuilder
10
10
  include WithLayout
11
11
 
12
- def find_signal signal_name
13
- signal_definers.each do |inf|
14
- sig = inf.find_signal signal_name
15
- return sig if sig
12
+ # Dummy builder for the ObjectBase class
13
+ class ObjectBaseBuilder
14
+ def build_class
15
+ ObjectBase
16
+ end
17
+
18
+ def ancestor_infos
19
+ []
16
20
  end
17
- superclass.find_signal signal_name or
21
+ end
22
+
23
+ def find_signal signal_name
24
+ seek_in_ancestor_infos { |info| info.find_signal signal_name } or
18
25
  raise "Signal #{signal_name} not found"
19
26
  end
20
27
 
21
28
  def find_property property_name
22
- info.find_property property_name or
23
- superclass.find_property property_name or
29
+ seek_in_ancestor_infos { |info| info.find_property property_name } or
24
30
  raise "Property #{property_name} not found"
25
31
  end
26
32
 
@@ -28,6 +34,10 @@ module GirFFI
28
34
  @object_class_struct ||= Builder.build_class object_class_struct_info
29
35
  end
30
36
 
37
+ def ancestor_infos
38
+ @ancestor_infos ||= [info] + info.interfaces + parent_ancestor_infos
39
+ end
40
+
31
41
  private
32
42
 
33
43
  def setup_class
@@ -48,24 +58,29 @@ module GirFFI
48
58
  FFI::Struct
49
59
  end
50
60
 
51
- def parent
52
- unless defined? @parent
53
- pr = info.parent
54
- if pr.nil? or (pr.safe_name == @classname and pr.namespace == @namespace)
55
- @parent = nil
56
- else
57
- @parent = pr
58
- end
61
+ def parent_info
62
+ unless defined? @parent_info
63
+ @parent_info = if (parent = info.parent) && parent != info
64
+ parent
65
+ end
59
66
  end
60
- @parent
67
+ @parent_info
61
68
  end
62
69
 
63
70
  def superclass
64
- @superclass ||= if parent
65
- Builder.build_class parent
66
- else
67
- ObjectBase
68
- end
71
+ @superclass ||= parent_builder.build_class
72
+ end
73
+
74
+ def parent_builder
75
+ @parent_builder ||= if parent_info
76
+ Builders::TypeBuilder.builder_for(parent_info)
77
+ else
78
+ ObjectBaseBuilder.new
79
+ end
80
+ end
81
+
82
+ def parent_ancestor_infos
83
+ @parent_ancestor_infos ||= parent_builder.ancestor_infos
69
84
  end
70
85
 
71
86
  def setup_property_accessors
@@ -99,10 +114,6 @@ module GirFFI
99
114
  end
100
115
  end
101
116
 
102
- def signal_definers
103
- [info] + info.interfaces
104
- end
105
-
106
117
  def interfaces
107
118
  info.interfaces.map do |ifinfo|
108
119
  GirFFI::Builder.build_class ifinfo
@@ -112,6 +123,14 @@ module GirFFI
112
123
  def object_class_struct_info
113
124
  @object_class_struct_info ||= info.class_struct
114
125
  end
126
+
127
+ def seek_in_ancestor_infos
128
+ ancestor_infos.each do |info|
129
+ item = yield info
130
+ return item if item
131
+ end
132
+ nil
133
+ end
115
134
  end
116
135
  end
117
136
  end
@@ -23,6 +23,7 @@ module GirFFI
23
23
  container_class.class_eval setter_def
24
24
  end
25
25
 
26
+ # TODO: Fix argument builders so converting_getter_def can always be used.
26
27
  def getter_def
27
28
  case type_info.tag
28
29
  when :glist, :ghash
@@ -32,6 +33,7 @@ module GirFFI
32
33
  end
33
34
  end
34
35
 
36
+ # TODO: Fix argument builders so converting_setter_def can always be used.
35
37
  def setter_def
36
38
  case type_info.flattened_tag
37
39
  when :glist, :ghash, :strv
@@ -43,10 +45,12 @@ module GirFFI
43
45
 
44
46
  private
45
47
 
48
+ # TODO: Use a builder like MarshallingMethodBuilder
46
49
  def converting_getter_def
50
+ capture = getter_builder.capture_variable_name
47
51
  <<-CODE.reset_indentation
48
52
  def #{getter_name}
49
- #{getter_builder.capture_variable_name} = get_property("#{property_name}").get_value_plain
53
+ #{capture} = get_property("#{property_name}").get_value_plain
50
54
  #{getter_builder.post_conversion.join("\n")}
51
55
  #{getter_builder.return_value_name}
52
56
  end
@@ -70,7 +74,7 @@ module GirFFI
70
74
  <<-CODE.reset_indentation
71
75
  def #{setter_name} value
72
76
  #{setter_builder.pre_conversion.join("\n")}
73
- set_property("#{property_name}", #{setter_builder.callarg})
77
+ set_property("#{property_name}", #{setter_builder.call_argument_name})
74
78
  end
75
79
  CODE
76
80
  end