gir_ffi 0.0.7 → 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt CHANGED
@@ -1,3 +1,12 @@
1
+ == 0.0.8 / 2011-04-08
2
+
3
+ * Generate modules with names starting with a lowercase letter (like
4
+ cairo).
5
+ * Allow specifying the typelib version on setup.
6
+ * Rename methods #methods and #type of the introspection classes to avoid
7
+ clashing with standard Ruby methods.
8
+ * Refactoring.
9
+
1
10
  == 0.0.7 / 2011-04-01
2
11
 
3
12
  * Support gobject-introspection 0.10, drop support for earlier versions.
data/README.rdoc CHANGED
@@ -25,26 +25,22 @@ Ruby-FFI-based binding of the GObject Introspection Repository
25
25
 
26
26
  * Ruby-FFI of course
27
27
  * gobject-introspection installed with some introspection data
28
+ * The `rr` and `shoulda` gems for testing.
28
29
 
29
30
  The current implementation needs the actual libraries to be available under
30
31
  the name ending in just `.so`. On Debian and Ubuntu at least, this means
31
32
  you have to install the -dev packages of any library you may want to
32
- access.
33
-
34
- On Ubuntu, the following set of packages should do the trick:
35
- `libffi-ruby`, `libgirepository1.0-dev`, `libgtk2.0-dev`,
36
- `libshoulda-ruby`, `gir1.0-everything-1.0`.
37
-
38
- On Debian it's the same, but the `gir1.0-everything-1.0` package is only
39
- available in experimental. You can take one of the patches attached to bug
40
- 550478 and recompile `gobject-introspection` to get the files GirFFI needs.
33
+ access. The following set of packages should do the trick:
34
+ `libgirepository1.0-dev` (at least version 0.10), and either
35
+ `gir1.2-gtk-3.0` and `libgtk-3-dev`, or `gir1.2-gtk-2.0` and
36
+ `libgtk2.0-dev`.
41
37
 
42
38
  == Hacking
43
39
 
44
40
  This is still very much a work in progress. You can start exploring by
45
41
  running the example programs in the examples/ folder. Some illustrate what
46
42
  works, some are a test bed for how things should work. Have a look at
47
- +rake+ +-T+.
43
+ `rake -T`. Feel free to file bugs or send pull requests.
48
44
 
49
45
  == Install
50
46
 
@@ -52,7 +48,7 @@ works, some are a test bed for how things should work. Have a look at
52
48
 
53
49
  == License
54
50
 
55
- Copyright (c) 2009--2010 Matijs van Zuijlen
51
+ Copyright (c) 2009--2011 Matijs van Zuijlen
56
52
 
57
53
  GirFFI is free software, distributed under the terms of the GNU Lesser
58
54
  General Public License, version 2.1 or later. See the file COPYING.LIB for
@@ -5,8 +5,8 @@
5
5
  $LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib')
6
6
  require 'gir_ffi'
7
7
 
8
+ GirFFI.setup :Gtk, '2.0'
8
9
  GirFFI.setup :GObject
9
- GirFFI.setup :Gtk
10
10
 
11
11
  Gtk.init
12
12
  win = Gtk::Window.new :toplevel
@@ -5,8 +5,8 @@
5
5
  $LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib')
6
6
  require 'gir_ffi'
7
7
 
8
+ GirFFI.setup :Gtk, '2.0'
8
9
  GirFFI.setup :GObject
9
- GirFFI.setup :Gtk
10
10
 
11
11
  Gtk.init
12
12
 
@@ -5,8 +5,8 @@
5
5
  $LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib')
6
6
  require 'gir_ffi'
7
7
 
8
+ GirFFI.setup :Gtk, '2.0'
8
9
  GirFFI.setup :GObject
9
- GirFFI.setup :Gtk
10
10
 
11
11
  callback = lambda { |widget, data|
12
12
  puts "Hello again - #{data} was pressed"
@@ -2,8 +2,8 @@
2
2
  $LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib')
3
3
  require 'gir_ffi'
4
4
 
5
- GirFFI.setup :Gtk
6
- GirFFI.setup :WebKit
5
+ GirFFI.setup :Gtk, '2.0'
6
+ GirFFI.setup :WebKit, '1.0'
7
7
 
8
8
  Gtk.init
9
9
 
@@ -4,7 +4,6 @@ module GirFFI
4
4
  module ArgHelper
5
5
  # FIXME: Hideous.
6
6
  def self.object_to_inptr obj
7
- return obj if obj.is_a? FFI::Pointer
8
7
  return obj.to_ptr if obj.respond_to? :to_ptr
9
8
  return nil if obj.nil?
10
9
  FFI::Pointer.new(obj.object_id)
@@ -74,26 +73,22 @@ module GirFFI
74
73
  end
75
74
 
76
75
  def self.cleanup_ptr_ptr ptr
77
- block = ptr.read_pointer
76
+ LibC.free ptr.read_pointer
78
77
  LibC.free ptr
79
- LibC.free block
80
78
  end
81
79
 
82
80
  # Takes an outptr to a pointer array, and frees all pointers.
83
81
  def self.cleanup_ptr_array_ptr ptr, size
84
82
  block = ptr.read_pointer
83
+ unless block.null?
84
+ block.read_array_of_pointer(size).each { |pt| LibC.free pt }
85
+ LibC.free block
86
+ end
85
87
  LibC.free ptr
86
-
87
- return if block.null?
88
-
89
- ptrs = block.read_array_of_pointer(size)
90
- LibC.free block
91
-
92
- ptrs.each { |ptr| LibC.free ptr }
93
88
  end
94
89
 
95
90
  def self.int32_to_inoutptr val
96
- int32_pointer.write_int32 val
91
+ int32_pointer.put_int32 0, val
97
92
  end
98
93
 
99
94
  def self.utf8_to_inoutptr str
@@ -148,7 +143,7 @@ module GirFFI
148
143
  end
149
144
 
150
145
  def self.int32_outptr
151
- int32_pointer.write_int32 0
146
+ int32_pointer.put_int32 0, 0
152
147
  end
153
148
 
154
149
  def self.double_outptr
@@ -176,7 +171,7 @@ module GirFFI
176
171
 
177
172
  # Converts an outptr to an int.
178
173
  def self.outptr_to_int32 ptr
179
- ptr.read_int32
174
+ ptr.get_int32 0
180
175
  end
181
176
 
182
177
  # Converts an outptr to a string.
@@ -214,7 +209,7 @@ module GirFFI
214
209
  end
215
210
 
216
211
  def self.ptr_to_int32_array ptr, size
217
- ptr.read_array_of_int32(size)
212
+ ptr.get_array_of_int32(0, size)
218
213
  end
219
214
 
220
215
  def self.ptr_to_utf8 ptr
@@ -273,7 +268,7 @@ module GirFFI
273
268
  end
274
269
 
275
270
  def self.map_single_callback_arg arg, info
276
- case info.type.tag
271
+ case info.argument_type.tag
277
272
  when :interface
278
273
  map_interface_callback_arg arg, info
279
274
  when :utf8
@@ -286,8 +281,8 @@ module GirFFI
286
281
  end
287
282
 
288
283
  def self.map_interface_callback_arg arg, info
289
- iface = info.type.interface
290
- case iface.type
284
+ iface = info.argument_type.interface
285
+ case iface.info_type
291
286
  when :object
292
287
  object_pointer_to_object arg
293
288
  when :struct
@@ -331,12 +326,6 @@ module GirFFI
331
326
  return nil if optr.null?
332
327
  tp = ::GObject.type_from_instance_pointer optr
333
328
  info = gir.find_by_gtype tp
334
-
335
- if info.nil?
336
- tpname = ::GObject.type_name tp
337
- raise RuntimeError, "Unable to find info for type '#{tpname}' (#{tp})"
338
- end
339
-
340
329
  klass = GirFFI::Builder.build_class info
341
330
  klass.wrap optr
342
331
  end
@@ -13,7 +13,7 @@ module GirFFI::Builder
13
13
 
14
14
  attr_reader :callarg, :name, :retname
15
15
 
16
- attr_accessor :length_arg, :length_arg_for
16
+ attr_accessor :length_arg, :array_arg
17
17
 
18
18
  def initialize function_builder, arginfo=nil, libmodule=nil
19
19
  @arginfo = arginfo
@@ -24,7 +24,7 @@ module GirFFI::Builder
24
24
  @function_builder = function_builder
25
25
  @libmodule = libmodule
26
26
  @length_arg = nil
27
- @length_arg_for = nil
27
+ @array_arg = nil
28
28
  end
29
29
 
30
30
  def self.build function_builder, arginfo, libmodule
@@ -41,8 +41,44 @@ module GirFFI::Builder
41
41
  klass.build function_builder, arginfo, libmodule
42
42
  end
43
43
 
44
- def type
45
- @arginfo.type
44
+ def type_info
45
+ @arginfo.argument_type
46
+ end
47
+
48
+ def type_tag
49
+ type_info.tag
50
+ end
51
+
52
+ def subtype_tag
53
+ st = type_info.param_type(0)
54
+ t = st.tag
55
+ case t
56
+ when :GType
57
+ return :gtype
58
+ when :interface
59
+ raise NotImplementedError if st.pointer?
60
+ iface = st.interface
61
+ if iface.name == 'Value' and iface.namespace == 'GObject'
62
+ return :gvalue
63
+ else
64
+ raise NotImplementedError
65
+ end
66
+ else
67
+ return t
68
+ end
69
+ end
70
+
71
+ def argument_class_name
72
+ iface = type_info.interface
73
+ "::#{iface.namespace}::#{iface.name}"
74
+ end
75
+
76
+ def array_size
77
+ if @length_arg
78
+ @length_arg.retname
79
+ else
80
+ type_info.array_fixed_size
81
+ end
46
82
  end
47
83
 
48
84
  def safe name
@@ -54,11 +90,11 @@ module GirFFI::Builder
54
90
  end
55
91
 
56
92
  def inarg
57
- @length_arg_for.nil? ? @inarg : nil
93
+ @array_arg.nil? ? @inarg : nil
58
94
  end
59
95
 
60
96
  def retval
61
- @length_arg_for.nil? ? @retname : nil
97
+ @array_arg.nil? ? @retname : nil
62
98
  end
63
99
 
64
100
  def pre
@@ -83,10 +119,10 @@ module GirFFI::Builder
83
119
  end
84
120
 
85
121
  def self.build function_builder, arginfo, libmodule
86
- type = arginfo.type
122
+ type = arginfo.argument_type
87
123
  klass = case type.tag
88
124
  when :interface
89
- if type.interface.type == :callback
125
+ if type.interface.info_type == :callback
90
126
  CallbackInArgument
91
127
  else
92
128
  RegularInArgument
@@ -110,7 +146,7 @@ module GirFFI::Builder
110
146
  # :in.
111
147
  class CallbackInArgument < InArgument
112
148
  def pre
113
- iface = @arginfo.type.interface
149
+ iface = type_info.interface
114
150
  [ "#{@callarg} = GirFFI::ArgHelper.wrap_in_callback_args_mapper \"#{iface.namespace}\", \"#{iface.name}\", #{@name}",
115
151
  "::#{@libmodule}::CALLBACKS << #{@callarg}" ]
116
152
  end
@@ -126,24 +162,6 @@ module GirFFI::Builder
126
162
 
127
163
  # Implements argument processing for array arguments with direction :in.
128
164
  class ArrayInArgument < InArgument
129
- def subtype_tag
130
- st = @arginfo.type.param_type(0)
131
- t = st.tag
132
- case t
133
- when :GType : return :gtype
134
- when :interface
135
- raise NotImplementedError if st.pointer?
136
- iface = st.interface
137
- if iface.name == 'Value' and iface.namespace == 'GObject'
138
- return :gvalue
139
- else
140
- raise NotImplementedError
141
- end
142
- else
143
- return t
144
- end
145
- end
146
-
147
165
  def post
148
166
  unless @arginfo.ownership_transfer == :everything
149
167
  if subtype_tag == :utf8
@@ -156,7 +174,7 @@ module GirFFI::Builder
156
174
 
157
175
  def pre
158
176
  pr = []
159
- size = type.array_fixed_size
177
+ size = type_info.array_fixed_size
160
178
  if size > -1
161
179
  pr << "GirFFI::ArgHelper.check_fixed_array_size #{size}, #{@name}, \"#{@name}\""
162
180
  end
@@ -167,20 +185,8 @@ module GirFFI::Builder
167
185
 
168
186
  # Implements argument processing for gslist arguments with direction :in.
169
187
  class ListInArgument < InArgument
170
- def subtype_tag
171
- @arginfo.type.param_type(0).tag
172
- end
173
-
174
- def type_tag
175
- @arginfo.type.tag
176
- end
177
-
178
188
  def pre
179
- if subtype_tag == :void
180
- [ "#{@callarg} = #{@name}" ]
181
- else
182
- [ "#{@callarg} = GirFFI::ArgHelper.#{subtype_tag}_array_to_#{type_tag} #{@name}" ]
183
- end
189
+ [ "#{@callarg} = GirFFI::ArgHelper.#{subtype_tag}_array_to_#{type_tag} #{@name}" ]
184
190
  end
185
191
  end
186
192
 
@@ -204,8 +210,9 @@ module GirFFI::Builder
204
210
  class RegularInArgument < InArgument
205
211
  def pre
206
212
  pr = []
207
- if @length_arg_for
208
- pr << "#{@name} = #{@length_arg_for.name}.nil? ? 0 : #{@length_arg_for.name}.length"
213
+ if @array_arg
214
+ arrname = @array_arg.name
215
+ pr << "#{@name} = #{arrname}.nil? ? 0 : #{arrname}.length"
209
216
  end
210
217
  pr << "#{@callarg} = #{@name}"
211
218
  pr
@@ -221,7 +228,7 @@ module GirFFI::Builder
221
228
  end
222
229
 
223
230
  def self.build function_builder, arginfo, libmodule
224
- klass = case arginfo.type.tag
231
+ klass = case arginfo.argument_type.tag
225
232
  when :interface
226
233
  InterfaceOutArgument
227
234
  when :array
@@ -238,14 +245,9 @@ module GirFFI::Builder
238
245
  # Implements argument processing for interface arguments with direction
239
246
  # :out (structs, objects, etc.).
240
247
  class InterfaceOutArgument < OutArgument
241
- def klass
242
- iface = @arginfo.type.interface
243
- "#{iface.namespace}::#{iface.name}"
244
- end
245
-
246
248
  def pre
247
249
  if @arginfo.caller_allocates?
248
- [ "#{@callarg} = #{klass}.allocate" ]
250
+ [ "#{@callarg} = #{argument_class_name}.allocate" ]
249
251
  else
250
252
  [ "#{@callarg} = GirFFI::ArgHelper.pointer_outptr" ]
251
253
  end
@@ -255,7 +257,7 @@ module GirFFI::Builder
255
257
  if @arginfo.caller_allocates?
256
258
  [ "#{@retname} = #{@callarg}" ]
257
259
  else
258
- [ "#{@retname} = #{klass}.wrap GirFFI::ArgHelper.outptr_to_pointer(#{@callarg})" ]
260
+ [ "#{@retname} = #{argument_class_name}.wrap GirFFI::ArgHelper.outptr_to_pointer(#{@callarg})" ]
259
261
  end
260
262
  end
261
263
  end
@@ -268,15 +270,8 @@ module GirFFI::Builder
268
270
  end
269
271
 
270
272
  def postpost
271
- type = @arginfo.type
272
-
273
- size = if @length_arg
274
- @length_arg.retname
275
- else
276
- type.array_fixed_size
277
- end
278
-
279
- tag = type.param_type(0).tag
273
+ size = array_size
274
+ tag = subtype_tag
280
275
 
281
276
  pp = [ "#{@retname} = GirFFI::ArgHelper.outptr_to_#{tag}_array #{@callarg}, #{size}" ]
282
277
 
@@ -300,22 +295,12 @@ module GirFFI::Builder
300
295
  end
301
296
 
302
297
  def postpost
303
- type = @arginfo.type
304
-
305
- tag = type.param_type(0).tag
306
-
307
- pp = [ "#{@retname} = GirFFI::ArgHelper.outgslist_to_#{tag}_array #{@callarg}" ]
308
-
309
- pp
298
+ [ "#{@retname} = GirFFI::ArgHelper.outgslist_to_#{subtype_tag}_array #{@callarg}" ]
310
299
  end
311
300
  end
312
301
  # Implements argument processing for arguments with direction
313
302
  # :out that are neither arrays nor 'interfaces'.
314
303
  class RegularOutArgument < OutArgument
315
- def type_tag
316
- @arginfo.type.tag
317
- end
318
-
319
304
  def post
320
305
  pst = [ "#{@retname} = GirFFI::ArgHelper.outptr_to_#{type_tag} #{@callarg}" ]
321
306
  if @arginfo.ownership_transfer == :everything
@@ -341,7 +326,7 @@ module GirFFI::Builder
341
326
  def self.build function_builder, arginfo, libmodule
342
327
  raise NotImplementedError unless arginfo.ownership_transfer == :everything
343
328
 
344
- klass = case arginfo.type.tag
329
+ klass = case arginfo.argument_type.tag
345
330
  when :interface
346
331
  raise NotImplementedError
347
332
  when :array
@@ -357,10 +342,6 @@ module GirFFI::Builder
357
342
  # Implements argument processing for array arguments with direction
358
343
  # :inout.
359
344
  class ArrayInOutArgument < InOutArgument
360
- def subtype_tag
361
- @arginfo.type.param_type(0).tag
362
- end
363
-
364
345
  def pre
365
346
  [ "#{@callarg} = GirFFI::ArgHelper.#{subtype_tag}_array_to_inoutptr #{@name}" ]
366
347
  end
@@ -381,10 +362,6 @@ module GirFFI::Builder
381
362
  # Implements argument processing for arguments with direction
382
363
  # :inout that are neither arrays nor 'interfaces'.
383
364
  class RegularInOutArgument < InOutArgument
384
- def type_tag
385
- @arginfo.type.tag
386
- end
387
-
388
365
  def post
389
366
  [ "#{@retname} = GirFFI::ArgHelper.outptr_to_#{type_tag} #{@callarg}",
390
367
  "GirFFI::ArgHelper.cleanup_ptr #{@callarg}" ]
@@ -392,8 +369,8 @@ module GirFFI::Builder
392
369
 
393
370
  def pre
394
371
  pr = []
395
- if @length_arg_for
396
- pr << "#{@name} = #{@length_arg_for.name}.length"
372
+ if @array_arg
373
+ pr << "#{@name} = #{@array_arg.name}.length"
397
374
  end
398
375
  pr << "#{@callarg} = GirFFI::ArgHelper.#{type_tag}_to_inoutptr #{@name}"
399
376
  pr
@@ -409,7 +386,7 @@ module GirFFI::Builder
409
386
  @retname = @function_builder.new_var
410
387
  end
411
388
 
412
- def type
389
+ def type_info
413
390
  @arginfo.return_type
414
391
  end
415
392
 
@@ -419,7 +396,7 @@ module GirFFI::Builder
419
396
  when :void
420
397
  VoidReturnValue
421
398
  when :interface
422
- case type.interface.type
399
+ case type.interface.info_type
423
400
  when :interface, :struct
424
401
  InterfaceReturnValue
425
402
  when :object
@@ -456,12 +433,7 @@ module GirFFI::Builder
456
433
  # polymorphism and constructors.
457
434
  class InterfaceReturnValue < ReturnValue
458
435
  def post
459
- interface = @arginfo.return_type.interface
460
- namespace = interface.namespace
461
- name = interface.name
462
-
463
- GirFFI::Builder.build_class interface
464
- [ "#{@retname} = ::#{namespace}::#{name}.wrap(#{@cvar})" ]
436
+ [ "#{@retname} = #{argument_class_name}.wrap(#{@cvar})" ]
465
437
  end
466
438
  end
467
439
 
@@ -474,50 +446,29 @@ module GirFFI::Builder
474
446
 
475
447
  # Implements argument processing for object constructors.
476
448
  class ConstructorReturnValue < ReturnValue
477
- def post
449
+ def defining_class_name
478
450
  classinfo = @arginfo.container
479
- namespace = classinfo.namespace
480
- name = classinfo.name
451
+ "::#{classinfo.namespace}::#{classinfo.name}"
452
+ end
481
453
 
482
- GirFFI::Builder.build_class classinfo
483
- [ "#{@retname} = ::#{namespace}::#{name}.constructor_wrap(#{@cvar})" ]
454
+ def post
455
+ [ "#{@retname} = #{defining_class_name}.constructor_wrap(#{@cvar})" ]
484
456
  end
485
457
  end
486
458
 
487
459
  # Implements argument processing for array return values.
488
460
  class ArrayReturnValue < ReturnValue
489
- def subtype_tag
490
- @arginfo.return_type.param_type(0).tag
491
- end
492
-
493
461
  def post
494
- type = @arginfo.return_type
495
- size = type.array_fixed_size
462
+ size = array_size
496
463
 
497
- if size <= 0
498
- size = @length_arg.retname
499
- end
500
464
  [ "#{@retname} = GirFFI::ArgHelper.ptr_to_#{subtype_tag}_array #{@cvar}, #{size}" ]
501
465
  end
502
466
  end
503
467
 
504
468
  # Implements argument processing for GSList return values.
505
469
  class ListReturnValue < ReturnValue
506
- # TODO: Extract to a module.
507
- def subtype_tag
508
- @arginfo.return_type.param_type(0).tag
509
- end
510
-
511
- def type_tag
512
- @arginfo.return_type.tag
513
- end
514
-
515
470
  def post
516
- if subtype_tag == :void
517
- [ "#{@retname} = ::GLib::SList.wrap(#{@cvar})" ]
518
- else
519
- [ "#{@retname} = GirFFI::ArgHelper.#{type_tag}_to_#{subtype_tag}_array #{@cvar}" ]
520
- end
471
+ [ "#{@retname} = GirFFI::ArgHelper.#{type_tag}_to_#{subtype_tag}_array #{@cvar}" ]
521
472
  end
522
473
  end
523
474
 
@@ -18,10 +18,10 @@ module GirFFI::Builder
18
18
 
19
19
  alldata.each {|data|
20
20
  data.prepare
21
- idx = data.type.array_length
21
+ idx = data.type_info.array_length
22
22
  if idx > -1
23
23
  data.length_arg = @data[idx]
24
- @data[idx].length_arg_for = data
24
+ @data[idx].array_arg = data
25
25
  end
26
26
  }
27
27
 
@@ -7,8 +7,10 @@ module GirFFI
7
7
  class Builder::Module
8
8
  include BuilderHelper
9
9
 
10
- def initialize namespace
10
+ def initialize namespace, version=nil
11
11
  @namespace = namespace
12
+ @version = version
13
+ @safe_namespace = @namespace.gsub(/^(.)/) { $1.upcase }
12
14
  end
13
15
 
14
16
  def generate
@@ -48,7 +50,7 @@ module GirFFI
48
50
  end
49
51
 
50
52
  def instantiate_module
51
- @module = get_or_define_module ::Object, @namespace.to_s
53
+ @module = get_or_define_module ::Object, @safe_namespace
52
54
  end
53
55
 
54
56
  def setup_module
@@ -81,7 +83,7 @@ module GirFFI
81
83
  def function_introspection_data function
82
84
  info = gir.find_by_name @namespace, function.to_s
83
85
 
84
- if info.type == :function
86
+ if info.info_type == :function
85
87
  info
86
88
  else
87
89
  nil
@@ -95,7 +97,7 @@ module GirFFI
95
97
  def gir
96
98
  unless defined? @gir
97
99
  @gir = IRepository.default
98
- @gir.require @namespace, nil
100
+ @gir.require @namespace, @version
99
101
  end
100
102
  @gir
101
103
  end
@@ -0,0 +1,35 @@
1
+ module GirFFI
2
+ module Builder
3
+ module Type
4
+ class Base
5
+ include BuilderHelper
6
+
7
+ def initialize info
8
+ @info = info
9
+ @namespace = @info.namespace
10
+ @classname = @info.name.gsub(/^(.)/) { $1.upcase }
11
+ end
12
+
13
+ private
14
+
15
+ def info
16
+ @info
17
+ end
18
+
19
+ def namespace_module
20
+ @namespace_module ||= Builder.build_module @namespace
21
+ end
22
+
23
+ def lib
24
+ @lib ||= namespace_module.const_get :Lib
25
+ end
26
+
27
+ def get_or_define_class namespace, name, parent
28
+ optionally_define_constant(namespace, name) {
29
+ Class.new parent
30
+ }
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,27 @@
1
+ require 'gir_ffi/builder/type/base'
2
+ module GirFFI
3
+ module Builder
4
+ module Type
5
+
6
+ # Implements the creation of a callback type. The type will be
7
+ # attached to the appropriate namespace module, and will be defined
8
+ # as a callback for FFI.
9
+ class Callback < Base
10
+ def build_class
11
+ unless defined? @klass
12
+ instantiate_callback_class
13
+ end
14
+ @klass
15
+ end
16
+
17
+ def instantiate_callback_class
18
+ @klass = optionally_define_constant namespace_module, @classname do
19
+ args = Builder.ffi_function_argument_types info
20
+ ret = Builder.ffi_function_return_type info
21
+ lib.callback @classname.to_sym, args, ret
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end