gir_ffi 0.8.1 → 0.8.2
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.
- checksums.yaml +4 -4
- data/Changelog.md +16 -0
- data/DESIGN.md +17 -15
- data/lib/ffi-glib/array.rb +4 -5
- data/lib/ffi-glib/byte_array.rb +2 -4
- data/lib/ffi-glib/bytes.rb +12 -2
- data/lib/ffi-glib/hash_table.rb +31 -31
- data/lib/ffi-glib/list_methods.rb +5 -15
- data/lib/ffi-glib/ptr_array.rb +3 -3
- data/lib/ffi-gobject/closure.rb +2 -0
- data/lib/ffi-gobject/ruby_closure.rb +13 -15
- data/lib/ffi-gobject/value.rb +33 -27
- data/lib/ffi-gobject.rb +5 -3
- data/lib/ffi-gobject_introspection/i_base_info.rb +2 -1
- data/lib/ffi-gobject_introspection/i_interface_info.rb +1 -1
- data/lib/ffi-gobject_introspection/i_object_info.rb +2 -2
- data/lib/ffi-gobject_introspection/i_struct_info.rb +1 -1
- data/lib/ffi-gobject_introspection/i_union_info.rb +1 -1
- data/lib/gir_ffi/boxed_base.rb +8 -6
- data/lib/gir_ffi/builders/boxed_builder.rb +0 -10
- data/lib/gir_ffi/builders/null_class_builder.rb +13 -0
- data/lib/gir_ffi/builders/user_defined_builder.rb +3 -3
- data/lib/gir_ffi/class_base.rb +10 -6
- data/lib/gir_ffi/in_out_pointer.rb +1 -5
- data/lib/gir_ffi/info_ext/i_registered_type_info.rb +4 -0
- data/lib/gir_ffi/user_defined_type_info.rb +4 -0
- data/lib/gir_ffi/version.rb +1 -1
- data/test/ffi-glib/ruby_closure_test.rb +1 -1
- data/test/ffi-gobject/value_test.rb +29 -0
- data/test/ffi-gobject_introspection/i_interface_info_test.rb +21 -0
- data/test/ffi-gobject_introspection/i_object_info_test.rb +15 -1
- data/test/ffi-gobject_introspection/i_struct_info_test.rb +21 -0
- data/test/ffi-gobject_introspection/i_union_info_test.rb +15 -0
- data/test/gir_ffi/class_base_test.rb +31 -6
- data/test/gir_ffi/in_out_pointer_test.rb +21 -2
- data/test/gir_ffi/user_defined_type_info_test.rb +9 -0
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6121625e854dd754146516dab64b67c650155c67
|
4
|
+
data.tar.gz: e486edea5ebffe7146c68dca786796f94ac58945
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 170a26c6f8aecc34a77722a5525d8b1534491febdd244fff0a9c88aa298a357ee0914f1fc15393da52b306d2f295e7aaba0180f258a187e942433658e51262ae
|
7
|
+
data.tar.gz: afbed9ce4c8869f8e44b6c1bbb36d22192bf27e01720874d9e3632fd5dd4b59fcc5604e785c39ccf1c6b8e6fe084270d7efee54f992a70e36dc469fd93508031
|
data/Changelog.md
CHANGED
@@ -1,5 +1,21 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## 0.8.2 / 2015-10-10
|
4
|
+
|
5
|
+
* Use inherited constructor for boxed types
|
6
|
+
* Make InOutPointer work correctly for boxed types
|
7
|
+
* Make .for work with boxed types
|
8
|
+
* Make #set_value work with boxed types
|
9
|
+
* Make GObject::Value support nil type:
|
10
|
+
* Make .wrap_ruby_value(nil) work
|
11
|
+
* Make #set_value and #get_value work when the type is TYPE_INVALID
|
12
|
+
* Make .for_gtype work with TYPE_INVALID and TYPE_NONE
|
13
|
+
* Make .from(nil) return a GObject::Value instead of nil
|
14
|
+
* Make #set_ruby_value private
|
15
|
+
* Make GObject::Object.signal_emit work with gobject-introspection 1.46
|
16
|
+
* Replace or remove all custom .new methods
|
17
|
+
* Make setup_method and setup_instance_method handle symbol arguments
|
18
|
+
|
3
19
|
## 0.8.1 / 2015-10-04
|
4
20
|
|
5
21
|
* Handle struct array fields with related length fields
|
data/DESIGN.md
CHANGED
@@ -64,25 +64,27 @@ cannot bootstrap itself.
|
|
64
64
|
|
65
65
|
## Object initialization
|
66
66
|
|
67
|
-
|
67
|
+
Each constructor method is implemented in Ruby by a pair of new/initialize
|
68
|
+
methods. For example, a constructor `new_from_file` is implemented as a
|
69
|
+
combination of the singleton method `new_from_file` and the instance method
|
70
|
+
`initialize_from_file`. User-created subclasses override the appropriate
|
71
|
+
initializer method and must call super with the appropriate arguments.
|
68
72
|
|
69
|
-
|
70
|
-
|
71
|
-
* No aliasing of Ruby's new. Overriding is possible with super being called.
|
72
|
-
* #initialize should behave as expected. We may enforce use of super in Ruby
|
73
|
-
subclasses.
|
74
|
-
|
75
|
-
Schematic depiction of what happens (can happen):
|
73
|
+
Here is an example of the generated pair of methods:
|
76
74
|
|
77
75
|
```ruby
|
78
|
-
class
|
79
|
-
def self.
|
80
|
-
|
81
|
-
|
82
|
-
|
76
|
+
class Regress::TestObj
|
77
|
+
def self.new_from_file(*args)
|
78
|
+
obj = allocate
|
79
|
+
obj.__send__ :initialize_from_file, *args
|
80
|
+
obj
|
83
81
|
end
|
84
82
|
|
85
|
-
def
|
86
|
-
|
83
|
+
def initialize_from_file(x)
|
84
|
+
_v1 = GirFFI::InPointer.from(:utf8, x)
|
85
|
+
_v2 = FFI::MemoryPointer.new(:pointer).write_pointer nil
|
86
|
+
_v3 = Regress::Lib.regress_test_obj_new_from_file _v1, _v2
|
87
|
+
GirFFI::ArgHelper.check_error(_v2)
|
88
|
+
store_pointer(_v3)
|
87
89
|
end
|
88
90
|
end
|
data/lib/ffi-glib/array.rb
CHANGED
@@ -13,11 +13,10 @@ module GLib
|
|
13
13
|
|
14
14
|
attr_reader :element_type
|
15
15
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
ptr
|
20
|
-
wrap type, ptr
|
16
|
+
def initialize(type)
|
17
|
+
@element_type = type
|
18
|
+
ptr = Lib.g_array_new(0, 0, calculated_element_size)
|
19
|
+
store_pointer(ptr)
|
21
20
|
end
|
22
21
|
|
23
22
|
# @api private
|
data/lib/ffi-glib/byte_array.rb
CHANGED
data/lib/ffi-glib/bytes.rb
CHANGED
@@ -32,13 +32,23 @@ module GLib
|
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
35
|
+
# Why redefine new here? The class builder will only define the full
|
36
|
+
# version of 'new' on first call, causing both new and initialize to be
|
37
|
+
# defined. This overwrites the custom version of initialize below.
|
38
|
+
# TODO: Improve class builder so this trick is not needed.
|
35
39
|
class << self
|
36
40
|
undef new
|
37
41
|
end
|
38
42
|
|
39
|
-
def self.new(
|
43
|
+
def self.new(*args)
|
44
|
+
obj = allocate
|
45
|
+
obj.__send__ :initialize, *args
|
46
|
+
obj
|
47
|
+
end
|
48
|
+
|
49
|
+
def initialize(arr)
|
40
50
|
data = GirFFI::SizedArray.from :guint8, arr.size, arr
|
41
|
-
|
51
|
+
store_pointer Lib.g_bytes_new data.to_ptr, data.size
|
42
52
|
end
|
43
53
|
|
44
54
|
private
|
data/lib/ffi-glib/hash_table.rb
CHANGED
@@ -11,11 +11,11 @@ module GLib
|
|
11
11
|
attr_reader :key_type
|
12
12
|
attr_reader :value_type
|
13
13
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
14
|
+
def initialize(key_type, value_type)
|
15
|
+
@key_type = key_type
|
16
|
+
@value_type = value_type
|
17
|
+
store_pointer Lib.g_hash_table_new(
|
18
|
+
hash_function_for_key_type, equality_function_for_key_type)
|
19
19
|
end
|
20
20
|
|
21
21
|
# @api private
|
@@ -27,32 +27,6 @@ module GLib
|
|
27
27
|
ghash
|
28
28
|
end
|
29
29
|
|
30
|
-
# @api private
|
31
|
-
def self.hash_function_for(keytype)
|
32
|
-
case keytype
|
33
|
-
when :utf8
|
34
|
-
FFI::Function.new(:uint,
|
35
|
-
[:pointer],
|
36
|
-
find_support_function('g_str_hash'))
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
# @api private
|
41
|
-
def self.equality_function_for(keytype)
|
42
|
-
case keytype
|
43
|
-
when :utf8
|
44
|
-
FFI::Function.new(:int,
|
45
|
-
[:pointer, :pointer],
|
46
|
-
find_support_function('g_str_equal'))
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
# @api private
|
51
|
-
def self.find_support_function(name)
|
52
|
-
lib = ::GLib::Lib.ffi_libraries.first
|
53
|
-
lib.find_function(name)
|
54
|
-
end
|
55
|
-
|
56
30
|
def each
|
57
31
|
prc = proc do|keyptr, valptr, _userdata|
|
58
32
|
key = GirFFI::ArgHelper.cast_from_pointer key_type, keyptr
|
@@ -79,5 +53,31 @@ module GLib
|
|
79
53
|
@key_type, @value_type = *typespec
|
80
54
|
self
|
81
55
|
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
def hash_function_for_key_type
|
60
|
+
case @key_type
|
61
|
+
when :utf8
|
62
|
+
FFI::Function.new(:uint,
|
63
|
+
[:pointer],
|
64
|
+
find_support_function('g_str_hash'))
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def equality_function_for_key_type
|
69
|
+
case @key_type
|
70
|
+
when :utf8
|
71
|
+
FFI::Function.new(:int,
|
72
|
+
[:pointer, :pointer],
|
73
|
+
find_support_function('g_str_equal'))
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def find_support_function(name)
|
78
|
+
lib = ::GLib::Lib.ffi_libraries.first
|
79
|
+
lib.find_function(name)
|
80
|
+
end
|
81
|
+
|
82
82
|
end
|
83
83
|
end
|
@@ -11,9 +11,6 @@ module GLib
|
|
11
11
|
replace_method base, :next, :tail
|
12
12
|
replace_method base, :data, :head
|
13
13
|
|
14
|
-
class << base; self end.send :remove_method, :new
|
15
|
-
base.extend ListClassMethods
|
16
|
-
|
17
14
|
base.extend ContainerClassMethods
|
18
15
|
end
|
19
16
|
|
@@ -24,6 +21,11 @@ module GLib
|
|
24
21
|
end
|
25
22
|
end
|
26
23
|
|
24
|
+
def initialize(type)
|
25
|
+
store_pointer(FFI::Pointer.new(0))
|
26
|
+
@element_type = type
|
27
|
+
end
|
28
|
+
|
27
29
|
def each
|
28
30
|
reset_iterator
|
29
31
|
while (elem = next_element)
|
@@ -64,17 +66,5 @@ module GLib
|
|
64
66
|
def element_ptr_for(data)
|
65
67
|
GirFFI::InPointer.from(element_type, data)
|
66
68
|
end
|
67
|
-
|
68
|
-
# Common class methods for List and SList
|
69
|
-
module ListClassMethods
|
70
|
-
# TODO: Make this behave more like a real .new method
|
71
|
-
def new(type)
|
72
|
-
allocate.tap do |it|
|
73
|
-
struct = self::Struct.new(FFI::Pointer.new(0))
|
74
|
-
it.instance_variable_set :@struct, struct
|
75
|
-
it.instance_variable_set :@element_type, type
|
76
|
-
end
|
77
|
-
end
|
78
|
-
end
|
79
69
|
end
|
80
70
|
end
|
data/lib/ffi-glib/ptr_array.rb
CHANGED
@@ -16,13 +16,13 @@ module GLib
|
|
16
16
|
POINTER_SIZE = FFI.type_size(:pointer)
|
17
17
|
|
18
18
|
class << self
|
19
|
-
remove_method :new
|
20
19
|
# Remove stub generated by builder.
|
21
20
|
remove_method :add if method_defined? :add
|
22
21
|
end
|
23
22
|
|
24
|
-
def
|
25
|
-
|
23
|
+
def initialize(type)
|
24
|
+
@element_type = type
|
25
|
+
store_pointer Lib.g_ptr_array_new
|
26
26
|
end
|
27
27
|
|
28
28
|
def self.from_enumerable(type, it)
|
data/lib/ffi-gobject/closure.rb
CHANGED
@@ -15,14 +15,12 @@ module GObject
|
|
15
15
|
:block_id, :int64
|
16
16
|
end
|
17
17
|
|
18
|
-
def
|
18
|
+
def initialize(&block)
|
19
19
|
raise ArgumentError unless block_given?
|
20
20
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
closure
|
21
|
+
initialize_simple(self.class::Struct.size, nil)
|
22
|
+
self.block = block
|
23
|
+
set_marshal proc { |*args| self.class.marshaller(*args) }
|
26
24
|
end
|
27
25
|
|
28
26
|
# @api private
|
@@ -36,24 +34,24 @@ module GObject
|
|
36
34
|
|
37
35
|
result = rclosure.invoke_block(*args)
|
38
36
|
|
39
|
-
return_value.
|
40
|
-
end
|
41
|
-
|
42
|
-
# @api private
|
43
|
-
# TODO: Re-structure so block= and invoke_block can become private methods
|
44
|
-
def block=(block)
|
45
|
-
id = block.object_id
|
46
|
-
BLOCK_STORE[id] = block
|
47
|
-
@struct[:block_id] = id
|
37
|
+
return_value.set_value(result) if return_value
|
48
38
|
end
|
49
39
|
|
50
40
|
# @api private
|
41
|
+
# TODO: Re-structure so invoke_block can become a private method
|
51
42
|
def invoke_block(*args)
|
52
43
|
block.call(*args)
|
53
44
|
end
|
54
45
|
|
55
46
|
private
|
56
47
|
|
48
|
+
# @api private
|
49
|
+
def block=(block)
|
50
|
+
id = block.object_id
|
51
|
+
BLOCK_STORE[id] = block
|
52
|
+
@struct[:block_id] = id
|
53
|
+
end
|
54
|
+
|
57
55
|
def block
|
58
56
|
BLOCK_STORE[@struct[:block_id]]
|
59
57
|
end
|
data/lib/ffi-gobject/value.rb
CHANGED
@@ -6,6 +6,7 @@ module GObject
|
|
6
6
|
setup_instance_method 'init'
|
7
7
|
|
8
8
|
def init_with_finalizer(type)
|
9
|
+
return self if [TYPE_NONE, TYPE_INVALID].include? type
|
9
10
|
init_without_finalizer(type).tap do
|
10
11
|
ObjectSpace.define_finalizer self, self.class.make_finalizer(to_ptr)
|
11
12
|
end
|
@@ -20,13 +21,8 @@ module GObject
|
|
20
21
|
end
|
21
22
|
end
|
22
23
|
|
23
|
-
# TODO: Give more generic name
|
24
|
-
def set_ruby_value(val)
|
25
|
-
init_for_ruby_value val if current_gtype == 0
|
26
|
-
set_value val
|
27
|
-
end
|
28
|
-
|
29
24
|
METHOD_MAP = {
|
25
|
+
TYPE_INVALID => [:get_none, :set_none],
|
30
26
|
TYPE_BOOLEAN => [:get_boolean, :set_boolean],
|
31
27
|
TYPE_BOXED => [:get_boxed, :set_boxed],
|
32
28
|
TYPE_CHAR => [:get_char, :set_char],
|
@@ -55,23 +51,6 @@ module GObject
|
|
55
51
|
|
56
52
|
alias_method :value=, :set_value
|
57
53
|
|
58
|
-
CLASS_TO_GTYPE_MAP = {
|
59
|
-
TrueClass => TYPE_BOOLEAN,
|
60
|
-
FalseClass => TYPE_BOOLEAN,
|
61
|
-
Integer => TYPE_INT,
|
62
|
-
String => TYPE_STRING
|
63
|
-
}
|
64
|
-
|
65
|
-
def init_for_ruby_value(val)
|
66
|
-
CLASS_TO_GTYPE_MAP.each do |klass, type|
|
67
|
-
if val.is_a? klass
|
68
|
-
init type
|
69
|
-
return self
|
70
|
-
end
|
71
|
-
end
|
72
|
-
raise "Can't handle #{val.class}"
|
73
|
-
end
|
74
|
-
|
75
54
|
def current_gtype
|
76
55
|
@struct[:g_type]
|
77
56
|
end
|
@@ -99,22 +78,19 @@ module GObject
|
|
99
78
|
|
100
79
|
# TODO: Give more generic name
|
101
80
|
def self.wrap_ruby_value(val)
|
102
|
-
new.tap { |gv| gv.set_ruby_value val }
|
81
|
+
new.tap { |gv| gv.__send__ :set_ruby_value, val }
|
103
82
|
end
|
104
83
|
|
105
84
|
def self.from(val)
|
106
85
|
case val
|
107
86
|
when self
|
108
87
|
val
|
109
|
-
when nil
|
110
|
-
nil
|
111
88
|
else
|
112
89
|
wrap_ruby_value val
|
113
90
|
end
|
114
91
|
end
|
115
92
|
|
116
93
|
def self.for_gtype(gtype)
|
117
|
-
return nil if gtype == TYPE_NONE
|
118
94
|
new.tap do |it|
|
119
95
|
it.init gtype
|
120
96
|
end
|
@@ -130,6 +106,36 @@ module GObject
|
|
130
106
|
|
131
107
|
private
|
132
108
|
|
109
|
+
def set_ruby_value(val)
|
110
|
+
init_for_ruby_value val if uninitialized?
|
111
|
+
set_value val
|
112
|
+
end
|
113
|
+
|
114
|
+
CLASS_TO_GTYPE_MAP = {
|
115
|
+
NilClass => TYPE_INVALID,
|
116
|
+
TrueClass => TYPE_BOOLEAN,
|
117
|
+
FalseClass => TYPE_BOOLEAN,
|
118
|
+
Integer => TYPE_INT,
|
119
|
+
String => TYPE_STRING
|
120
|
+
}
|
121
|
+
|
122
|
+
def init_for_ruby_value(val)
|
123
|
+
CLASS_TO_GTYPE_MAP.each do |klass, type|
|
124
|
+
return init type if val.is_a? klass
|
125
|
+
end
|
126
|
+
raise "Can't handle #{val.class}"
|
127
|
+
end
|
128
|
+
|
129
|
+
def set_none(_)
|
130
|
+
end
|
131
|
+
|
132
|
+
def get_none
|
133
|
+
end
|
134
|
+
|
135
|
+
def uninitialized?
|
136
|
+
current_gtype == TYPE_INVALID
|
137
|
+
end
|
138
|
+
|
133
139
|
def set_instance_enhanced(val)
|
134
140
|
check_type_compatibility val if val
|
135
141
|
set_instance val
|
data/lib/ffi-gobject.rb
CHANGED
@@ -47,9 +47,11 @@ module GObject
|
|
47
47
|
argument_gvalues = sig_info.arguments_to_gvalues object, args
|
48
48
|
return_gvalue = sig_info.gvalue_for_return_value
|
49
49
|
|
50
|
-
signal_emitv argument_gvalues, signal_id, detail_quark, return_gvalue
|
51
|
-
|
52
|
-
return_gvalue
|
50
|
+
result = signal_emitv argument_gvalues, signal_id, detail_quark, return_gvalue
|
51
|
+
# NOTE: Depending on the version of GObjectIntrospection, the result will
|
52
|
+
# be stored in result or return_gvalue. This was changed between versions
|
53
|
+
# 1.44 and 1.46.
|
54
|
+
result || return_gvalue
|
53
55
|
end
|
54
56
|
|
55
57
|
def self.signal_connect(object, detailed_signal, data = nil, after = false, &block)
|
@@ -68,7 +68,7 @@ module GObjectIntrospection
|
|
68
68
|
build_array_method :get_methods
|
69
69
|
|
70
70
|
def find_method(name)
|
71
|
-
IFunctionInfo.wrap(Lib.g_object_info_find_method @gobj, name)
|
71
|
+
IFunctionInfo.wrap(Lib.g_object_info_find_method @gobj, name.to_s)
|
72
72
|
end
|
73
73
|
|
74
74
|
def n_signals
|
@@ -92,7 +92,7 @@ module GObjectIntrospection
|
|
92
92
|
end
|
93
93
|
|
94
94
|
def find_vfunc(name)
|
95
|
-
IVFuncInfo.wrap(Lib.g_object_info_find_vfunc @gobj, name)
|
95
|
+
IVFuncInfo.wrap(Lib.g_object_info_find_vfunc @gobj, name.to_s)
|
96
96
|
end
|
97
97
|
##
|
98
98
|
build_array_method :vfuncs
|
@@ -24,7 +24,7 @@ module GObjectIntrospection
|
|
24
24
|
|
25
25
|
##
|
26
26
|
build_array_method :get_methods
|
27
|
-
# There is a function
|
27
|
+
# There is a function g_struct_info_find_method but it causes a core dump.
|
28
28
|
build_finder_method :find_method, :get_n_methods, :get_method
|
29
29
|
|
30
30
|
def size
|
data/lib/gir_ffi/boxed_base.rb
CHANGED
@@ -23,14 +23,16 @@ module GirFFI
|
|
23
23
|
|
24
24
|
def self.copy_value_to_pointer(value, pointer, offset = 0)
|
25
25
|
size = self::Struct.size
|
26
|
-
|
26
|
+
bytes = if value
|
27
|
+
value.to_ptr.read_bytes(size)
|
28
|
+
else
|
29
|
+
"\x00" * size
|
30
|
+
end
|
31
|
+
pointer.put_bytes offset, bytes, 0, size
|
27
32
|
end
|
28
33
|
|
29
|
-
|
30
|
-
|
31
|
-
obj = allocate
|
32
|
-
obj.instance_variable_set :@struct, self::Struct.new
|
33
|
-
obj
|
34
|
+
def initialize
|
35
|
+
@struct = self.class::Struct.new
|
34
36
|
end
|
35
37
|
end
|
36
38
|
end
|
@@ -14,16 +14,6 @@ module GirFFI
|
|
14
14
|
setup_constants
|
15
15
|
stub_methods
|
16
16
|
setup_field_accessors
|
17
|
-
provide_constructor
|
18
|
-
end
|
19
|
-
|
20
|
-
def provide_constructor
|
21
|
-
return if info.find_method 'new'
|
22
|
-
|
23
|
-
# TODO: Provide both new and initialize
|
24
|
-
(class << klass; self; end).class_eval do
|
25
|
-
alias_method :new, :_allocate
|
26
|
-
end
|
27
17
|
end
|
28
18
|
end
|
29
19
|
end
|
@@ -200,9 +200,9 @@ module GirFFI
|
|
200
200
|
|
201
201
|
def setup_constructor
|
202
202
|
code = <<-CODE
|
203
|
-
def
|
204
|
-
|
205
|
-
|
203
|
+
def initialize
|
204
|
+
ptr = GObject::Lib.g_object_newv #{@gtype}, 0, nil
|
205
|
+
store_pointer(ptr)
|
206
206
|
end
|
207
207
|
CODE
|
208
208
|
klass.class_eval code
|
data/lib/gir_ffi/class_base.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'forwardable'
|
2
2
|
require 'gir_ffi/registered_type_base'
|
3
|
+
require 'gir_ffi/builders/null_class_builder'
|
3
4
|
|
4
5
|
module GirFFI
|
5
6
|
# Base class for all generated classes and structs. Contains code for dealing
|
@@ -8,6 +9,8 @@ module GirFFI
|
|
8
9
|
extend RegisteredTypeBase
|
9
10
|
extend Forwardable
|
10
11
|
|
12
|
+
GIR_FFI_BUILDER = Builders::NullClassBuilder.new
|
13
|
+
|
11
14
|
attr_reader :struct
|
12
15
|
def_delegators :@struct, :to_ptr
|
13
16
|
|
@@ -15,7 +18,7 @@ module GirFFI
|
|
15
18
|
method_name = self.class.try_in_ancestors(:setup_instance_method, method.to_s)
|
16
19
|
|
17
20
|
unless method_name
|
18
|
-
raise "
|
21
|
+
raise NoMethodError, "undefined method `#{method}' for #{self}"
|
19
22
|
end
|
20
23
|
|
21
24
|
send method_name, *arguments, &block
|
@@ -27,11 +30,15 @@ module GirFFI
|
|
27
30
|
other.class == self.class && to_ptr.address == other.to_ptr.address
|
28
31
|
end
|
29
32
|
|
33
|
+
def initialize
|
34
|
+
raise NoMethodError
|
35
|
+
end
|
36
|
+
|
30
37
|
def self.setup_and_call(method, arguments, &block)
|
31
38
|
method_name = try_in_ancestors(:setup_method, method.to_s)
|
32
39
|
|
33
40
|
unless method_name
|
34
|
-
raise "
|
41
|
+
raise NoMethodError, "undefined method `#{method}' for #{self}"
|
35
42
|
end
|
36
43
|
|
37
44
|
send method_name, *arguments, &block
|
@@ -44,6 +51,7 @@ module GirFFI
|
|
44
51
|
return result if result
|
45
52
|
end
|
46
53
|
end
|
54
|
+
nil
|
47
55
|
end
|
48
56
|
|
49
57
|
def self.to_ffi_type
|
@@ -58,10 +66,6 @@ module GirFFI
|
|
58
66
|
gir_ffi_builder.setup_instance_method name
|
59
67
|
end
|
60
68
|
|
61
|
-
class << self
|
62
|
-
undef new
|
63
|
-
end
|
64
|
-
|
65
69
|
# Wrap the passed pointer in an instance of the current class, or a
|
66
70
|
# descendant type if applicable.
|
67
71
|
def self.wrap(ptr)
|
@@ -52,7 +52,7 @@ module GirFFI
|
|
52
52
|
end
|
53
53
|
|
54
54
|
def clear
|
55
|
-
|
55
|
+
put_bytes 0, "\x00" * value_type_size, 0, value_type_size
|
56
56
|
end
|
57
57
|
|
58
58
|
def self.for(type)
|
@@ -72,9 +72,5 @@ module GirFFI
|
|
72
72
|
def value_type_size
|
73
73
|
@value_type_size ||= FFI.type_size value_ffi_type
|
74
74
|
end
|
75
|
-
|
76
|
-
def nil_value
|
77
|
-
value_ffi_type == :pointer ? nil : 0
|
78
|
-
end
|
79
75
|
end
|
80
76
|
end
|
data/lib/gir_ffi/version.rb
CHANGED
@@ -38,7 +38,7 @@ describe GObject::RubyClosure do
|
|
38
38
|
|
39
39
|
it "stores the closure's return value in the proper gvalue" do
|
40
40
|
c = GObject::RubyClosure.new { 2 }
|
41
|
-
gv = GObject::Value.new
|
41
|
+
gv = GObject::Value.new.init GObject::TYPE_INT
|
42
42
|
GObject::RubyClosure.marshaller(c, gv, nil, nil, nil)
|
43
43
|
assert_equal 2, gv.get_value
|
44
44
|
end
|
@@ -18,6 +18,23 @@ describe GObject::Value do
|
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
21
|
+
describe '.for_gtype' do
|
22
|
+
it 'handles char' do
|
23
|
+
gv = GObject::Value.for_gtype GObject::TYPE_CHAR
|
24
|
+
gv.current_gtype.must_equal GObject::TYPE_CHAR
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'handles invalid type' do
|
28
|
+
gv = GObject::Value.for_gtype GObject::TYPE_INVALID
|
29
|
+
gv.current_gtype.must_equal GObject::TYPE_INVALID
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'handles void type' do
|
33
|
+
gv = GObject::Value.for_gtype GObject::TYPE_NONE
|
34
|
+
gv.current_gtype.must_equal GObject::TYPE_INVALID
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
21
38
|
describe '::wrap_ruby_value' do
|
22
39
|
it 'wraps a boolean false' do
|
23
40
|
gv = GObject::Value.wrap_ruby_value false
|
@@ -40,6 +57,12 @@ describe GObject::Value do
|
|
40
57
|
gv = GObject::Value.wrap_ruby_value 'Some Random String'
|
41
58
|
assert_equal 'Some Random String', gv.get_string
|
42
59
|
end
|
60
|
+
|
61
|
+
it 'wraps nil' do
|
62
|
+
gv = GObject::Value.wrap_ruby_value nil
|
63
|
+
assert_instance_of GObject::Value, gv
|
64
|
+
assert_equal nil, gv.get_value
|
65
|
+
end
|
43
66
|
end
|
44
67
|
|
45
68
|
describe '#set_value' do
|
@@ -247,6 +270,12 @@ describe GObject::Value do
|
|
247
270
|
gv2.current_gtype_name.must_equal 'gint'
|
248
271
|
gv2.get_value.must_equal 21
|
249
272
|
end
|
273
|
+
|
274
|
+
it 'creates a null GValue from a Ruby nil' do
|
275
|
+
gv = GObject::Value.from nil
|
276
|
+
gv.current_gtype.must_equal GObject::TYPE_INVALID
|
277
|
+
gv.get_value.must_equal nil
|
278
|
+
end
|
250
279
|
end
|
251
280
|
|
252
281
|
describe '#set_value' do
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'introspection_test_helper'
|
2
|
+
|
3
|
+
describe GObjectIntrospection::IInterfaceInfo do
|
4
|
+
let(:object_info) { get_introspection_data('GObject', 'TypePlugin') }
|
5
|
+
|
6
|
+
describe '#find_method' do
|
7
|
+
it 'finds a method by name string' do
|
8
|
+
object_info.find_method('complete_interface_info').wont_be_nil
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'finds a method by name symbol' do
|
12
|
+
object_info.find_method(:complete_interface_info).wont_be_nil
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe '#type_name' do
|
17
|
+
it 'returns the correct name' do
|
18
|
+
object_info.type_name.must_equal 'GTypePlugin'
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -4,9 +4,23 @@ describe GObjectIntrospection::IObjectInfo do
|
|
4
4
|
let(:object_info) { get_introspection_data('GObject', 'Object') }
|
5
5
|
|
6
6
|
describe '#find_vfunc' do
|
7
|
-
it 'finds a vfunc by name' do
|
7
|
+
it 'finds a vfunc by name string' do
|
8
8
|
object_info.find_vfunc('finalize').wont_be_nil
|
9
9
|
end
|
10
|
+
|
11
|
+
it 'finds a vfunc by name symbol' do
|
12
|
+
object_info.find_vfunc(:finalize).wont_be_nil
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe '#find_method' do
|
17
|
+
it 'finds a method by name string' do
|
18
|
+
object_info.find_method('bind_property').wont_be_nil
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'finds a method by name symbol' do
|
22
|
+
object_info.find_method(:bind_property).wont_be_nil
|
23
|
+
end
|
10
24
|
end
|
11
25
|
|
12
26
|
describe '#type_name' do
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'introspection_test_helper'
|
2
|
+
|
3
|
+
describe GObjectIntrospection::IStructInfo do
|
4
|
+
let(:object_info) { get_introspection_data('GObject', 'Closure') }
|
5
|
+
|
6
|
+
describe '#find_method' do
|
7
|
+
it 'finds a method by name string' do
|
8
|
+
object_info.find_method('new_simple').wont_be_nil
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'finds a method by name symbol' do
|
12
|
+
object_info.find_method(:new_simple).wont_be_nil
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe '#type_name' do
|
17
|
+
it 'returns the correct name' do
|
18
|
+
object_info.type_name.must_equal 'GClosure'
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'introspection_test_helper'
|
2
|
+
|
3
|
+
describe GObjectIntrospection::IUnionInfo do
|
4
|
+
let(:object_info) { get_introspection_data('GLib', 'Mutex') }
|
5
|
+
|
6
|
+
describe '#find_method' do
|
7
|
+
it 'finds a method by name string' do
|
8
|
+
object_info.find_method('clear').wont_be_nil
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'finds a method by name symbol' do
|
12
|
+
object_info.find_method(:clear).wont_be_nil
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -92,8 +92,7 @@ describe GirFFI::ClassBase do
|
|
92
92
|
'correct-result'
|
93
93
|
end
|
94
94
|
|
95
|
-
def
|
96
|
-
allocate
|
95
|
+
def initialize
|
97
96
|
end
|
98
97
|
end
|
99
98
|
klass.const_set :GIR_FFI_BUILDER, builder
|
@@ -101,6 +100,19 @@ describe GirFFI::ClassBase do
|
|
101
100
|
result = klass.setup_and_call :foo, []
|
102
101
|
result.must_equal 'correct-result'
|
103
102
|
end
|
103
|
+
|
104
|
+
it 'raises a sensible error if the method is not found' do
|
105
|
+
expect(builder = Object.new).to receive(:setup_method).with('foo').and_return nil
|
106
|
+
klass = Class.new GirFFI::ClassBase do
|
107
|
+
def initialize
|
108
|
+
end
|
109
|
+
end
|
110
|
+
klass.const_set :GIR_FFI_BUILDER, builder
|
111
|
+
|
112
|
+
proc { klass.setup_and_call :foo, [] }.
|
113
|
+
must_raise(NoMethodError).message.
|
114
|
+
must_match(/^undefined method `foo' for/)
|
115
|
+
end
|
104
116
|
end
|
105
117
|
|
106
118
|
describe '#setup_and_call' do
|
@@ -114,8 +126,7 @@ describe GirFFI::ClassBase do
|
|
114
126
|
def foo
|
115
127
|
end
|
116
128
|
|
117
|
-
def
|
118
|
-
allocate
|
129
|
+
def initialize
|
119
130
|
end
|
120
131
|
end
|
121
132
|
sub_klass.const_set :GIR_FFI_BUILDER, sub_builder
|
@@ -132,8 +143,7 @@ describe GirFFI::ClassBase do
|
|
132
143
|
'correct-result'
|
133
144
|
end
|
134
145
|
|
135
|
-
def
|
136
|
-
allocate
|
146
|
+
def initialize
|
137
147
|
end
|
138
148
|
end
|
139
149
|
klass.const_set :GIR_FFI_BUILDER, builder
|
@@ -143,5 +153,20 @@ describe GirFFI::ClassBase do
|
|
143
153
|
result = obj.setup_and_call :foo, []
|
144
154
|
result.must_equal 'correct-result'
|
145
155
|
end
|
156
|
+
|
157
|
+
it 'raises a sensible error if the method is not found' do
|
158
|
+
expect(builder = Object.new).to receive(:setup_instance_method).with('foo').and_return nil
|
159
|
+
klass = Class.new GirFFI::ClassBase do
|
160
|
+
def initialize
|
161
|
+
end
|
162
|
+
end
|
163
|
+
klass.const_set :GIR_FFI_BUILDER, builder
|
164
|
+
|
165
|
+
obj = klass.new
|
166
|
+
|
167
|
+
proc { obj.setup_and_call :foo, [] }.
|
168
|
+
must_raise(NoMethodError).message.
|
169
|
+
must_match(/^undefined method `foo' for/)
|
170
|
+
end
|
146
171
|
end
|
147
172
|
end
|
@@ -57,11 +57,30 @@ describe GirFFI::InOutPointer do
|
|
57
57
|
|
58
58
|
describe '.for' do
|
59
59
|
it 'handles :gboolean' do
|
60
|
-
GirFFI::InOutPointer.for :gboolean
|
60
|
+
result = GirFFI::InOutPointer.for :gboolean
|
61
|
+
result.to_value.must_equal false
|
61
62
|
end
|
62
63
|
|
63
64
|
it 'handles :utf8' do
|
64
|
-
GirFFI::InOutPointer.for :utf8
|
65
|
+
result = GirFFI::InOutPointer.for :utf8
|
66
|
+
result.to_value.must_be :null?
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'handles GObject::Value' do
|
70
|
+
result = GirFFI::InOutPointer.for GObject::Value
|
71
|
+
type_size = FFI.type_size GObject::Value
|
72
|
+
expected = "\x00" * type_size
|
73
|
+
result.to_value.read_bytes(type_size).must_equal expected
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
describe '#set_value' do
|
78
|
+
it 'works setting the value to nil for GObject::Value' do
|
79
|
+
pointer = GirFFI::InOutPointer.from GObject::Value, GObject::Value.from(3)
|
80
|
+
pointer.set_value nil
|
81
|
+
type_size = FFI.type_size GObject::Value
|
82
|
+
expected = "\x00" * type_size
|
83
|
+
pointer.to_value.read_bytes(type_size).must_equal expected
|
65
84
|
end
|
66
85
|
end
|
67
86
|
|
@@ -76,4 +76,13 @@ describe GirFFI::UserDefinedTypeInfo do
|
|
76
76
|
info.g_name.must_equal 'bar'
|
77
77
|
end
|
78
78
|
end
|
79
|
+
|
80
|
+
describe '#find_method' do
|
81
|
+
let(:klass) { Object.new }
|
82
|
+
let(:info) { GirFFI::UserDefinedTypeInfo.new klass }
|
83
|
+
|
84
|
+
it 'finds no methods' do
|
85
|
+
info.find_method('foo').must_equal nil
|
86
|
+
end
|
87
|
+
end
|
79
88
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gir_ffi
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.8.
|
4
|
+
version: 0.8.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matijs van Zuijlen
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-10-
|
11
|
+
date: 2015-10-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ffi
|
@@ -189,6 +189,7 @@ files:
|
|
189
189
|
- lib/gir_ffi/builders/method_template.rb
|
190
190
|
- lib/gir_ffi/builders/module_builder.rb
|
191
191
|
- lib/gir_ffi/builders/null_argument_builder.rb
|
192
|
+
- lib/gir_ffi/builders/null_class_builder.rb
|
192
193
|
- lib/gir_ffi/builders/null_convertor.rb
|
193
194
|
- lib/gir_ffi/builders/null_return_value_builder.rb
|
194
195
|
- lib/gir_ffi/builders/object_builder.rb
|
@@ -278,10 +279,13 @@ files:
|
|
278
279
|
- test/ffi-gobject_introspection/i_constant_info_test.rb
|
279
280
|
- test/ffi-gobject_introspection/i_enum_info_test.rb
|
280
281
|
- test/ffi-gobject_introspection/i_function_info_test.rb
|
282
|
+
- test/ffi-gobject_introspection/i_interface_info_test.rb
|
281
283
|
- test/ffi-gobject_introspection/i_object_info_test.rb
|
282
284
|
- test/ffi-gobject_introspection/i_registered_type_info_test.rb
|
283
285
|
- test/ffi-gobject_introspection/i_repository_test.rb
|
286
|
+
- test/ffi-gobject_introspection/i_struct_info_test.rb
|
284
287
|
- test/ffi-gobject_introspection/i_type_info_test.rb
|
288
|
+
- test/ffi-gobject_introspection/i_union_info_test.rb
|
285
289
|
- test/ffi-gobject_introspection/lib_test.rb
|
286
290
|
- test/ffi-gobject_test.rb
|
287
291
|
- test/gir_ffi-base/glib/boolean_test.rb
|