gir_ffi 0.0.9 → 0.0.10

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,9 @@
1
+ == 0.0.10 / 2011-05-18
2
+
3
+ * Handle GObject interfaces properly.
4
+ * Create types only defined by the GType system.
5
+ * Support GType array return values.
6
+
1
7
  == 0.0.9 / 2011-05-02
2
8
 
3
9
  * More complete support for the basic types.
@@ -1,5 +1,6 @@
1
1
  require 'gir_ffi/allocation_helper'
2
2
  require 'gir_ffi/builder'
3
+ require 'gir_ffi/builder/dynamic_type'
3
4
 
4
5
  module GirFFI
5
6
  module ArgHelper
@@ -201,7 +202,7 @@ module GirFFI
201
202
  def self.outptr_to_int32_array ptr, size
202
203
  block = ptr.read_pointer
203
204
  return nil if block.null?
204
- ptr_to_int32_array block, size
205
+ ptr_to_gint32_array block, size
205
206
  end
206
207
 
207
208
  # Converts an outptr to an array of the given class.
@@ -224,13 +225,18 @@ module GirFFI
224
225
  end
225
226
  end
226
227
 
227
- def self.ptr_to_int32_array ptr, size
228
- ptr.get_array_of_int32(0, size)
228
+ def self.setup_ptr_to_type_array_handler_for *types
229
+ types.flatten.each do |type|
230
+ ffi_type = GirFFI::Builder::TAG_TYPE_MAP[type] || type
231
+ defn =
232
+ "def self.ptr_to_#{type}_array ptr, size
233
+ ptr.get_array_of_#{ffi_type}(0, size)
234
+ end"
235
+ eval defn
236
+ end
229
237
  end
230
238
 
231
- def self.ptr_to_int16_array ptr, size
232
- ptr.get_array_of_int16(0, size)
233
- end
239
+ setup_ptr_to_type_array_handler_for SIMPLE_G_TYPES
234
240
 
235
241
  def self.ptr_to_utf8_array ptr, size
236
242
  ptrs = ptr.read_array_of_pointer(size)
@@ -262,28 +268,15 @@ module GirFFI
262
268
  ptr.null? ? nil : ptr.read_string(len)
263
269
  end
264
270
 
265
- class << self
266
- alias ptr_to_int_array ptr_to_int32_array
267
- alias ptr_to_gint32_array ptr_to_int32_array
268
- alias ptr_to_gint16_array ptr_to_int16_array
269
- end
270
-
271
271
  # Set up gtype handlers depending on type size.
272
272
  class << self
273
- case FFI.type_size(:size_t)
274
- when 4
275
- alias gtype_array_to_inptr gint32_array_to_inptr
276
- alias gtype_outptr gint32_outptr
277
- alias gtype_to_inoutptr gint32_to_inoutptr
278
- alias outptr_to_gtype outptr_to_gint32
279
- when 8
280
- alias gtype_array_to_inptr gint64_array_to_inptr
281
- alias gtype_outptr gint64_outptr
282
- alias gtype_to_inoutptr gint64_to_inoutptr
283
- alias outptr_to_gtype outptr_to_gint64
284
- else
285
- raise RuntimeError, "Unexpected size of :size_t"
286
- end
273
+ sz = FFI.type_size(:size_t) * 8
274
+ type = "guint#{sz}"
275
+ alias_method :gtype_array_to_inptr, "#{type}_array_to_inptr"
276
+ alias_method :gtype_outptr, "#{type}_outptr"
277
+ alias_method :gtype_to_inoutptr, "#{type}_to_inoutptr"
278
+ alias_method :outptr_to_gtype, "outptr_to_#{type}"
279
+ alias_method :ptr_to_gtype_array, "ptr_to_#{type}_array"
287
280
  end
288
281
 
289
282
  def self.outptr_strv_to_utf8_array ptr
@@ -436,7 +429,11 @@ module GirFFI
436
429
  return nil if optr.null?
437
430
  tp = ::GObject.type_from_instance_pointer optr
438
431
  info = gir.find_by_gtype tp
439
- klass = GirFFI::Builder.build_class info
432
+ if info.nil?
433
+ klass = GirFFI::Builder::DynamicType.new(tp).build_class
434
+ else
435
+ klass = GirFFI::Builder.build_class info
436
+ end
440
437
  klass.wrap optr
441
438
  end
442
439
 
@@ -658,9 +658,9 @@ module GirFFI::Builder
658
658
  VoidReturnValue
659
659
  when :interface
660
660
  case type.interface.info_type
661
- when :interface, :struct, :union
661
+ when :struct, :union
662
662
  InterfaceReturnValue
663
- when :object
663
+ when :interface, :object
664
664
  if arginfo.constructor?
665
665
  ConstructorReturnValue
666
666
  else
@@ -0,0 +1,41 @@
1
+ module GirFFI
2
+ module Builder
3
+ class DynamicType
4
+ CACHE = {}
5
+
6
+ def initialize gtype
7
+ @gtype = gtype
8
+ end
9
+
10
+ def build_class
11
+ CACHE[@gtype] ||= Class.new(parent).tap do |klass|
12
+ interfaces.each do |iface|
13
+ klass.class_eval do
14
+ include iface
15
+ end
16
+ end
17
+ end
18
+ end
19
+
20
+ private
21
+
22
+ def parent
23
+ parent_type = ::GObject.type_parent @gtype
24
+ info = gir.find_by_gtype(parent_type)
25
+ GirFFI::Builder.build_class info
26
+ end
27
+
28
+ def interfaces
29
+ iface_types = ::GObject.type_interfaces @gtype
30
+ iface_types.map do |gtype|
31
+ info = gir.find_by_gtype gtype
32
+ GirFFI::Builder.build_class info
33
+ end
34
+ end
35
+
36
+ def gir
37
+ @gir ||= GirFFI::IRepository.default
38
+ end
39
+ end
40
+ end
41
+ end
@@ -4,7 +4,29 @@ module GirFFI
4
4
  module Type
5
5
 
6
6
  # Implements the creation of a class representing an Interface.
7
- class Interface < StructBased
7
+ class Interface < RegisteredType
8
+ def build_class
9
+ unless defined? @klass
10
+ instantiate_module
11
+ end
12
+ @klass
13
+ end
14
+
15
+ def instantiate_module
16
+ @klass = optionally_define_constant(namespace_module, @classname) do
17
+ ::Module.new do
18
+ def self.gir_ffi_builder
19
+ const_get :GIR_FFI_BUILDER
20
+ end
21
+ end
22
+ end
23
+ setup_module unless already_set_up
24
+ end
25
+
26
+ def setup_module
27
+ setup_constants
28
+ stub_methods
29
+ end
8
30
  end
9
31
  end
10
32
  end
@@ -5,9 +5,42 @@ module GirFFI
5
5
 
6
6
  # Implements the creation of a class representing a GObject Object.
7
7
  class Object < StructBased
8
+ def setup_method method
9
+ if super
10
+ return true
11
+ else
12
+ if parent
13
+ return superclass.gir_ffi_builder.setup_method method
14
+ else
15
+ return false
16
+ end
17
+ end
18
+ end
19
+
20
+ def setup_instance_method method
21
+ if super
22
+ return true
23
+ else
24
+ info.interfaces.each do |ifinfo|
25
+ iface = GirFFI::Builder.build_class ifinfo
26
+ if iface.gir_ffi_builder.setup_instance_method method
27
+ return true
28
+ end
29
+ end
30
+ if parent
31
+ return superclass.gir_ffi_builder.setup_instance_method method
32
+ else
33
+ return false
34
+ end
35
+ end
36
+ end
37
+
38
+ private
39
+
8
40
  def setup_class
9
41
  super
10
42
  setup_vfunc_invokers
43
+ setup_interfaces
11
44
  end
12
45
 
13
46
  def parent
@@ -36,6 +69,15 @@ module GirFFI
36
69
  end
37
70
  end
38
71
 
72
+ def setup_interfaces
73
+ info.interfaces.each do |ifinfo|
74
+ iface = GirFFI::Builder.build_class ifinfo
75
+ @klass.class_eval do
76
+ include iface
77
+ end
78
+ end
79
+ end
80
+
39
81
  def signal_definers
40
82
  [info] + info.interfaces
41
83
  end
@@ -14,30 +14,12 @@ module GirFFI
14
14
  meta = (class << klass; self; end)
15
15
 
16
16
  go = method_introspection_data method
17
- if go.nil?
18
- if parent
19
- return superclass.gir_ffi_builder.setup_method method
20
- else
21
- raise NoMethodError
22
- end
23
- end
24
-
25
17
  attach_and_define_method method, go, meta
26
18
  end
27
19
 
28
20
  def setup_instance_method method
29
21
  go = instance_method_introspection_data method
30
- result = attach_and_define_method method, go, build_class
31
-
32
- unless result
33
- if parent
34
- return superclass.gir_ffi_builder.setup_instance_method method
35
- else
36
- return false
37
- end
38
- end
39
-
40
- true
22
+ attach_and_define_method method, go, build_class
41
23
  end
42
24
 
43
25
  private
@@ -76,11 +58,7 @@ module GirFFI
76
58
  end
77
59
 
78
60
  def layout_specification
79
- fields = if info.info_type == :interface
80
- []
81
- else
82
- info.fields
83
- end
61
+ fields = info.fields
84
62
 
85
63
  if fields.empty?
86
64
  if parent
@@ -20,13 +20,16 @@ module GirFFI
20
20
  end
21
21
 
22
22
  def setup_and_call method, *arguments, &block
23
- result = gir_ffi_builder.setup_instance_method method.to_s
24
- return super unless result
23
+ unless gir_ffi_builder.setup_instance_method method.to_s
24
+ raise RuntimeError, "Unable to set up instance method #{method} in #{self}"
25
+ end
25
26
  self.send method, *arguments, &block
26
27
  end
27
28
 
28
29
  def self.setup_and_call method, *arguments, &block
29
- gir_ffi_builder.setup_method method.to_s
30
+ unless gir_ffi_builder.setup_method method.to_s
31
+ raise RuntimeError, "Unable to set up method #{method} in #{self}"
32
+ end
30
33
  self.send method, *arguments, &block
31
34
  end
32
35
 
@@ -0,0 +1,40 @@
1
+ require File.expand_path('test_helper.rb', File.dirname(__FILE__))
2
+
3
+ require 'gir_ffi/builder/dynamic_type'
4
+
5
+ describe "GirFFI::Builder::DynamicType" do
6
+ describe "building the GLocalFile type" do
7
+ before do
8
+ # Ensure existence of GLocalFile type
9
+ GirFFI.setup :Gio
10
+ unless Gio::Lib.respond_to? :g_file_new_for_path
11
+ Gio.gir_ffi_builder.setup_function "file_new_for_path"
12
+ end
13
+ ptr = GirFFI::ArgHelper.utf8_to_inptr '/'
14
+ Gio::Lib.g_file_new_for_path(ptr)
15
+
16
+ @gtype = GObject.type_from_name 'GLocalFile'
17
+ bldr = GirFFI::Builder::DynamicType.new(@gtype)
18
+ @klass = bldr.build_class
19
+ end
20
+
21
+ it "builds a class" do
22
+ assert_instance_of Class, @klass
23
+ end
24
+
25
+ it "builds a class derived from GObject::Object" do
26
+ assert_includes @klass.ancestors, GObject::Object
27
+ end
28
+
29
+ it "builds a class derived from Gio::File" do
30
+ assert_includes @klass.ancestors, Gio::File
31
+ end
32
+
33
+ it "returns the same class when built again" do
34
+ other_bldr = GirFFI::Builder::DynamicType.new(@gtype)
35
+ other_klass = other_bldr.build_class
36
+
37
+ assert_equal @klass, other_klass
38
+ end
39
+ end
40
+ end
@@ -7,10 +7,18 @@ class GeneratedGioTest < MiniTest::Spec
7
7
  GirFFI.setup :Gio
8
8
  end
9
9
 
10
- should "create a GFile with #file_new_from_path" do
11
- assert_nothing_raised {
12
- Gio.file_new_for_path('/')
13
- }
10
+ describe "#file_new_from_path, a method returning an interface," do
11
+ it "does not throw an error when generated" do
12
+ assert_nothing_raised {
13
+ Gio.file_new_for_path('/')
14
+ }
15
+ end
16
+
17
+ it "returns an object of a more specific class" do
18
+ file = Gio.file_new_for_path('/')
19
+ refute_instance_of Gio::File, file
20
+ assert_includes file.class.ancestors, Gio::File
21
+ end
14
22
  end
15
23
 
16
24
  context "the FileInfo class" do
@@ -21,9 +29,8 @@ class GeneratedGioTest < MiniTest::Spec
21
29
  end
22
30
 
23
31
  should "hava a working #get_attribute_type method" do
24
- assert_nothing_raised {
25
- @fileinfo.get_attribute_type "standard::displayname"
26
- }
32
+ type = @fileinfo.get_attribute_type "standard::display-name"
33
+ assert_equal :string, type
27
34
  end
28
35
  end
29
36
  end
@@ -0,0 +1,15 @@
1
+ require File.expand_path('test_helper.rb', File.dirname(__FILE__))
2
+
3
+ describe "The generated GObject module" do
4
+ before do
5
+ GirFFI.setup :GObject
6
+ end
7
+
8
+ describe "#type_interfaces" do
9
+ it "works, showing that returning an array of GType works" do
10
+ tp = GObject.type_from_name 'GTypeModule'
11
+ ifcs = GObject.type_interfaces tp
12
+ assert_equal 1, ifcs.size
13
+ end
14
+ end
15
+ end
@@ -45,7 +45,7 @@ class GeneratedGtkTest < MiniTest::Spec
45
45
  assert_equal "clicked", sn
46
46
  assert_equal "on_button_clicked", hn
47
47
  assert_equal nil, co
48
- assert_equal :after, f
48
+ assert_equal 0, f
49
49
  assert_equal nil, ud
50
50
  end
51
51
  end
@@ -0,0 +1,17 @@
1
+ require File.expand_path('test_helper.rb', File.dirname(__FILE__))
2
+
3
+ describe GirFFI::Builder::Type::Interface do
4
+ before do
5
+ info = get_function_introspection_data 'GObject', 'TypePlugin'
6
+ @bldr = GirFFI::Builder::Type::Interface.new info
7
+ @iface = @bldr.build_class
8
+ end
9
+
10
+ it "builds an interface as a module" do
11
+ assert_instance_of Module, @iface
12
+ end
13
+
14
+ it "creates methods on the interface" do
15
+ assert_includes @iface.instance_methods.map(&:to_s), 'complete_interface_info'
16
+ end
17
+ end
@@ -0,0 +1,34 @@
1
+ require File.expand_path('test_helper.rb', File.dirname(__FILE__))
2
+
3
+ describe GirFFI::Builder::Type::Object do
4
+ describe "building GObject::TypeModule, which implements an interface" do
5
+ before do
6
+ info = get_function_introspection_data 'GObject', 'TypeModule'
7
+ @bldr = GirFFI::Builder::Type::Object.new info
8
+ end
9
+
10
+ it "mixes the interface into the generated class" do
11
+ klass = @bldr.build_class
12
+ assert_includes klass.ancestors, GObject::TypePlugin
13
+ end
14
+ end
15
+
16
+ describe "building the CharsetConverter class" do
17
+ before do
18
+ GirFFI.setup :Gio
19
+ end
20
+
21
+ it "includes two interfaces" do
22
+ klass = Gio::CharsetConverter
23
+ assert_includes klass.ancestors, Gio::Converter
24
+ assert_includes klass.ancestors, Gio::Initable
25
+ end
26
+
27
+ it "allows an instance to find the #reset method" do
28
+ cnv = Gio::CharsetConverter.new "utf8", "utf8"
29
+ cnv.reset
30
+ pass
31
+ end
32
+ end
33
+ end
34
+
data/test/test_helper.rb CHANGED
@@ -1,3 +1,9 @@
1
+ if RUBY_PLATFORM == 'java'
2
+ require 'java'
3
+ JRuby.objectspace = true
4
+ require 'rubygems'
5
+ end
6
+
1
7
  require 'minitest/spec'
2
8
  require 'minitest/autorun'
3
9
  require 'rr'
@@ -9,11 +15,6 @@ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
9
15
 
10
16
  require 'gir_ffi'
11
17
 
12
- if RUBY_PLATFORM == 'java'
13
- require 'java'
14
- JRuby.objectspace = true
15
- end
16
-
17
18
  # Since the tests will call Gtk+ functions, Gtk+ must be initialized.
18
19
  GirFFI.setup :Gtk, '2.0'
19
20
  Gtk.init
@@ -47,6 +48,7 @@ class MiniTest::Unit::TestCase
47
48
  code.gsub(/(^\s*|\s*$)/, "")
48
49
  end
49
50
 
51
+ # FIXME: Rename. It can also get object, interface, etc., data.
50
52
  def get_function_introspection_data namespace, function
51
53
  gir = GirFFI::IRepository.default
52
54
  gir.require namespace, nil
@@ -62,8 +62,8 @@ class TypeBuilderTest < MiniTest::Spec
62
62
  @cbuilder = GirFFI::Builder::Type::Union.new get_function_introspection_data('GObject', 'TypeCValue')
63
63
  end
64
64
 
65
- should "not raise an error looking for a method that doesn't exist" do
66
- assert_nothing_raised { @cbuilder.setup_instance_method 'blub' }
65
+ should "returns false looking for a method that doesn't exist" do
66
+ assert_equal false, @cbuilder.setup_instance_method('blub')
67
67
  end
68
68
  end
69
69
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gir_ffi
3
3
  version: !ruby/object:Gem::Version
4
- hash: 13
4
+ hash: 11
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 9
10
- version: 0.0.9
9
+ - 10
10
+ version: 0.0.10
11
11
  platform: ruby
12
12
  authors:
13
13
  - Matijs van Zuijlen
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-05-02 00:00:00 Z
18
+ date: 2011-05-18 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: ffi
@@ -25,12 +25,12 @@ dependencies:
25
25
  requirements:
26
26
  - - ~>
27
27
  - !ruby/object:Gem::Version
28
- hash: 31
28
+ hash: 7
29
29
  segments:
30
30
  - 1
31
31
  - 0
32
- - 4
33
- version: 1.0.4
32
+ - 8
33
+ version: 1.0.8
34
34
  type: :runtime
35
35
  version_requirements: *id001
36
36
  - !ruby/object:Gem::Dependency
@@ -86,6 +86,7 @@ files:
86
86
  - lib/gir_ffi/g_error.rb
87
87
  - lib/gir_ffi/i_object_info.rb
88
88
  - lib/gir_ffi/builder.rb
89
+ - lib/gir_ffi/builder/dynamic_type.rb
89
90
  - lib/gir_ffi/builder/module.rb
90
91
  - lib/gir_ffi/builder/function.rb
91
92
  - lib/gir_ffi/builder/type/base.rb
@@ -137,9 +138,11 @@ files:
137
138
  - test/lib/autogen.sh
138
139
  - test/lib/configure.ac
139
140
  - test/lib/m4/jhflags.m4
141
+ - test/dynamic_type_builder_test.rb
140
142
  - test/class_base_test.rb
141
143
  - test/test_helper.rb
142
144
  - test/girffi_test.rb
145
+ - test/interface_type_builder_test.rb
143
146
  - test/module_builder_test.rb
144
147
  - test/i_object_info_test.rb
145
148
  - test/g_object_overrides_test.rb
@@ -148,6 +151,8 @@ files:
148
151
  - test/builder_test.rb
149
152
  - test/glib_overrides_test.rb
150
153
  - test/gtk_overrides_test.rb
154
+ - test/object_type_builder_test.rb
155
+ - test/generated_gobject_test.rb
151
156
  - test/generated_gio_test.rb
152
157
  - test/generated_gimarshallingtests_test.rb
153
158
  - tasks/test.rake
@@ -204,11 +209,13 @@ test_files:
204
209
  - test/arg_helper_test.rb
205
210
  - test/builder_test.rb
206
211
  - test/class_base_test.rb
212
+ - test/dynamic_type_builder_test.rb
207
213
  - test/function_definition_builder_test.rb
208
214
  - test/g_object_overrides_test.rb
209
215
  - test/g_object_test.rb
210
216
  - test/generated_gimarshallingtests_test.rb
211
217
  - test/generated_gio_test.rb
218
+ - test/generated_gobject_test.rb
212
219
  - test/generated_gtk_test.rb
213
220
  - test/generated_regress_test.rb
214
221
  - test/girffi_test.rb
@@ -216,10 +223,12 @@ test_files:
216
223
  - test/gtk_overrides_test.rb
217
224
  - test/i_object_info_test.rb
218
225
  - test/i_repository_test.rb
226
+ - test/interface_type_builder_test.rb
219
227
  - test/lib/Makefile.am
220
228
  - test/lib/autogen.sh
221
229
  - test/lib/configure.ac
222
230
  - test/lib/m4/jhflags.m4
223
231
  - test/module_builder_test.rb
232
+ - test/object_type_builder_test.rb
224
233
  - test/test_helper.rb
225
234
  - test/type_builder_test.rb