gir_ffi 0.0.9 → 0.0.10

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