gir_ffi 0.6.6 → 0.6.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (166) hide show
  1. data/History.txt +14 -0
  2. data/TODO.rdoc +23 -5
  3. data/lib/ffi-glib/array.rb +14 -15
  4. data/lib/ffi-glib/container_class_methods.rb +0 -1
  5. data/lib/ffi-glib/hash_table.rb +3 -4
  6. data/lib/ffi-glib/ptr_array.rb +12 -4
  7. data/lib/ffi-glib/sized_array.rb +27 -7
  8. data/lib/ffi-gobject.rb +14 -15
  9. data/lib/ffi-gobject/closure.rb +1 -1
  10. data/lib/ffi-gobject/object.rb +40 -15
  11. data/lib/ffi-gobject/ruby_closure.rb +0 -1
  12. data/lib/ffi-gobject/value.rb +45 -21
  13. data/lib/ffi-gobject_introspection/i_arg_info.rb +4 -0
  14. data/lib/ffi-gobject_introspection/i_base_info.rb +42 -2
  15. data/lib/ffi-gobject_introspection/i_callable_info.rb +8 -0
  16. data/lib/ffi-gobject_introspection/i_enum_info.rb +1 -4
  17. data/lib/ffi-gobject_introspection/i_interface_info.rb +1 -0
  18. data/lib/ffi-gobject_introspection/i_object_info.rb +2 -0
  19. data/lib/ffi-gobject_introspection/i_repository.rb +2 -3
  20. data/lib/ffi-gobject_introspection/i_struct_info.rb +3 -8
  21. data/lib/ffi-gobject_introspection/lib.rb +3 -0
  22. data/lib/gir_ffi-base.rb +3 -1
  23. data/lib/gir_ffi-base/gir_ffi/struct.rb +27 -0
  24. data/lib/gir_ffi-base/glib/boolean.rb +13 -1
  25. data/lib/gir_ffi-base/gobject.rb +7 -0
  26. data/lib/gir_ffi-base/gobject/lib.rb +0 -2
  27. data/lib/gir_ffi.rb +1 -3
  28. data/lib/gir_ffi/arg_helper.rb +4 -85
  29. data/lib/gir_ffi/builder.rb +5 -5
  30. data/lib/gir_ffi/builder_helper.rb +7 -0
  31. data/lib/gir_ffi/builders/argument_builder.rb +132 -0
  32. data/lib/gir_ffi/{base_argument_builder.rb → builders/base_argument_builder.rb} +32 -41
  33. data/lib/gir_ffi/builders/base_type_builder.rb +47 -0
  34. data/lib/gir_ffi/builders/callback_builder.rb +38 -0
  35. data/lib/gir_ffi/builders/constant_builder.rb +18 -0
  36. data/lib/gir_ffi/builders/enum_builder.rb +62 -0
  37. data/lib/gir_ffi/builders/error_argument_builder.rb +18 -0
  38. data/lib/gir_ffi/builders/field_builder.rb +94 -0
  39. data/lib/gir_ffi/builders/function_builder.rb +123 -0
  40. data/lib/gir_ffi/builders/interface_builder.rb +29 -0
  41. data/lib/gir_ffi/builders/mapping_method_builder.rb +88 -0
  42. data/lib/gir_ffi/builders/module_builder.rb +124 -0
  43. data/lib/gir_ffi/{null_argument_builder.rb → builders/null_argument_builder.rb} +0 -0
  44. data/lib/gir_ffi/builders/null_builder.rb +11 -0
  45. data/lib/gir_ffi/builders/object_builder.rb +123 -0
  46. data/lib/gir_ffi/{builder/property.rb → builders/property_builder.rb} +0 -0
  47. data/lib/gir_ffi/builders/registered_type_builder.rb +50 -0
  48. data/lib/gir_ffi/builders/return_value_builder.rb +68 -0
  49. data/lib/gir_ffi/builders/signal_builder.rb +91 -0
  50. data/lib/gir_ffi/builders/struct_builder.rb +35 -0
  51. data/lib/gir_ffi/builders/type_builder.rb +40 -0
  52. data/lib/gir_ffi/builders/unintrospectable_builder.rb +35 -0
  53. data/lib/gir_ffi/builders/union_builder.rb +34 -0
  54. data/lib/gir_ffi/builders/user_defined_builder.rb +103 -0
  55. data/lib/gir_ffi/builders/with_layout.rb +55 -0
  56. data/lib/gir_ffi/builders/with_methods.rb +44 -0
  57. data/lib/gir_ffi/callback_base.rb +31 -0
  58. data/lib/gir_ffi/class_base.rb +16 -10
  59. data/lib/gir_ffi/enum_base.rb +8 -4
  60. data/lib/gir_ffi/ffi_ext/pointer.rb +19 -2
  61. data/lib/gir_ffi/in_out_pointer.rb +38 -39
  62. data/lib/gir_ffi/in_pointer.rb +33 -18
  63. data/lib/gir_ffi/info_ext.rb +0 -4
  64. data/lib/gir_ffi/info_ext/i_arg_info.rb +0 -18
  65. data/lib/gir_ffi/info_ext/i_callable_info.rb +2 -1
  66. data/lib/gir_ffi/info_ext/i_registered_type_info.rb +6 -8
  67. data/lib/gir_ffi/info_ext/i_signal_info.rb +6 -21
  68. data/lib/gir_ffi/info_ext/i_type_info.rb +54 -29
  69. data/lib/gir_ffi/info_ext/safe_constant_name.rb +8 -1
  70. data/lib/gir_ffi/interface_base.rb +1 -1
  71. data/lib/gir_ffi/module_base.rb +5 -1
  72. data/lib/gir_ffi/object_base.rb +5 -1
  73. data/lib/gir_ffi/setter_argument_info.rb +4 -0
  74. data/lib/gir_ffi/signal_base.rb +21 -0
  75. data/lib/gir_ffi/struct_base.rb +24 -0
  76. data/lib/gir_ffi/type_base.rb +11 -0
  77. data/lib/gir_ffi/type_map.rb +4 -2
  78. data/lib/gir_ffi/union_base.rb +24 -0
  79. data/lib/gir_ffi/version.rb +1 -1
  80. data/tasks/test.rake +73 -7
  81. data/test/base_test_helper.rb +3 -19
  82. data/test/ffi-glib/array_test.rb +6 -0
  83. data/test/ffi-glib/ptr_array_test.rb +13 -0
  84. data/test/ffi-glib/ruby_closure_test.rb +7 -7
  85. data/test/ffi-glib/sized_array_test.rb +2 -2
  86. data/test/ffi-gobject/gobject_test.rb +3 -12
  87. data/test/ffi-gobject/object_test.rb +33 -2
  88. data/test/ffi-gobject/value_test.rb +114 -1
  89. data/test/ffi-gobject_introspection/i_enum_info_test.rb +2 -2
  90. data/test/ffi-gobject_introspection/i_object_info_test.rb +3 -3
  91. data/test/ffi-gobject_introspection/i_repository_test.rb +26 -21
  92. data/test/ffi-gobject_test.rb +14 -14
  93. data/test/gir_ffi-base/glib/boolean_test.rb +6 -0
  94. data/test/gir_ffi/arg_helper_test.rb +2 -122
  95. data/test/gir_ffi/builder_test.rb +67 -204
  96. data/test/gir_ffi/{argument_builder_test.rb → builders/argument_builder_test.rb} +230 -108
  97. data/test/gir_ffi/builders/base_argument_builder_test.rb +5 -0
  98. data/test/gir_ffi/builders/callback_builder_test.rb +50 -0
  99. data/test/gir_ffi/builders/constant_builder_test.rb +4 -0
  100. data/test/gir_ffi/{builder/type/enum_test.rb → builders/enum_builder_test.rb} +2 -3
  101. data/test/gir_ffi/builders/field_builder_test.rb +94 -0
  102. data/test/gir_ffi/{function_builder_test.rb → builders/function_builder_test.rb} +43 -24
  103. data/test/gir_ffi/{builder/type/interface_test.rb → builders/interface_builder_test.rb} +2 -2
  104. data/test/gir_ffi/{builder/module_test.rb → builders/module_builder_test.rb} +12 -13
  105. data/test/gir_ffi/{builder/type/object_test.rb → builders/object_builder_test.rb} +9 -9
  106. data/test/gir_ffi/{return_value_builder_test.rb → builders/return_value_builder_test.rb} +94 -58
  107. data/test/gir_ffi/builders/signal_builder_test.rb +62 -0
  108. data/test/gir_ffi/{builder/type/struct_test.rb → builders/struct_builder_test.rb} +36 -19
  109. data/test/gir_ffi/{builder/type/unintrospectable_test.rb → builders/unintrospectable_builder_test.rb} +3 -3
  110. data/test/gir_ffi/builders/union_builder_test.rb +29 -0
  111. data/test/gir_ffi/{builder/type/user_defined_test.rb → builders/user_defined_builder_test.rb} +2 -2
  112. data/test/gir_ffi/callback_base_test.rb +11 -0
  113. data/test/gir_ffi/class_base_test.rb +22 -22
  114. data/test/gir_ffi/ffi_ext/pointer_test.rb +18 -0
  115. data/test/gir_ffi/in_out_pointer_test.rb +0 -7
  116. data/test/gir_ffi/in_pointer_test.rb +27 -3
  117. data/test/gir_ffi/info_ext/i_signal_info_test.rb +16 -44
  118. data/test/gir_ffi/info_ext/i_type_info_test.rb +315 -74
  119. data/test/gir_ffi/info_ext/safe_constant_name_test.rb +6 -0
  120. data/test/gir_ffi/interface_base_test.rb +3 -5
  121. data/test/gir_ffi/object_base_test.rb +10 -6
  122. data/test/gir_ffi/type_map_test.rb +2 -2
  123. data/test/gir_ffi/unintrospectable_type_info_test.rb +2 -2
  124. data/test/gir_ffi_test_helper.rb +12 -4
  125. data/test/integration/generated_gimarshallingtests_test.rb +436 -76
  126. data/test/integration/generated_gio_test.rb +5 -11
  127. data/test/integration/generated_gobject_test.rb +8 -0
  128. data/test/integration/generated_regress_test.rb +755 -309
  129. data/test/integration/generated_secret_test.rb +2 -1
  130. metadata +73 -72
  131. data/lib/ffi-gobject/ruby_style.rb +0 -23
  132. data/lib/gir_ffi/argument_builder.rb +0 -154
  133. data/lib/gir_ffi/builder/field.rb +0 -60
  134. data/lib/gir_ffi/builder/module.rb +0 -127
  135. data/lib/gir_ffi/builder/type.rb +0 -39
  136. data/lib/gir_ffi/builder/type/base.rb +0 -48
  137. data/lib/gir_ffi/builder/type/callback.rb +0 -30
  138. data/lib/gir_ffi/builder/type/constant.rb +0 -22
  139. data/lib/gir_ffi/builder/type/enum.rb +0 -66
  140. data/lib/gir_ffi/builder/type/interface.rb +0 -33
  141. data/lib/gir_ffi/builder/type/object.rb +0 -134
  142. data/lib/gir_ffi/builder/type/registered_type.rb +0 -62
  143. data/lib/gir_ffi/builder/type/struct.rb +0 -34
  144. data/lib/gir_ffi/builder/type/unintrospectable.rb +0 -39
  145. data/lib/gir_ffi/builder/type/union.rb +0 -34
  146. data/lib/gir_ffi/builder/type/user_defined.rb +0 -107
  147. data/lib/gir_ffi/builder/type/with_layout.rb +0 -62
  148. data/lib/gir_ffi/builder/type/with_methods.rb +0 -64
  149. data/lib/gir_ffi/callback.rb +0 -72
  150. data/lib/gir_ffi/callback_helper.rb +0 -11
  151. data/lib/gir_ffi/error_argument_builder.rb +0 -17
  152. data/lib/gir_ffi/function_builder.rb +0 -112
  153. data/lib/gir_ffi/info_ext/i_enum_info.rb +0 -11
  154. data/lib/gir_ffi/info_ext/i_object_info.rb +0 -11
  155. data/lib/gir_ffi/info_ext/i_struct_info.rb +0 -11
  156. data/lib/gir_ffi/info_ext/i_union_info.rb +0 -12
  157. data/lib/gir_ffi/return_value_builder.rb +0 -81
  158. data/test/ffi-gobject/ruby_style_test.rb +0 -38
  159. data/test/gir_ffi/base_argument_builder_test.rb +0 -13
  160. data/test/gir_ffi/builder/type/callback_test.rb +0 -6
  161. data/test/gir_ffi/builder/type/constant_test.rb +0 -4
  162. data/test/gir_ffi/builder/type/union_test.rb +0 -12
  163. data/test/gir_ffi/callback_helper_test.rb +0 -10
  164. data/test/gir_ffi/callback_test.rb +0 -49
  165. data/test/gir_ffi/info_ext/i_arg_info_test.rb +0 -39
  166. data/test/gir_ffi/info_ext/i_object_info_test.rb +0 -14
@@ -0,0 +1,123 @@
1
+ require 'gir_ffi/builders/argument_builder'
2
+ require 'gir_ffi/builders/return_value_builder'
3
+ require 'gir_ffi/builders/error_argument_builder'
4
+ require 'gir_ffi/builders/null_argument_builder'
5
+ require 'gir_ffi/variable_name_generator'
6
+
7
+ module GirFFI
8
+ module Builders
9
+ # Implements the creation of a Ruby function definition out of a GIR
10
+ # IFunctionInfo.
11
+ class FunctionBuilder
12
+ def initialize info
13
+ @info = info
14
+ end
15
+
16
+ def generate
17
+ vargen = GirFFI::VariableNameGenerator.new
18
+ @argument_builders = @info.args.map {|arg| ArgumentBuilder.new vargen, arg }
19
+ @return_value_builder = ReturnValueBuilder.new(vargen,
20
+ @info.return_type,
21
+ @info.constructor?,
22
+ @info.skip_return?)
23
+
24
+ link_array_length_arguments
25
+ setup_error_argument vargen
26
+ return filled_out_template
27
+ end
28
+
29
+ private
30
+
31
+ def libmodule
32
+ Object.const_get(@info.safe_namespace)::Lib
33
+ end
34
+
35
+ def link_array_length_arguments
36
+ alldata = @argument_builders.dup << @return_value_builder
37
+
38
+ alldata.each {|data|
39
+ idx = data.type_info.array_length
40
+ if idx > -1
41
+ other_data = @argument_builders[idx]
42
+ data.length_arg = other_data
43
+ other_data.array_arg = data
44
+ end
45
+ }
46
+ end
47
+
48
+ def setup_error_argument vargen
49
+ klass = @info.throws? ? ErrorArgumentBuilder : NullArgumentBuilder
50
+ @errarg = klass.new vargen, nil, nil, :error
51
+ end
52
+
53
+ def filled_out_template
54
+ meta = @info.method? ? '' : "self."
55
+
56
+ code = "def #{meta}#{@info.safe_name} #{method_arguments.join(', ')}\n"
57
+ code << method_body
58
+ code << "\nend\n"
59
+ end
60
+
61
+ def method_body
62
+ lines = preparation << function_call << post_processing << cleanup
63
+ lines << "return #{return_values.join(', ')}" if has_return_values?
64
+ lines.flatten.join("\n").indent
65
+ end
66
+
67
+ def function_call
68
+ "#{capture}#{libmodule}.#{@info.symbol} #{function_call_arguments.join(', ')}"
69
+ end
70
+
71
+ def method_arguments
72
+ @argument_builders.map(&:inarg).compact
73
+ end
74
+
75
+ def function_call_arguments
76
+ ca = @argument_builders.map(&:callarg)
77
+ ca << @errarg.callarg
78
+ ca.unshift "self" if @info.method?
79
+ ca.compact
80
+ end
81
+
82
+ def preparation
83
+ pr = @argument_builders.map(&:pre)
84
+ pr << @errarg.pre
85
+ pr.flatten
86
+ end
87
+
88
+ def capture
89
+ if has_capture?
90
+ "#{@return_value_builder.callarg} = "
91
+ else
92
+ ""
93
+ end
94
+ end
95
+
96
+ def post_processing
97
+ # FIXME: Sorting knows too much about internals of ArgumentBuilder.
98
+ args = @argument_builders.sort_by {|arg| arg.type_info.array_length}
99
+ args << @return_value_builder
100
+ args.unshift @errarg
101
+
102
+ args.map {|arg| arg.post}
103
+ end
104
+
105
+ def cleanup
106
+ @argument_builders.map {|item| item.cleanup}
107
+ end
108
+
109
+ def return_values
110
+ @return_values ||= ([@return_value_builder.retval] +
111
+ @argument_builders.map(&:retval)).compact
112
+ end
113
+
114
+ def has_return_values?
115
+ !return_values.empty?
116
+ end
117
+
118
+ def has_capture?
119
+ @return_value_builder.is_relevant?
120
+ end
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,29 @@
1
+ require 'gir_ffi/builders/registered_type_builder'
2
+ require 'gir_ffi/builders/with_methods'
3
+ require 'gir_ffi/interface_base'
4
+
5
+ module GirFFI
6
+ module Builders
7
+ # Implements the creation of a module representing an Interface.
8
+ class InterfaceBuilder < RegisteredTypeBuilder
9
+ include WithMethods
10
+
11
+ private
12
+
13
+ # FIXME: The word 'class' is not really correct.
14
+ def instantiate_class
15
+ @klass = optionally_define_constant(namespace_module, @classname) do
16
+ ::Module.new
17
+ end
18
+ setup_module unless already_set_up
19
+ end
20
+
21
+ def setup_module
22
+ @klass.extend InterfaceBase
23
+ setup_constants
24
+ stub_methods
25
+ setup_gtype_getter
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,88 @@
1
+ require 'gir_ffi/builders/return_value_builder'
2
+
3
+ module GirFFI
4
+ module Builders
5
+ # Implements the creation mapping method for a callback or signal
6
+ # handler. This method converts arguments from C to Ruby, and the
7
+ # result from Ruby to C.
8
+ class MappingMethodBuilder
9
+ # TODO: Make CallbackArgumentBuilder accept argument name
10
+ # TODO: Fix name of #post method
11
+ class CallbackArgumentBuilder < ReturnValueBuilder
12
+ def post
13
+ if specialized_type_tag == :enum
14
+ ["#{retname} = #{argument_class_name}[#{callarg}]"]
15
+ else
16
+ super
17
+ end
18
+ end
19
+
20
+ def retval
21
+ if specialized_type_tag == :enum
22
+ retname
23
+ else
24
+ super
25
+ end
26
+ end
27
+ end
28
+
29
+ def initialize argument_infos, return_type_info
30
+ @argument_infos = argument_infos
31
+ @return_type_info = return_type_info
32
+ end
33
+
34
+ attr_reader :argument_infos
35
+ attr_reader :return_type_info
36
+
37
+ def method_definition
38
+ code = "def self.call_with_argument_mapping(#{method_arguments.join(', ')})"
39
+ method_lines.each { |line| code << "\n #{line}" }
40
+ code << "\nend\n"
41
+ end
42
+
43
+ def method_lines
44
+ lines = argument_builders.map(&:post).flatten +
45
+ ["#{capture}_proc.call(#{call_arguments.join(', ')})"] +
46
+ return_value_builder.post
47
+ lines << "return #{return_value_builder.retval}" if return_value_builder.is_relevant?
48
+ lines
49
+ end
50
+
51
+ def capture
52
+ @capture ||= return_value_builder.is_relevant? ?
53
+ "#{return_value_builder.callarg} = " :
54
+ ""
55
+ end
56
+
57
+ def call_arguments
58
+ @call_arguments ||= argument_builders.map(&:retval)
59
+ end
60
+
61
+ def method_arguments
62
+ @method_arguments ||= argument_builders.map(&:callarg).unshift('_proc')
63
+ end
64
+
65
+ def return_value_builder
66
+ @return_value_builder ||= ReturnValueBuilder.new(vargen, return_type_info)
67
+ end
68
+
69
+ def argument_builders
70
+ unless defined?(@argument_builders)
71
+ @argument_builders = argument_infos.map {|arg|
72
+ CallbackArgumentBuilder.new vargen, arg.argument_type }
73
+ argument_infos.each do |arg|
74
+ if (idx = arg.closure) >= 0
75
+ @argument_builders[idx].is_closure = true
76
+ end
77
+ end
78
+ end
79
+ @argument_builders
80
+ end
81
+
82
+ def vargen
83
+ @vargen ||= GirFFI::VariableNameGenerator.new
84
+ end
85
+ end
86
+ end
87
+ end
88
+
@@ -0,0 +1,124 @@
1
+ require 'gir_ffi/builder_helper'
2
+ require 'gir_ffi/module_base'
3
+ require 'gir_ffi/builders/function_builder'
4
+ require 'indentation'
5
+
6
+ module GirFFI
7
+ module Builders
8
+ # Builds a module based on information found in the introspection
9
+ # repository.
10
+ class ModuleBuilder
11
+ include BuilderHelper
12
+
13
+ def initialize namespace, version=nil
14
+ @namespace = namespace
15
+ @version = version
16
+ # FIXME: Pass safe namespace as an argument
17
+ @safe_namespace = @namespace.gsub(/^(.)/) { $1.upcase }
18
+ end
19
+
20
+ def generate
21
+ build_module
22
+ end
23
+
24
+ def setup_method method
25
+ go = function_introspection_data method.to_s
26
+
27
+ return false if go.nil?
28
+
29
+ modul = build_module
30
+
31
+ Builder.attach_ffi_function libmodule, go
32
+ definition = function_definition go
33
+ modul.class_eval definition
34
+
35
+ true
36
+ end
37
+
38
+ def build_namespaced_class classname
39
+ info = gir.find_by_name @namespace, classname.to_s
40
+ if info.nil?
41
+ raise NameError.new(
42
+ "Class #{classname} not found in namespace #{@namespace}")
43
+ end
44
+ Builder.build_class info
45
+ end
46
+
47
+ def build_module
48
+ unless defined? @module
49
+ build_dependencies
50
+ instantiate_module
51
+ setup_lib_for_ffi
52
+ setup_module unless already_set_up
53
+ end
54
+ @module
55
+ end
56
+
57
+ private
58
+
59
+ def build_dependencies
60
+ deps = gir.dependencies @namespace
61
+ deps.each {|dep|
62
+ name, version = dep.split '-'
63
+ Builder.build_module name, version
64
+ }
65
+ end
66
+
67
+ def instantiate_module
68
+ @module = get_or_define_module ::Object, @safe_namespace
69
+ end
70
+
71
+ def setup_module
72
+ @module.extend ModuleBase
73
+ @module.const_set :GIR_FFI_BUILDER, self
74
+ end
75
+
76
+ def already_set_up
77
+ @module.respond_to? :method_missing
78
+ end
79
+
80
+ def setup_lib_for_ffi
81
+ @lib = get_or_define_module @module, :Lib
82
+
83
+ unless (class << @lib; self.include? GirFFI::Library; end)
84
+ @lib.extend GirFFI::Library
85
+ @lib.ffi_lib_flags :global, :lazy
86
+ libspec = gir.shared_library(@namespace)
87
+ unless libspec.nil?
88
+ @lib.ffi_lib(*libspec.split(/,/))
89
+ end
90
+ end
91
+ end
92
+
93
+ def sub_builder info
94
+ if info.info_type == :function
95
+ FunctionBuilder.new info
96
+ else
97
+ TypeBuilder.builder_for info
98
+ end
99
+ end
100
+
101
+ def libmodule
102
+ @module.const_get(:Lib)
103
+ end
104
+
105
+ def function_introspection_data function
106
+ info = gir.find_by_name @namespace, function.to_s
107
+ return nil if info.nil?
108
+ info.info_type == :function ? info : nil
109
+ end
110
+
111
+ def function_definition info
112
+ FunctionBuilder.new(info).generate
113
+ end
114
+
115
+ def gir
116
+ unless defined? @gir
117
+ @gir = GObjectIntrospection::IRepository.default
118
+ @gir.require @namespace, @version
119
+ end
120
+ @gir
121
+ end
122
+ end
123
+ end
124
+ end
@@ -0,0 +1,11 @@
1
+ module GirFFI
2
+ class NullBuilder
3
+ def find_signal _
4
+ nil
5
+ end
6
+
7
+ def find_property _
8
+ nil
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,123 @@
1
+ require 'gir_ffi/builders/registered_type_builder'
2
+ require 'gir_ffi/builders/with_layout'
3
+ require 'gir_ffi/builders/with_methods'
4
+ require 'gir_ffi/builders/property_builder'
5
+ require 'gir_ffi/object_base'
6
+
7
+ module GirFFI
8
+ module Builders
9
+ # Implements the creation of a class representing a GObject Object.
10
+ class ObjectBuilder < RegisteredTypeBuilder
11
+ include WithMethods
12
+ include WithLayout
13
+
14
+ def find_signal signal_name
15
+ signal_definers.each do |inf|
16
+ sig = inf.find_signal signal_name
17
+ return sig if sig
18
+ end
19
+ superclass.find_signal signal_name or
20
+ raise "Signal #{signal_name} not found"
21
+ end
22
+
23
+ def find_property property_name
24
+ info.find_property property_name or
25
+ superclass.find_property property_name or
26
+ raise "Property #{property_name} not found"
27
+ end
28
+
29
+ private
30
+
31
+ def setup_class
32
+ setup_layout
33
+ setup_constants
34
+ stub_methods
35
+ setup_gtype_getter
36
+ if info.fundamental?
37
+ setup_field_accessors
38
+ else
39
+ setup_property_accessors
40
+ end
41
+ setup_vfunc_invokers
42
+ setup_interfaces
43
+ end
44
+
45
+ # FIXME: Private method only used in subclass
46
+ def layout_superclass
47
+ FFI::Struct
48
+ end
49
+
50
+ def parent
51
+ unless defined? @parent
52
+ pr = info.parent
53
+ if pr.nil? or (pr.safe_name == @classname and pr.namespace == @namespace)
54
+ @parent = nil
55
+ else
56
+ @parent = pr
57
+ end
58
+ end
59
+ @parent
60
+ end
61
+
62
+ def superclass
63
+ @superclass ||= if parent
64
+ Builder.build_class parent
65
+ else
66
+ ObjectBase
67
+ end
68
+ end
69
+
70
+ # TODO: Unify with field accessor setup.
71
+ def setup_property_accessors
72
+ info.properties.each do |prop|
73
+ setup_accessors_for_property_info prop
74
+ end
75
+ end
76
+
77
+ def setup_accessors_for_property_info prop
78
+ builder = Builder::Property.new prop
79
+ unless info.find_instance_method prop.getter_name
80
+ @klass.class_eval builder.getter_def
81
+ end
82
+ @klass.class_eval builder.setter_def
83
+ end
84
+
85
+ # TODO: Guard agains accidental invocation of undefined vfuncs.
86
+ # TODO: Create object responsible for creating these invokers
87
+ def setup_vfunc_invokers
88
+ info.vfuncs.each do |vfinfo|
89
+ if (invoker = vfinfo.invoker)
90
+ define_vfunc_invoker vfinfo.name, invoker.name
91
+ end
92
+ end
93
+ end
94
+
95
+ def define_vfunc_invoker vfunc_name, invoker_name
96
+ return if vfunc_name == invoker_name
97
+ @klass.class_eval "
98
+ def #{vfunc_name} *args, &block
99
+ #{invoker_name}(*args, &block)
100
+ end
101
+ "
102
+ end
103
+
104
+ def setup_interfaces
105
+ interfaces.each do |iface|
106
+ @klass.class_eval do
107
+ include iface
108
+ end
109
+ end
110
+ end
111
+
112
+ def signal_definers
113
+ [info] + info.interfaces
114
+ end
115
+
116
+ def interfaces
117
+ info.interfaces.map do |ifinfo|
118
+ GirFFI::Builder.build_class ifinfo
119
+ end
120
+ end
121
+ end
122
+ end
123
+ end