gir_ffi 0.7.5 → 0.7.6

Sign up to get free protection for your applications and to get access to all the features.
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