gir_ffi 0.0.5 → 0.0.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.
data/History.txt CHANGED
@@ -1,3 +1,11 @@
1
+ == 0.0.6 / 2011-03-01
2
+
3
+ * Cast returned GObjects to their actual type.
4
+ * Properly cast callback arguments.
5
+ * Handle the case where functions formally return interfaces.
6
+ * Make sure Gtk::Window has the correct number of references after creation.
7
+ * Refactoring and some small fixes.
8
+
1
9
  == 0.0.5 / 2010-12-30
2
10
 
3
11
  * Don't create instance methods out of functions and vice versa.
@@ -41,7 +41,7 @@ module GirFFI
41
41
  AllocationHelper.safe_malloc(len + 1).write_string(str).put_char(len, 0)
42
42
  end
43
43
 
44
- def self.GType_array_to_inptr ary
44
+ def self.gtype_array_to_inptr ary
45
45
  case FFI.type_size(:size_t)
46
46
  when 4
47
47
  int32_array_to_inptr ary
@@ -64,8 +64,6 @@ module GirFFI
64
64
 
65
65
  # Takes an outptr to a pointer array, and frees all pointers.
66
66
  def self.cleanup_ptr_array_ptr ptr, size
67
- return if ptr.nil?
68
-
69
67
  block = ptr.read_pointer
70
68
  LibC.free ptr
71
69
 
@@ -74,9 +72,7 @@ module GirFFI
74
72
  ptrs = block.read_array_of_pointer(size)
75
73
  LibC.free block
76
74
 
77
- ptrs.map do |p|
78
- LibC.free p unless p.null?
79
- end
75
+ ptrs.each { |ptr| LibC.free ptr }
80
76
  end
81
77
 
82
78
  def self.int_to_inoutptr val
@@ -148,22 +144,16 @@ module GirFFI
148
144
 
149
145
  # Converts an outptr to a string.
150
146
  def self.outptr_to_utf8 ptr
151
- return nil if ptr.nil?
152
- sptr = ptr.read_pointer
153
-
154
- sptr.null? ? nil : sptr.read_string
147
+ ptr_to_utf8 ptr.read_pointer
155
148
  end
156
149
 
157
150
  # Converts an outptr to a string array.
158
151
  def self.outptr_to_utf8_array ptr, size
159
- return nil if ptr.nil?
160
152
  block = ptr.read_pointer
161
153
  return nil if block.null?
162
154
  ptrs = block.read_array_of_pointer(size)
163
155
 
164
- ptrs.map do |p|
165
- p.null? ? nil : p.read_string
166
- end
156
+ ptrs.map { |ptr| ptr_to_utf8 ptr }
167
157
  end
168
158
 
169
159
  # Converts an outptr to a double.
@@ -173,7 +163,6 @@ module GirFFI
173
163
 
174
164
  # Converts an outptr to an array of int.
175
165
  def self.outptr_to_int_array ptr, size
176
- return nil if ptr.null?
177
166
  block = ptr.read_pointer
178
167
  return nil if block.null?
179
168
  ptr_to_int_array block, size
@@ -183,25 +172,50 @@ module GirFFI
183
172
  ptr.read_array_of_int(size)
184
173
  end
185
174
 
186
- def self.mapped_callback_args prc=nil, &block
175
+ def self.ptr_to_utf8 ptr
176
+ ptr.null? ? nil : ptr.read_string
177
+ end
178
+
179
+ def self.wrap_in_callback_args_mapper namespace, name, prc
187
180
  return prc if FFI::Function === prc
188
- if prc.nil?
189
- return nil if block.nil?
190
- prc = block
191
- end
181
+ return nil if prc.nil?
182
+ info = gir.find_by_name namespace, name
192
183
  return Proc.new do |*args|
193
- mapped = args.map {|arg|
194
- if FFI::Pointer === arg
195
- begin
196
- ObjectSpace._id2ref arg.address
197
- rescue RangeError
198
- arg
199
- end
200
- else
184
+ prc.call(*map_callback_args(args, info))
185
+ end
186
+ end
187
+
188
+ def self.map_callback_args args, info
189
+ args.zip(info.args).map { |arg, inf|
190
+ map_single_callback_arg arg, inf }
191
+ end
192
+
193
+ def self.map_single_callback_arg arg, info
194
+ type = info.type
195
+ tag = type.tag
196
+
197
+ case tag
198
+ when :interface
199
+ iface = type.interface
200
+ if iface.type == :object
201
+ object_pointer_to_object arg
202
+ else
203
+ arg
204
+ end
205
+ when :utf8
206
+ ptr_to_utf8 arg
207
+ when :void
208
+ if arg.null?
209
+ nil
210
+ else
211
+ begin
212
+ ObjectSpace._id2ref arg.address
213
+ rescue RangeError
201
214
  arg
202
215
  end
203
- }
204
- prc.call(*mapped)
216
+ end
217
+ else
218
+ arg
205
219
  end
206
220
  end
207
221
 
@@ -210,12 +224,6 @@ module GirFFI
210
224
  raise GError.new(errp)[:message] unless errp.null?
211
225
  end
212
226
 
213
- def self.sink_if_floating gobject
214
- if GirFFI::GObject.object_is_floating(gobject)
215
- GirFFI::GObject.object_ref_sink(gobject)
216
- end
217
- end
218
-
219
227
  def self.check_fixed_array_size size, arr, name
220
228
  unless arr.size == size
221
229
  raise ArgumentError, "#{name} should have size #{size}"
@@ -228,11 +236,21 @@ module GirFFI
228
236
 
229
237
  # FIXME: Quasi-circular dependency on generated module
230
238
  def self.object_pointer_to_object optr
239
+ return nil if optr.null?
231
240
  tp = ::GObject.type_from_instance_pointer optr
232
- gir = GirFFI::IRepository.default
233
241
  info = gir.find_by_gtype tp
242
+
243
+ if info.nil?
244
+ tpname = ::GObject.type_name tp
245
+ raise RuntimeError, "Unable to find info for type '#{tpname}' (#{tp})"
246
+ end
247
+
234
248
  klass = GirFFI::Builder.build_class info.namespace, info.name
235
249
  klass.wrap optr
236
250
  end
251
+
252
+ def self.gir
253
+ gir = GirFFI::IRepository.default
254
+ end
237
255
  end
238
256
  end
@@ -0,0 +1,382 @@
1
+ module GirFFI
2
+ # Abstract parent class of the argument building classes. These classes
3
+ # are used by FunctionDefinitionBuilder to create the code that processes
4
+ # each argument before and after the actual function call.
5
+ class ArgumentBuilder
6
+ KEYWORDS = [
7
+ "alias", "and", "begin", "break", "case", "class", "def", "do",
8
+ "else", "elsif", "end", "ensure", "false", "for", "if", "in",
9
+ "module", "next", "nil", "not", "or", "redo", "rescue", "retry",
10
+ "return", "self", "super", "then", "true", "undef", "unless",
11
+ "until", "when", "while", "yield"
12
+ ]
13
+
14
+ attr_reader :arginfo, :callarg, :pre, :post, :postpost
15
+
16
+ attr_accessor :length_arg, :inarg, :retval
17
+
18
+ def initialize function_builder, arginfo=nil, libmodule=nil
19
+ @arginfo = arginfo
20
+ @inarg = nil
21
+ @callarg = nil
22
+ @retval = nil
23
+ @retname = nil
24
+ @name = nil
25
+ @pre = []
26
+ @post = []
27
+ @postpost = []
28
+ @function_builder = function_builder
29
+ @libmodule = libmodule
30
+ end
31
+
32
+ def self.build function_builder, arginfo, libmodule
33
+ klass = case arginfo.direction
34
+ when :inout
35
+ InOutArgumentBuilder
36
+ when :in
37
+ InArgumentBuilder
38
+ when :out
39
+ OutArgumentBuilder
40
+ else
41
+ raise ArgumentError
42
+ end
43
+ klass.new function_builder, arginfo, libmodule
44
+ end
45
+
46
+ def type
47
+ @arginfo.type
48
+ end
49
+
50
+ private
51
+
52
+ def safe name
53
+ if KEYWORDS.include? name
54
+ "#{name}_"
55
+ else
56
+ name
57
+ end
58
+ end
59
+ end
60
+
61
+ # Implements argument processing for arguments with direction :in
62
+ class InArgumentBuilder < ArgumentBuilder
63
+ def prepare
64
+ @name = safe(@arginfo.name)
65
+ @callarg = @function_builder.new_var
66
+ @inarg = @name
67
+ end
68
+
69
+ def process
70
+ case @arginfo.type.tag
71
+ when :interface
72
+ process_interface_in_arg
73
+ when :void
74
+ process_void_in_arg
75
+ when :array
76
+ process_array_in_arg
77
+ when :utf8
78
+ process_utf8_in_arg
79
+ else
80
+ process_other_in_arg
81
+ end
82
+ end
83
+
84
+ private
85
+
86
+
87
+ def process_interface_in_arg
88
+ arg = @arginfo
89
+ type = arg.type
90
+
91
+ iface = type.interface
92
+ if iface.type == :callback
93
+ @pre << "#{@callarg} = GirFFI::ArgHelper.wrap_in_callback_args_mapper \"#{iface.namespace}\", \"#{iface.name}\", #{@inarg}"
94
+ @pre << "::#{@libmodule}::CALLBACKS << #{@callarg}"
95
+ else
96
+ @pre << "#{@callarg} = #{@inarg}"
97
+ end
98
+ end
99
+
100
+ def process_void_in_arg
101
+ @pre << "#{@callarg} = GirFFI::ArgHelper.object_to_inptr #{@inarg}"
102
+ end
103
+
104
+ def process_utf8_in_arg
105
+ @pre << "#{@callarg} = GirFFI::ArgHelper.utf8_to_inptr #{@name}"
106
+ # TODO:
107
+ #@post << "GirFFI::ArgHelper.cleanup_ptr #{@callarg}"
108
+ end
109
+
110
+ def process_array_in_arg
111
+ arg = @arginfo
112
+ type = arg.type
113
+
114
+ if type.array_fixed_size > 0
115
+ @pre << "GirFFI::ArgHelper.check_fixed_array_size #{type.array_fixed_size}, #{@inarg}, \"#{@inarg}\""
116
+ elsif type.array_length > -1
117
+ idx = type.array_length
118
+ lenvar = @length_arg.inarg
119
+ @length_arg.inarg = nil
120
+ @length_arg.pre.unshift "#{lenvar} = #{@inarg}.nil? ? 0 : #{@inarg}.length"
121
+ end
122
+
123
+ tag = arg.type.param_type(0).tag.to_s.downcase
124
+ @pre << "#{@callarg} = GirFFI::ArgHelper.#{tag}_array_to_inptr #{@inarg}"
125
+ unless arg.ownership_transfer == :everything
126
+ if tag == :utf8
127
+ @post << "GirFFI::ArgHelper.cleanup_ptr_ptr #{@callarg}"
128
+ else
129
+ @post << "GirFFI::ArgHelper.cleanup_ptr #{@callarg}"
130
+ end
131
+ end
132
+ end
133
+
134
+ def process_other_in_arg
135
+ @pre << "#{@callarg} = #{@name}"
136
+ end
137
+ end
138
+
139
+ # Implements argument processing for arguments with direction :out
140
+ class OutArgumentBuilder < ArgumentBuilder
141
+ def prepare
142
+ @name = safe(@arginfo.name)
143
+ @callarg = @function_builder.new_var
144
+ @retname = @retval = @function_builder.new_var
145
+ end
146
+
147
+ def process
148
+ case @arginfo.type.tag
149
+ when :interface
150
+ process_interface_out_arg
151
+ when :array
152
+ process_array_out_arg
153
+ else
154
+ process_other_out_arg
155
+ end
156
+ end
157
+
158
+ private
159
+
160
+ def process_interface_out_arg
161
+ iface = @arginfo.type.interface
162
+ klass = "#{iface.namespace}::#{iface.name}"
163
+
164
+ if @arginfo.caller_allocates?
165
+ @pre << "#{@callarg} = #{klass}.allocate"
166
+ @post << "#{@retval} = #{@callarg}"
167
+ else
168
+ @pre << "#{@callarg} = GirFFI::ArgHelper.pointer_outptr"
169
+ @post << "#{@retval} = #{klass}.wrap GirFFI::ArgHelper.outptr_to_pointer(#{@callarg})"
170
+ end
171
+ end
172
+
173
+ def process_array_out_arg
174
+ @pre << "#{@callarg} = GirFFI::ArgHelper.pointer_outptr"
175
+
176
+ arg = @arginfo
177
+ type = arg.type
178
+ tag = type.param_type(0).tag
179
+ size = type.array_fixed_size
180
+ idx = type.array_length
181
+
182
+ if size <= 0
183
+ if idx > -1
184
+ size = @length_arg.retval
185
+ @length_arg.retval = nil
186
+ else
187
+ raise NotImplementedError
188
+ end
189
+ end
190
+
191
+ @postpost << "#{@retval} = GirFFI::ArgHelper.outptr_to_#{tag}_array #{@callarg}, #{size}"
192
+
193
+ if arg.ownership_transfer == :everything
194
+ if tag == :utf8
195
+ @postpost << "GirFFI::ArgHelper.cleanup_ptr_array_ptr #{@callarg}, #{rv}"
196
+ else
197
+ @postpost << "GirFFI::ArgHelper.cleanup_ptr_ptr #{@callarg}"
198
+ end
199
+ end
200
+ end
201
+
202
+ def process_other_out_arg
203
+ tag = @arginfo.type.tag
204
+ @pre << "#{@callarg} = GirFFI::ArgHelper.#{tag}_outptr"
205
+ @post << "#{@retname} = GirFFI::ArgHelper.outptr_to_#{tag} #{@callarg}"
206
+ if @arginfo.ownership_transfer == :everything
207
+ @post << "GirFFI::ArgHelper.cleanup_ptr #{@callarg}"
208
+ end
209
+ end
210
+
211
+ end
212
+
213
+ # Implements argument processing for arguments with direction :inout
214
+ class InOutArgumentBuilder < ArgumentBuilder
215
+ def prepare
216
+ @name = safe(@arginfo.name)
217
+ @callarg = @function_builder.new_var
218
+ @inarg = @name
219
+ @retname = @retval = @function_builder.new_var
220
+ end
221
+
222
+ def process
223
+ raise NotImplementedError unless @arginfo.ownership_transfer == :everything
224
+
225
+ case @arginfo.type.tag
226
+ when :interface
227
+ process_interface_inout_arg
228
+ when :array
229
+ process_array_inout_arg
230
+ else
231
+ process_other_inout_arg
232
+ end
233
+ end
234
+
235
+ private
236
+
237
+ def process_interface_inout_arg
238
+ raise NotImplementedError
239
+ end
240
+
241
+ def process_array_inout_arg
242
+ arg = @arginfo
243
+ tag = arg.type.param_type(0).tag
244
+ @pre << "#{@callarg} = GirFFI::ArgHelper.#{tag}_array_to_inoutptr #{@inarg}"
245
+ if arg.type.array_length > -1
246
+ idx = arg.type.array_length
247
+ rv = @length_arg.retval
248
+ @length_arg.retval = nil
249
+ lname = @length_arg.inarg
250
+ @length_arg.inarg = nil
251
+ @length_arg.pre.unshift "#{lname} = #{@inarg}.length"
252
+ @post << "#{@retval} = GirFFI::ArgHelper.outptr_to_#{tag}_array #{@callarg}, #{rv}"
253
+ if tag == :utf8
254
+ @post << "GirFFI::ArgHelper.cleanup_ptr_array_ptr #{@callarg}, #{rv}"
255
+ else
256
+ @post << "GirFFI::ArgHelper.cleanup_ptr_ptr #{@callarg}"
257
+ end
258
+ else
259
+ raise NotImplementedError
260
+ end
261
+ end
262
+
263
+ def process_other_inout_arg
264
+ tag = @arginfo.type.tag
265
+ @pre << "#{@callarg} = GirFFI::ArgHelper.#{tag}_to_inoutptr #{@inarg}"
266
+ @post << "#{@retval} = GirFFI::ArgHelper.outptr_to_#{tag} #{@callarg}"
267
+ @post << "GirFFI::ArgHelper.cleanup_ptr #{@callarg}"
268
+ end
269
+ end
270
+
271
+ # Implements argument processing for return values.
272
+ class ReturnValueBuilder < ArgumentBuilder
273
+ attr_reader :cvar
274
+
275
+ def prepare
276
+ return if tag == :void
277
+ @cvar = @function_builder.new_var
278
+ @retval = @function_builder.new_var
279
+ end
280
+
281
+ def process
282
+ return if tag == :void
283
+
284
+ type = @arginfo.return_type
285
+
286
+ case tag
287
+ when :interface
288
+ process_interface_return_value type, @cvar
289
+ when :array
290
+ process_array_return_value type, @cvar
291
+ else
292
+ process_other_return_value
293
+ end
294
+ end
295
+
296
+ def type
297
+ @arginfo.return_type
298
+ end
299
+
300
+ private
301
+
302
+ def process_interface_return_value type, cvar
303
+ interface = type.interface
304
+ namespace = interface.namespace
305
+ name = interface.name
306
+
307
+ case interface.type
308
+ when :interface
309
+ GirFFI::Builder.build_class namespace, name
310
+ @post << "#{@retval} = ::#{namespace}::#{name}.wrap(#{cvar})"
311
+ when :object
312
+ if @arginfo.constructor?
313
+ GirFFI::Builder.build_class namespace, name
314
+ @post << "#{@retval} = ::#{namespace}::#{name}.wrap(#{cvar})"
315
+ if is_subclass_of_initially_unowned interface
316
+ @post << "GirFFI::GObject.object_ref_sink(#{@retval})"
317
+ end
318
+ else
319
+ @post << "#{@retval} = GirFFI::ArgHelper.object_pointer_to_object(#{cvar})"
320
+ end
321
+ when :struct
322
+ GirFFI::Builder.build_class namespace, name
323
+ @post << "#{@retval} = ::#{namespace}::#{name}.wrap(#{cvar})"
324
+ else
325
+ @post << "#{@retval} = #{cvar}"
326
+ end
327
+ end
328
+
329
+ def process_array_return_value type, cvar
330
+ tag = type.param_type(0).tag
331
+ size = type.array_fixed_size
332
+ idx = type.array_length
333
+
334
+ if size > 0
335
+ @post << "#{@retval} = GirFFI::ArgHelper.ptr_to_#{tag}_array #{cvar}, #{size}"
336
+ elsif idx > -1
337
+ lendata = @length_arg #@data[idx]
338
+ rv = lendata.retval
339
+ lendata.retval = nil
340
+ @post << "#{@retval} = GirFFI::ArgHelper.ptr_to_#{tag}_array #{cvar}, #{rv}"
341
+ end
342
+ end
343
+
344
+ def process_other_return_value
345
+ @retval = @cvar
346
+ end
347
+
348
+ def tag
349
+ type.tag
350
+ end
351
+
352
+ def is_subclass_of_initially_unowned interface
353
+ if interface.namespace == "GObject" and interface.name == "InitiallyUnowned"
354
+ true
355
+ elsif interface.parent
356
+ is_subclass_of_initially_unowned interface.parent
357
+ else
358
+ false
359
+ end
360
+ end
361
+ end
362
+
363
+ # Implements argument processing for error handling arguments. These
364
+ # arguments are not part of the introspected signature, but their
365
+ # presence is indicated by the 'throws' attribute of the function.
366
+ class ErrorHandlerBuilder < ArgumentBuilder
367
+ def prepare
368
+ @callarg = @function_builder.new_var
369
+ end
370
+
371
+ def process
372
+ @pre << "#{@callarg} = FFI::MemoryPointer.new(:pointer).write_pointer nil"
373
+ @post << "GirFFI::ArgHelper.check_error(#{@callarg})"
374
+ end
375
+ end
376
+
377
+ # Argument builder that does nothing. Implements Null Object pattern.
378
+ class NullArgumentBuilder < ArgumentBuilder
379
+ def prepare; end
380
+ def process; end
381
+ end
382
+ end
@@ -30,8 +30,8 @@ module GirFFI
30
30
  # All methods below will be made private at the end.
31
31
 
32
32
  def self.ffi_function_argument_types info
33
- types = info.args.map do |a|
34
- tp = iarginfo_to_ffitype a
33
+ types = info.args.map do |arg|
34
+ tp = iarginfo_to_ffitype arg
35
35
  tp == :string ? :pointer : tp
36
36
  end
37
37
  if info.type == :function
@@ -93,8 +93,8 @@ module GirFFI
93
93
  end
94
94
 
95
95
  # Set up method access.
96
- (self.public_methods - Module.public_methods).each do |m|
97
- private_class_method m.to_sym
96
+ (self.public_methods - Module.public_methods).each do |method|
97
+ private_class_method method.to_sym
98
98
  end
99
99
  public_class_method :build_module, :build_class
100
100
  public_class_method :itypeinfo_to_ffitype
@@ -37,15 +37,10 @@ module GirFFI
37
37
  end
38
38
 
39
39
  def find_signal signal_name
40
- info.signals.each do |s|
41
- return s if s.name == signal_name
42
- end
43
- if info.type == :object
44
- info.interfaces.each do |i|
45
- i.signals.each do |s|
46
- return s if s.name == signal_name
47
- end
48
- end
40
+ signal_definers.each do |inf|
41
+ inf.signals.each do |sig|
42
+ return sig if sig.name == signal_name
43
+ end
49
44
  end
50
45
  if info.parent
51
46
  return superclass.gir_ffi_builder.find_signal signal_name
@@ -57,14 +52,14 @@ module GirFFI
57
52
  def build_class
58
53
  unless defined? @klass
59
54
  case info.type
60
- when :object, :struct
61
- instantiate_struct_class
62
- when :union
63
- instantiate_union_class
64
- when :enum, :flags
65
- instantiate_enum_class
66
- else
67
- raise NotImplementedError, "Cannot build classes of type #{info.type}"
55
+ when :object, :struct, :interface
56
+ instantiate_struct_class
57
+ when :union
58
+ instantiate_union_class
59
+ when :enum, :flags
60
+ instantiate_enum_class
61
+ else
62
+ raise NotImplementedError, "Cannot build classes of type #{info.type}"
68
63
  end
69
64
  end
70
65
  @klass
@@ -118,7 +113,7 @@ module GirFFI
118
113
 
119
114
  def instantiate_enum_class
120
115
  @klass = optionally_define_constant namespace_module, @classname do
121
- vals = info.values.map {|v| [v.name.to_sym, v.value]}.flatten
116
+ vals = info.values.map {|vinfo| [vinfo.name.to_sym, vinfo.value]}.flatten
122
117
  lib.enum(@classname.to_sym, vals)
123
118
  end
124
119
  end
@@ -139,7 +134,11 @@ module GirFFI
139
134
  end
140
135
 
141
136
  def layout_specification
142
- fields = info.fields
137
+ fields = if info.type == :interface
138
+ []
139
+ else
140
+ info.fields
141
+ end
143
142
 
144
143
  if fields.empty?
145
144
  if parent
@@ -149,10 +148,10 @@ module GirFFI
149
148
  end
150
149
  end
151
150
 
152
- fields.map do |f|
153
- [ f.name.to_sym,
154
- itypeinfo_to_ffitype_for_struct(f.type),
155
- f.offset ]
151
+ fields.map do |finfo|
152
+ [ finfo.name.to_sym,
153
+ itypeinfo_to_ffitype_for_struct(finfo.type),
154
+ finfo.offset ]
156
155
  end.flatten
157
156
  end
158
157
 
@@ -168,14 +167,14 @@ module GirFFI
168
167
  end
169
168
 
170
169
  def stub_methods
171
- info.methods.each do |m|
172
- @klass.class_eval method_stub(m.method? ? m.name : "self.#{m.name}", m.name)
170
+ info.methods.each do |minfo|
171
+ @klass.class_eval method_stub(minfo.name, minfo.method?)
173
172
  end
174
173
  end
175
174
 
176
- def method_stub name, symbol
175
+ def method_stub symbol, is_instance_method
177
176
  "
178
- def #{name} *args, &block
177
+ def #{is_instance_method ? '' : 'self.'}#{symbol} *args, &block
179
178
  setup_and_call :#{symbol}, *args, &block
180
179
  end
181
180
  "
@@ -193,13 +192,13 @@ module GirFFI
193
192
  end
194
193
 
195
194
  def setup_vfunc_invokers
196
- info.vfuncs.each do |v|
197
- invoker = v.invoker
195
+ info.vfuncs.each do |vfinfo|
196
+ invoker = vfinfo.invoker
198
197
  next if invoker.nil?
199
- next if invoker.name == v.name
198
+ next if invoker.name == vfinfo.name
200
199
 
201
200
  @klass.class_eval "
202
- def #{v.name} *args, &block
201
+ def #{vfinfo.name} *args, &block
203
202
  #{invoker.name}(*args, &block)
204
203
  end
205
204
  "
@@ -228,8 +227,8 @@ module GirFFI
228
227
  end
229
228
 
230
229
  def instance_method_introspection_data method
231
- m = method_introspection_data method
232
- return !m.nil? && m.method? ? m : nil
230
+ data = method_introspection_data method
231
+ return !data.nil? && data.method? ? data : nil
233
232
  end
234
233
 
235
234
  def function_definition go
@@ -257,5 +256,9 @@ module GirFFI
257
256
  Class.new parent
258
257
  }
259
258
  end
259
+
260
+ def signal_definers
261
+ [info] + (info.type == :object ? info.interfaces : [])
262
+ end
260
263
  end
261
264
  end