gir_ffi 0.6.3 → 0.6.4
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 +11 -0
- data/README.md +24 -6
- data/lib/ffi-glib/ptr_array.rb +17 -1
- data/lib/ffi-glib/variant.rb +15 -0
- data/lib/ffi-glib.rb +1 -0
- data/lib/ffi-gobject/object.rb +1 -1
- data/lib/ffi-gobject/ruby_closure.rb +1 -1
- data/lib/ffi-gobject/value.rb +13 -3
- data/lib/ffi-gobject.rb +1 -2
- data/lib/ffi-gobject_introspection/i_enum_info.rb +14 -0
- data/lib/ffi-gobject_introspection/lib.rb +2 -0
- data/lib/gir_ffi/arg_helper.rb +2 -0
- data/lib/gir_ffi/argument_builder.rb +22 -21
- data/lib/gir_ffi/base_argument_builder.rb +2 -1
- data/lib/gir_ffi/builder/module.rb +2 -3
- data/lib/gir_ffi/builder/type/enum.rb +18 -1
- data/lib/gir_ffi/builder/type/object.rb +20 -18
- data/lib/gir_ffi/class_base.rb +0 -1
- data/lib/gir_ffi/enum_base.rb +25 -0
- data/lib/gir_ffi/ffi_ext.rb +1 -0
- data/lib/gir_ffi/function_builder.rb +50 -33
- data/lib/gir_ffi/in_out_pointer.rb +0 -5
- data/lib/gir_ffi/in_pointer.rb +7 -5
- data/lib/gir_ffi/info_ext/i_callable_info.rb +4 -0
- data/lib/gir_ffi/info_ext/i_enum_info.rb +13 -0
- data/lib/gir_ffi/info_ext/i_field_info.rb +1 -1
- data/lib/gir_ffi/info_ext/i_object_info.rb +11 -0
- data/lib/gir_ffi/info_ext/i_registered_type_info.rb +11 -0
- data/lib/gir_ffi/info_ext/i_struct_info.rb +11 -0
- data/lib/gir_ffi/info_ext/i_type_info.rb +10 -19
- data/lib/gir_ffi/info_ext/i_union_info.rb +12 -0
- data/lib/gir_ffi/info_ext/safe_constant_name.rb +0 -2
- data/lib/gir_ffi/info_ext.rb +4 -0
- data/lib/gir_ffi/interface_base.rb +0 -1
- data/lib/gir_ffi/return_value_builder.rb +3 -2
- data/lib/gir_ffi/type_map.rb +3 -0
- data/lib/gir_ffi/version.rb +1 -1
- data/lib/gir_ffi/zero_terminated.rb +36 -3
- data/lib/gir_ffi-base/gir_ffi/library.rb +17 -0
- data/lib/gir_ffi-base/gobject/lib.rb +2 -2
- data/lib/gir_ffi.rb +1 -0
- data/tasks/test.rake +1 -0
- data/test/base_test_helper.rb +22 -2
- data/test/ffi-glib/ruby_closure_test.rb +1 -1
- data/test/ffi-glib/variant_test.rb +10 -0
- data/test/ffi-gobject/value_test.rb +24 -8
- data/test/ffi-gobject_introspection/i_enum_info_test.rb +17 -0
- data/test/gir_ffi/argument_builder_test.rb +66 -24
- data/test/gir_ffi/builder_test.rb +1 -1
- data/test/gir_ffi/function_builder_test.rb +1 -3
- data/test/gir_ffi/in_out_pointer_test.rb +5 -3
- data/test/gir_ffi/in_pointer_test.rb +32 -2
- data/test/gir_ffi/info_ext/i_arg_info_test.rb +2 -2
- data/test/gir_ffi/info_ext/i_callable_info_test.rb +2 -2
- data/test/gir_ffi/info_ext/i_field_info_test.rb +14 -20
- data/test/gir_ffi/info_ext/i_function_info_test.rb +2 -2
- data/test/gir_ffi/info_ext/i_signal_info_test.rb +2 -2
- data/test/gir_ffi/info_ext/i_type_info_test.rb +8 -8
- data/test/gir_ffi/info_ext/safe_constant_name_test.rb +2 -2
- data/test/gir_ffi/info_ext/safe_function_name_test.rb +2 -2
- data/test/gir_ffi/return_value_builder_test.rb +18 -1
- data/test/gir_ffi/zero_terminated_test.rb +10 -0
- data/test/gir_ffi_test_helper.rb +0 -19
- data/test/integration/generated_gimarshallingtests_test.rb +291 -99
- data/test/integration/generated_regress_test.rb +138 -14
- data/test/lib/autogen.sh +6 -2
- metadata +14 -2
data/History.txt
CHANGED
@@ -1,3 +1,14 @@
|
|
1
|
+
== 0.6.4 / 2013-06-30
|
2
|
+
|
3
|
+
* Represent enum types by modules wrapping FFI::Enum
|
4
|
+
* Support functions on enums
|
5
|
+
* Handle zero-terminated arrays of types other than int32
|
6
|
+
* Add override for GLib::Variant#get_string
|
7
|
+
* Handle non-throwing arguments and return values of type GError
|
8
|
+
* Handle arguments and return values of type GPtrArray
|
9
|
+
* Handle caller-allocated arguments of type GArray
|
10
|
+
* Deprecate GObject::Value#ruby_value, replacing it with #get_value
|
11
|
+
|
1
12
|
== 0.6.3 / 2013-06-15
|
2
13
|
|
3
14
|
* Make use of enums as element type for GHashTable and other containers
|
data/README.md
CHANGED
@@ -20,12 +20,18 @@ Ruby bindings for GNOME using the GObject Introspection Repository.
|
|
20
20
|
|
21
21
|
require 'gir_ffi'
|
22
22
|
|
23
|
-
|
23
|
+
# Set up the namespace you wish to use
|
24
|
+
GirFFI.setup :Gio
|
24
25
|
|
25
|
-
|
26
|
+
# Create an object
|
27
|
+
inet_address = Gio::InetAddress.new_from_string "127.0.0.1"
|
26
28
|
|
27
|
-
|
28
|
-
|
29
|
+
# Call some methods on the object
|
30
|
+
inet_address.is_loopback # => true
|
31
|
+
inet_address.is_multicast # => false
|
32
|
+
|
33
|
+
# Call a function in the namespace
|
34
|
+
Gio.dbus_is_name "foo" # => false
|
29
35
|
|
30
36
|
## Install
|
31
37
|
|
@@ -33,8 +39,8 @@ Ruby bindings for GNOME using the GObject Introspection Repository.
|
|
33
39
|
|
34
40
|
## Requirements
|
35
41
|
|
36
|
-
GirFFI should work on MRI 1.8
|
37
|
-
modes
|
42
|
+
GirFFI should work on MRI 1.8, 1.9 and 2.0, JRuby in both 1.8 and 1.9
|
43
|
+
modes, and on Rubinius in both 1.8 and 1.9 modes.
|
38
44
|
|
39
45
|
You will also need gobject-introspection installed with some
|
40
46
|
introspection data.
|
@@ -53,6 +59,18 @@ On Debian and Ubuntu, installing `libgirepository1.0-dev` and
|
|
53
59
|
|
54
60
|
GirFFI has not been tested on Mac OS X or Microsoft Windows. YMMV.
|
55
61
|
|
62
|
+
## Overrides
|
63
|
+
|
64
|
+
Sometimes, the GIR data is incorrect, or not detailed enough, and a
|
65
|
+
reasonable binding cannot be created automatically. For these cases,
|
66
|
+
overrides can be defined. The following gems with overrides
|
67
|
+
already exist:
|
68
|
+
|
69
|
+
* `gir_ffi-gtk`: overrides for Gtk+ 2 and 3.
|
70
|
+
* `gir_ffi-cairo`: overrides for Cairo
|
71
|
+
* `gir_ffi-pango`: overrides for Pango
|
72
|
+
* `gir_ffi-tracker`: overrides for Tracker
|
73
|
+
|
56
74
|
## Hacking and contributing
|
57
75
|
|
58
76
|
If you want to help out, have a look at TODO.rdoc, and check the notes
|
data/lib/ffi-glib/ptr_array.rb
CHANGED
@@ -15,10 +15,22 @@ module GLib
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def self.new type
|
18
|
-
wrap(Lib.g_ptr_array_new)
|
18
|
+
wrap(type, Lib.g_ptr_array_new)
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.wrap type, ptr
|
22
|
+
super(ptr).tap {|it|
|
19
23
|
it.element_type = type}
|
20
24
|
end
|
21
25
|
|
26
|
+
def self.from type, it
|
27
|
+
case it
|
28
|
+
when self then it
|
29
|
+
when FFI::Pointer then wrap type, it
|
30
|
+
else self.new(type).tap {|arr| arr.add_array it}
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
22
34
|
def self.add array, data
|
23
35
|
array.add data
|
24
36
|
end
|
@@ -28,6 +40,10 @@ module GLib
|
|
28
40
|
Lib.g_ptr_array_add self, ptr
|
29
41
|
end
|
30
42
|
|
43
|
+
def add_array ary
|
44
|
+
ary.each {|item| add item}
|
45
|
+
end
|
46
|
+
|
31
47
|
# Re-implementation of the g_ptr_array_index macro
|
32
48
|
def index idx
|
33
49
|
sz = FFI.type_size :pointer
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module GLib
|
2
|
+
load_class :Variant
|
3
|
+
|
4
|
+
# Overrides for GVariant, GLib's variant data type.
|
5
|
+
class Variant
|
6
|
+
setup_instance_method "get_string"
|
7
|
+
|
8
|
+
def get_string_with_override
|
9
|
+
get_string_without_override.first
|
10
|
+
end
|
11
|
+
|
12
|
+
alias get_string_without_override get_string
|
13
|
+
alias get_string get_string_with_override
|
14
|
+
end
|
15
|
+
end
|
data/lib/ffi-glib.rb
CHANGED
data/lib/ffi-gobject/object.rb
CHANGED
@@ -43,7 +43,7 @@ module GObject
|
|
43
43
|
rclosure = wrap(closure.to_ptr)
|
44
44
|
|
45
45
|
args = n_param_values.times.map {|idx|
|
46
|
-
Value.wrap(param_values.to_ptr + idx * Value::Struct.size).
|
46
|
+
Value.wrap(param_values.to_ptr + idx * Value::Struct.size).get_value
|
47
47
|
}
|
48
48
|
|
49
49
|
result = rclosure.invoke_block(*args)
|
data/lib/ffi-gobject/value.rb
CHANGED
@@ -15,6 +15,7 @@ module GObject
|
|
15
15
|
TYPE_TO_SET_METHOD_MAP = {
|
16
16
|
TYPE_BOOLEAN => :set_boolean,
|
17
17
|
TYPE_INT => :set_int,
|
18
|
+
TYPE_INT64 => :set_int64,
|
18
19
|
TYPE_STRING => :set_string,
|
19
20
|
TYPE_FLOAT => :set_float,
|
20
21
|
TYPE_DOUBLE => :set_double,
|
@@ -25,6 +26,10 @@ module GObject
|
|
25
26
|
TYPE_ENUM => :set_enum
|
26
27
|
}
|
27
28
|
|
29
|
+
def value= val
|
30
|
+
set_value val
|
31
|
+
end
|
32
|
+
|
28
33
|
def set_value val
|
29
34
|
send set_method, val
|
30
35
|
self
|
@@ -62,6 +67,7 @@ module GObject
|
|
62
67
|
TYPE_TO_GET_METHOD_MAP = {
|
63
68
|
TYPE_BOOLEAN => :get_boolean,
|
64
69
|
TYPE_INT => :get_int,
|
70
|
+
TYPE_INT64 => :get_int64,
|
65
71
|
TYPE_STRING => :get_string,
|
66
72
|
TYPE_FLOAT => :get_float,
|
67
73
|
TYPE_DOUBLE => :get_double,
|
@@ -70,11 +76,15 @@ module GObject
|
|
70
76
|
TYPE_POINTER => :get_pointer
|
71
77
|
}
|
72
78
|
|
73
|
-
|
74
|
-
def ruby_value
|
79
|
+
def get_value
|
75
80
|
send get_method
|
76
81
|
end
|
77
82
|
|
83
|
+
# @deprecated Compatibility function. Remove in 0.7.0.
|
84
|
+
def ruby_value
|
85
|
+
get_value
|
86
|
+
end
|
87
|
+
|
78
88
|
class << self
|
79
89
|
# TODO: Give more generic name
|
80
90
|
def wrap_ruby_value val
|
@@ -94,7 +104,7 @@ module GObject
|
|
94
104
|
|
95
105
|
def for_g_type g_type
|
96
106
|
return nil if g_type == TYPE_NONE
|
97
|
-
self.new.
|
107
|
+
self.new.init g_type
|
98
108
|
end
|
99
109
|
end
|
100
110
|
|
data/lib/ffi-gobject.rb
CHANGED
@@ -109,8 +109,7 @@ module GObject
|
|
109
109
|
attach_function :g_hash_table_get_type, [], :size_t
|
110
110
|
|
111
111
|
attach_function :g_signal_connect_data,
|
112
|
-
[:pointer, :string, Callback, :pointer, ClosureNotify,
|
113
|
-
ConnectFlags],
|
112
|
+
[:pointer, :string, Callback, :pointer, ClosureNotify, ConnectFlags],
|
114
113
|
:ulong
|
115
114
|
attach_function :g_closure_set_marshal,
|
116
115
|
[:pointer, ClosureMarshal], :void
|
@@ -11,6 +11,20 @@ module GObjectIntrospection
|
|
11
11
|
##
|
12
12
|
build_array_method :values
|
13
13
|
|
14
|
+
def get_n_methods
|
15
|
+
Lib.g_enum_info_get_n_methods @gobj
|
16
|
+
end
|
17
|
+
def get_method(index)
|
18
|
+
IFunctionInfo.wrap(Lib.g_enum_info_get_method @gobj, index)
|
19
|
+
end
|
20
|
+
|
21
|
+
##
|
22
|
+
build_array_method :get_methods
|
23
|
+
|
24
|
+
def find_method name
|
25
|
+
get_methods.find {|m| m.name == name}
|
26
|
+
end
|
27
|
+
|
14
28
|
def storage_type
|
15
29
|
Lib.g_enum_info_get_storage_type @gobj
|
16
30
|
end
|
@@ -178,6 +178,8 @@ module GObjectIntrospection
|
|
178
178
|
attach_function :g_enum_info_get_storage_type, [:pointer], :ITypeTag
|
179
179
|
attach_function :g_enum_info_get_n_values, [:pointer], :int
|
180
180
|
attach_function :g_enum_info_get_value, [:pointer, :int], :pointer
|
181
|
+
attach_function :g_enum_info_get_n_methods, [:pointer], :int
|
182
|
+
attach_function :g_enum_info_get_method, [:pointer, :int], :pointer
|
181
183
|
|
182
184
|
# IObjectInfo
|
183
185
|
attach_function :g_object_info_get_type_name, [:pointer], :string
|
data/lib/gir_ffi/arg_helper.rb
CHANGED
@@ -53,8 +53,6 @@ module GirFFI
|
|
53
53
|
else
|
54
54
|
"#{argument_class_name}.wrap(#{output_conversion_arguments})"
|
55
55
|
end
|
56
|
-
elsif is_fixed_length_array?
|
57
|
-
"GLib::SizedArray.wrap(#{subtype_tag_or_class_name}, #{array_size}, #{callarg}.to_value)"
|
58
56
|
else
|
59
57
|
"#{callarg}.to_value"
|
60
58
|
end
|
@@ -68,10 +66,6 @@ module GirFFI
|
|
68
66
|
specialized_type_tag == :c && type_info.array_fixed_size > -1
|
69
67
|
end
|
70
68
|
|
71
|
-
def is_fixed_length_array?
|
72
|
-
specialized_type_tag == :c
|
73
|
-
end
|
74
|
-
|
75
69
|
def fixed_array_size_check
|
76
70
|
size = type_info.array_fixed_size
|
77
71
|
"GirFFI::ArgHelper.check_fixed_array_size #{size}, #{@name}, \"#{@name}\""
|
@@ -93,7 +87,11 @@ module GirFFI
|
|
93
87
|
def set_function_call_argument
|
94
88
|
value = if @direction == :out
|
95
89
|
if is_caller_allocated_object?
|
96
|
-
|
90
|
+
if specialized_type_tag == :array
|
91
|
+
"#{argument_class_name}.new #{elm_t}"
|
92
|
+
else
|
93
|
+
"#{argument_class_name}.new"
|
94
|
+
end
|
97
95
|
else
|
98
96
|
"GirFFI::InOutPointer.for #{specialized_type_tag.inspect}"
|
99
97
|
end
|
@@ -108,42 +106,45 @@ module GirFFI
|
|
108
106
|
end
|
109
107
|
|
110
108
|
def is_caller_allocated_object?
|
111
|
-
[:
|
109
|
+
[ :struct, :array ].include?(specialized_type_tag) &&
|
112
110
|
@arginfo.caller_allocates?
|
113
111
|
end
|
114
112
|
|
115
113
|
def needs_outgoing_parameter_conversion?
|
116
|
-
[ :array, :enum, :flags, :ghash, :glist, :gslist, :object,
|
117
|
-
:strv, :utf8 ].include?(specialized_type_tag)
|
114
|
+
[ :array, :c, :enum, :error, :flags, :ghash, :glist, :gslist, :object,
|
115
|
+
:ptr_array, :struct, :strv, :utf8 ].include?(specialized_type_tag)
|
118
116
|
end
|
119
117
|
|
120
118
|
def needs_ingoing_parameter_conversion?
|
121
119
|
@direction == :inout ||
|
122
|
-
[ :
|
123
|
-
:
|
120
|
+
[ :array, :c, :callback, :ghash, :glist, :gslist, :object, :ptr_array,
|
121
|
+
:struct, :strv, :utf8, :void, :zero_terminated ].include?(specialized_type_tag)
|
124
122
|
end
|
125
123
|
|
126
124
|
def ingoing_parameter_conversion
|
127
125
|
case specialized_type_tag
|
128
126
|
when :enum, :flags
|
129
127
|
base = "#{argument_class_name}[#{parameter_conversion_arguments}]"
|
130
|
-
|
131
|
-
|
132
|
-
:zero_terminated, :strv, :callback, :utf8, :c
|
128
|
+
when :array, :c, :callback, :ghash, :glist, :gslist, :object, :ptr_array,
|
129
|
+
:struct, :strv, :utf8, :void, :zero_terminated
|
133
130
|
base = "#{argument_class_name}.from(#{parameter_conversion_arguments})"
|
134
|
-
if has_output_value?
|
135
|
-
"GirFFI::InOutPointer.from :pointer, #{base}"
|
136
|
-
else
|
137
|
-
base
|
138
|
-
end
|
139
131
|
else
|
140
132
|
base = "#{parameter_conversion_arguments}"
|
133
|
+
end
|
134
|
+
|
135
|
+
if has_output_value?
|
141
136
|
"GirFFI::InOutPointer.from #{specialized_type_tag.inspect}, #{base}"
|
137
|
+
else
|
138
|
+
base
|
142
139
|
end
|
143
140
|
end
|
144
141
|
|
145
142
|
def output_conversion_arguments
|
146
|
-
|
143
|
+
if specialized_type_tag == :c
|
144
|
+
"#{subtype_tag_or_class_name}, #{array_size}, #{callarg}.to_value"
|
145
|
+
else
|
146
|
+
conversion_arguments "#{callarg}.to_value"
|
147
|
+
end
|
147
148
|
end
|
148
149
|
|
149
150
|
def parameter_conversion_arguments
|
@@ -42,6 +42,7 @@ module GirFFI
|
|
42
42
|
:byte_array => 'GLib::ByteArray',
|
43
43
|
:c => 'GLib::SizedArray',
|
44
44
|
:callback => 'GirFFI::Callback',
|
45
|
+
:error => 'GLib::Error',
|
45
46
|
:ghash => 'GLib::HashTable',
|
46
47
|
:glist => 'GLib::List',
|
47
48
|
:gslist => 'GLib::SList',
|
@@ -118,7 +119,7 @@ module GirFFI
|
|
118
119
|
"#{specialized_type_tag.inspect}, #{name}"
|
119
120
|
when :c
|
120
121
|
"#{subtype_tag_or_class_name}, #{type_info.array_fixed_size}, #{name}"
|
121
|
-
when :
|
122
|
+
when :array, :ghash, :glist, :gslist, :ptr_array, :zero_terminated
|
122
123
|
"#{elm_t}, #{name}"
|
123
124
|
when :callback
|
124
125
|
iface = type_info.interface
|
@@ -80,8 +80,8 @@ module GirFFI
|
|
80
80
|
def setup_lib_for_ffi
|
81
81
|
@lib = get_or_define_module @module, :Lib
|
82
82
|
|
83
|
-
unless (class << @lib; self.include?
|
84
|
-
@lib.extend
|
83
|
+
unless (class << @lib; self.include? GirFFI::Library; end)
|
84
|
+
@lib.extend GirFFI::Library
|
85
85
|
@lib.ffi_lib_flags :global, :lazy
|
86
86
|
libspec = gir.shared_library(@namespace)
|
87
87
|
unless libspec.nil?
|
@@ -123,6 +123,5 @@ module GirFFI
|
|
123
123
|
def get_or_define_module parent, name
|
124
124
|
optionally_define_constant(parent, name) { Module.new }
|
125
125
|
end
|
126
|
-
|
127
126
|
end
|
128
127
|
end
|
@@ -1,4 +1,6 @@
|
|
1
1
|
require 'gir_ffi/builder/type/registered_type'
|
2
|
+
require 'gir_ffi/builder/type/with_methods'
|
3
|
+
require 'gir_ffi/enum_base'
|
2
4
|
|
3
5
|
module GirFFI
|
4
6
|
module Builder
|
@@ -8,6 +10,8 @@ module GirFFI
|
|
8
10
|
# attached to the appropriate namespace module, and will be defined
|
9
11
|
# as an enum for FFI.
|
10
12
|
class Enum < RegisteredType
|
13
|
+
include WithMethods
|
14
|
+
|
11
15
|
private
|
12
16
|
|
13
17
|
def enum_sym
|
@@ -22,11 +26,15 @@ module GirFFI
|
|
22
26
|
end
|
23
27
|
|
24
28
|
def instantiate_class
|
25
|
-
@klass =
|
29
|
+
@klass = get_or_define_module namespace_module, @classname
|
30
|
+
@enum = optionally_define_constant @klass, :Enum do
|
26
31
|
lib.enum(enum_sym, value_spec)
|
27
32
|
end
|
28
33
|
unless already_set_up
|
34
|
+
@klass.extend superclass
|
35
|
+
setup_constants
|
29
36
|
setup_gtype_getter
|
37
|
+
stub_methods
|
30
38
|
setup_inspect
|
31
39
|
end
|
32
40
|
end
|
@@ -42,6 +50,15 @@ module GirFFI
|
|
42
50
|
def already_set_up
|
43
51
|
@klass.respond_to? :get_gtype
|
44
52
|
end
|
53
|
+
|
54
|
+
def superclass
|
55
|
+
@superclass ||= EnumBase
|
56
|
+
end
|
57
|
+
|
58
|
+
# FIXME: Remove duplication with Builder::Module
|
59
|
+
def get_or_define_module parent, name
|
60
|
+
optionally_define_constant(parent, name) { ::Module.new }
|
61
|
+
end
|
45
62
|
end
|
46
63
|
end
|
47
64
|
end
|
@@ -51,7 +51,7 @@ module GirFFI
|
|
51
51
|
setup_interfaces
|
52
52
|
end
|
53
53
|
|
54
|
-
# FIXME: Private method only in subclass
|
54
|
+
# FIXME: Private method only used in subclass
|
55
55
|
def layout_superclass
|
56
56
|
FFI::Struct
|
57
57
|
end
|
@@ -69,16 +69,14 @@ module GirFFI
|
|
69
69
|
end
|
70
70
|
|
71
71
|
def superclass
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
end
|
78
|
-
end
|
79
|
-
@superclass
|
72
|
+
@superclass ||= if parent
|
73
|
+
Builder.build_class parent
|
74
|
+
else
|
75
|
+
ObjectBase
|
76
|
+
end
|
80
77
|
end
|
81
78
|
|
79
|
+
# TODO: Unify with field accessor setup.
|
82
80
|
def setup_property_accessors
|
83
81
|
info.properties.each do |prop|
|
84
82
|
setup_accessors_for_property_info prop
|
@@ -94,20 +92,24 @@ module GirFFI
|
|
94
92
|
end
|
95
93
|
|
96
94
|
# TODO: Guard agains accidental invocation of undefined vfuncs.
|
95
|
+
# TODO: Create object responsible for creating these invokers
|
97
96
|
def setup_vfunc_invokers
|
98
97
|
info.vfuncs.each do |vfinfo|
|
99
|
-
invoker = vfinfo.invoker
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
@klass.class_eval "
|
104
|
-
def #{vfinfo.name} *args, &block
|
105
|
-
#{invoker.name}(*args, &block)
|
106
|
-
end
|
107
|
-
"
|
98
|
+
if (invoker = vfinfo.invoker)
|
99
|
+
define_vfunc_invoker vfinfo.name, invoker.name
|
100
|
+
end
|
108
101
|
end
|
109
102
|
end
|
110
103
|
|
104
|
+
def define_vfunc_invoker vfunc_name, invoker_name
|
105
|
+
return if vfunc_name == invoker_name
|
106
|
+
@klass.class_eval "
|
107
|
+
def #{vfunc_name} *args, &block
|
108
|
+
#{invoker_name}(*args, &block)
|
109
|
+
end
|
110
|
+
"
|
111
|
+
end
|
112
|
+
|
111
113
|
def setup_interfaces
|
112
114
|
interfaces.each do |iface|
|
113
115
|
@klass.class_eval do
|
data/lib/gir_ffi/class_base.rb
CHANGED
@@ -0,0 +1,25 @@
|
|
1
|
+
module GirFFI
|
2
|
+
module EnumBase
|
3
|
+
def [](arg)
|
4
|
+
self::Enum[arg]
|
5
|
+
end
|
6
|
+
|
7
|
+
def setup_and_call method, *arguments, &block
|
8
|
+
result = setup_method method.to_s
|
9
|
+
|
10
|
+
unless result
|
11
|
+
raise RuntimeError, "Unable to set up method #{method} in #{self}"
|
12
|
+
end
|
13
|
+
|
14
|
+
self.send method, *arguments, &block
|
15
|
+
end
|
16
|
+
|
17
|
+
def gir_ffi_builder
|
18
|
+
self.const_get :GIR_FFI_BUILDER
|
19
|
+
end
|
20
|
+
|
21
|
+
def setup_method name
|
22
|
+
gir_ffi_builder.setup_method name
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'gir_ffi/ffi_ext/pointer'
|
@@ -15,81 +15,98 @@ module GirFFI
|
|
15
15
|
|
16
16
|
def generate
|
17
17
|
vargen = GirFFI::VariableNameGenerator.new
|
18
|
-
@
|
19
|
-
@
|
20
|
-
|
18
|
+
@argument_builders = @info.args.map {|arg| ArgumentBuilder.new vargen, arg }
|
19
|
+
@return_value_builder = ReturnValueBuilder.new(vargen, @info.return_type,
|
20
|
+
@info.constructor?)
|
21
21
|
|
22
|
-
|
22
|
+
link_array_length_arguments
|
23
|
+
setup_error_argument vargen
|
24
|
+
return filled_out_template
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def link_array_length_arguments
|
30
|
+
alldata = @argument_builders.dup << @return_value_builder
|
23
31
|
|
24
32
|
alldata.each {|data|
|
25
33
|
idx = data.type_info.array_length
|
26
34
|
if idx > -1
|
27
|
-
|
28
|
-
|
35
|
+
other_data = @argument_builders[idx]
|
36
|
+
data.length_arg = other_data
|
37
|
+
other_data.array_arg = data
|
29
38
|
end
|
30
39
|
}
|
31
|
-
|
32
|
-
setup_error_argument vargen
|
33
|
-
return filled_out_template
|
34
40
|
end
|
35
41
|
|
36
|
-
private
|
37
|
-
|
38
42
|
def setup_error_argument vargen
|
39
43
|
klass = @info.throws? ? ErrorArgumentBuilder : NullArgumentBuilder
|
40
44
|
@errarg = klass.new vargen, nil, nil, :error
|
41
45
|
end
|
42
46
|
|
43
47
|
def filled_out_template
|
44
|
-
lines = pre
|
45
|
-
lines << "#{capture}#{@libmodule}.#{@info.symbol} #{callargs.join(', ')}"
|
46
|
-
lines << post
|
47
|
-
|
48
48
|
meta = @info.method? ? '' : "self."
|
49
49
|
|
50
|
-
code = "def #{meta}#{@info.safe_name} #{
|
51
|
-
code <<
|
50
|
+
code = "def #{meta}#{@info.safe_name} #{method_arguments.join(', ')}\n"
|
51
|
+
code << method_body
|
52
52
|
code << "\nend\n"
|
53
53
|
end
|
54
54
|
|
55
|
-
def
|
56
|
-
|
55
|
+
def method_body
|
56
|
+
lines = preparation << function_call << post_processing << cleanup
|
57
|
+
lines << "return #{return_values.join(', ')}" if has_return_values?
|
58
|
+
lines.flatten.join("\n").indent
|
57
59
|
end
|
58
60
|
|
59
|
-
def
|
60
|
-
|
61
|
+
def function_call
|
62
|
+
"#{capture}#{@libmodule}.#{@info.symbol} #{function_call_arguments.join(', ')}"
|
63
|
+
end
|
64
|
+
|
65
|
+
def method_arguments
|
66
|
+
@argument_builders.map(&:inarg).compact
|
67
|
+
end
|
68
|
+
|
69
|
+
def function_call_arguments
|
70
|
+
ca = @argument_builders.map(&:callarg)
|
61
71
|
ca << @errarg.callarg
|
62
72
|
ca.unshift "self" if @info.method?
|
63
73
|
ca.compact
|
64
74
|
end
|
65
75
|
|
66
|
-
def
|
67
|
-
pr = @
|
76
|
+
def preparation
|
77
|
+
pr = @argument_builders.map(&:pre)
|
68
78
|
pr << @errarg.pre
|
69
79
|
pr.flatten
|
70
80
|
end
|
71
81
|
|
72
82
|
def capture
|
73
|
-
if (cv = @
|
83
|
+
if (cv = @return_value_builder.cvar)
|
74
84
|
"#{cv} = "
|
75
85
|
else
|
76
86
|
""
|
77
87
|
end
|
78
88
|
end
|
79
89
|
|
80
|
-
def
|
81
|
-
|
90
|
+
def post_processing
|
91
|
+
# FIXME: Sorting knows too much about internals of ArgumentBuilder.
|
92
|
+
args = @argument_builders.sort_by {|arg| arg.type_info.array_length}
|
93
|
+
args << @return_value_builder
|
94
|
+
args.unshift @errarg
|
82
95
|
|
83
|
-
|
84
|
-
|
85
|
-
po.unshift @errarg.post
|
96
|
+
args.map {|arg| arg.post}
|
97
|
+
end
|
86
98
|
|
87
|
-
|
99
|
+
def cleanup
|
100
|
+
@argument_builders.map {|item| item.cleanup}
|
101
|
+
end
|
88
102
|
|
89
|
-
|
90
|
-
|
103
|
+
def return_values
|
104
|
+
@return_values ||= ([@return_value_builder.retval] +
|
105
|
+
@argument_builders.map(&:retval)).compact
|
106
|
+
end
|
91
107
|
|
92
|
-
|
108
|
+
def has_return_values?
|
109
|
+
!return_values.empty?
|
93
110
|
end
|
94
111
|
end
|
95
112
|
end
|