gir_ffi 0.8.6 → 0.9.0
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 +18 -0
- data/README.md +3 -4
- data/lib/ffi-glib.rb +1 -0
- data/lib/ffi-glib/container_class_methods.rb +12 -0
- data/lib/ffi-glib/destroy_notify.rb +15 -0
- data/lib/ffi-glib/main_loop.rb +23 -4
- data/lib/ffi-gobject.rb +4 -2
- data/lib/ffi-gobject/object.rb +31 -16
- data/lib/ffi-gobject/object_class.rb +4 -0
- data/lib/ffi-gobject/value.rb +3 -3
- data/lib/ffi-gobject_introspection/i_flags_info.rb +0 -1
- data/lib/gir_ffi-base/gobject/lib.rb +10 -0
- data/lib/gir_ffi/arg_helper.rb +1 -22
- data/lib/gir_ffi/boxed_base.rb +1 -0
- data/lib/gir_ffi/builder.rb +7 -1
- data/lib/gir_ffi/builders/argument_builder.rb +21 -9
- data/lib/gir_ffi/builders/argument_builder_collection.rb +28 -9
- data/lib/gir_ffi/builders/base_argument_builder.rb +36 -12
- data/lib/gir_ffi/builders/base_method_builder.rb +1 -1
- data/lib/gir_ffi/builders/callback_argument_builder.rb +4 -0
- data/lib/gir_ffi/builders/closure_to_pointer_convertor.rb +3 -2
- data/lib/gir_ffi/builders/constructor_builder.rb +1 -1
- data/lib/gir_ffi/builders/enum_builder.rb +4 -4
- data/lib/gir_ffi/builders/error_argument_builder.rb +4 -0
- data/lib/gir_ffi/builders/field_builder.rb +23 -9
- data/lib/gir_ffi/builders/flags_builder.rb +28 -0
- data/lib/gir_ffi/builders/full_c_to_ruby_convertor.rb +18 -0
- data/lib/gir_ffi/builders/module_builder.rb +1 -0
- data/lib/gir_ffi/builders/null_argument_builder.rb +9 -1
- data/lib/gir_ffi/builders/object_builder.rb +7 -4
- data/lib/gir_ffi/builders/property_builder.rb +2 -2
- data/lib/gir_ffi/builders/return_value_builder.rb +4 -4
- data/lib/gir_ffi/builders/struct_builder.rb +10 -2
- data/lib/gir_ffi/builders/type_builder.rb +12 -9
- data/lib/gir_ffi/builders/unintrospectable_boxed_builder.rb +26 -0
- data/lib/gir_ffi/builders/user_defined_builder.rb +2 -2
- data/lib/gir_ffi/builders/with_layout.rb +1 -1
- data/lib/gir_ffi/callback_base.rb +13 -5
- data/lib/gir_ffi/core.rb +1 -0
- data/lib/gir_ffi/error_argument_info.rb +4 -0
- data/lib/gir_ffi/flags_base.rb +63 -0
- data/lib/gir_ffi/in_pointer.rb +1 -3
- data/lib/gir_ffi/info_ext/i_type_info.rb +6 -0
- data/lib/gir_ffi/object_base.rb +9 -1
- data/lib/gir_ffi/object_store.rb +26 -0
- data/lib/gir_ffi/unintrospectable_boxed_info.rb +31 -0
- data/lib/gir_ffi/unintrospectable_type_info.rb +5 -0
- data/lib/gir_ffi/user_defined_type_info.rb +19 -0
- data/lib/gir_ffi/version.rb +1 -1
- data/test/ffi-glib/destroy_notify_test.rb +13 -0
- data/test/ffi-glib/main_loop_test.rb +3 -3
- data/test/ffi-gobject/object_class_test.rb +8 -0
- data/test/ffi-gobject/object_test.rb +23 -5
- data/test/ffi-gobject/value_test.rb +19 -5
- data/test/ffi-gobject_test.rb +2 -2
- data/test/gir_ffi/builders/argument_builder_test.rb +12 -2
- data/test/gir_ffi/builders/constructor_builder_test.rb +4 -4
- data/test/gir_ffi/builders/function_builder_test.rb +46 -3
- data/test/gir_ffi/builders/object_builder_test.rb +25 -0
- data/test/gir_ffi/builders/property_builder_test.rb +4 -4
- data/test/gir_ffi/builders/struct_builder_test.rb +15 -13
- data/test/gir_ffi/builders/unintrospectable_boxed_builder_test.rb +33 -0
- data/test/gir_ffi/builders/unintrospectable_builder_test.rb +6 -0
- data/test/gir_ffi/builders/user_defined_builder_test.rb +7 -1
- data/test/gir_ffi/callback_base_test.rb +12 -2
- data/test/gir_ffi/object_base_test.rb +14 -0
- data/test/integration/callback_exceptions_test.rb +61 -0
- data/test/integration/generated_gimarshallingtests_test.rb +70 -70
- data/test/integration/generated_gio_test.rb +1 -1
- data/test/integration/generated_gobject_test.rb +1 -1
- data/test/integration/generated_gtop_test.rb +5 -1
- data/test/integration/generated_regress_test.rb +83 -102
- data/test/integration/generated_warnlib_test.rb +2 -2
- metadata +42 -4
@@ -1,10 +1,12 @@
|
|
1
1
|
require 'gir_ffi/builders/callback_builder'
|
2
2
|
require 'gir_ffi/builders/constant_builder'
|
3
3
|
require 'gir_ffi/builders/enum_builder'
|
4
|
+
require 'gir_ffi/builders/flags_builder'
|
4
5
|
require 'gir_ffi/builders/interface_builder'
|
5
6
|
require 'gir_ffi/builders/object_builder'
|
6
7
|
require 'gir_ffi/builders/struct_builder'
|
7
8
|
require 'gir_ffi/builders/signal_closure_builder'
|
9
|
+
require 'gir_ffi/builders/unintrospectable_boxed_builder'
|
8
10
|
require 'gir_ffi/builders/unintrospectable_builder'
|
9
11
|
require 'gir_ffi/builders/union_builder'
|
10
12
|
require 'gir_ffi/builders/vfunc_builder'
|
@@ -17,15 +19,16 @@ module GirFFI
|
|
17
19
|
CACHE = {}
|
18
20
|
|
19
21
|
TYPE_MAP = {
|
20
|
-
callback:
|
21
|
-
constant:
|
22
|
-
enum:
|
23
|
-
flags:
|
24
|
-
interface:
|
25
|
-
object:
|
26
|
-
struct:
|
27
|
-
union:
|
28
|
-
|
22
|
+
callback: CallbackBuilder,
|
23
|
+
constant: ConstantBuilder,
|
24
|
+
enum: EnumBuilder,
|
25
|
+
flags: FlagsBuilder,
|
26
|
+
interface: InterfaceBuilder,
|
27
|
+
object: ObjectBuilder,
|
28
|
+
struct: StructBuilder,
|
29
|
+
union: UnionBuilder,
|
30
|
+
unintrospectable_boxed: UnintrospectableBoxedBuilder,
|
31
|
+
unintrospectable: UnintrospectableBuilder
|
29
32
|
}
|
30
33
|
|
31
34
|
def self.build(info)
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'gir_ffi/builders/boxed_builder'
|
2
|
+
|
3
|
+
module GirFFI
|
4
|
+
module Builders
|
5
|
+
# Implements the creation of a class representing a boxed type for
|
6
|
+
# which no data is found in the GIR.
|
7
|
+
class UnintrospectableBoxedBuilder < BoxedBuilder
|
8
|
+
def klass
|
9
|
+
@klass ||= TypeBuilder::CACHE[target_gtype] ||= Class.new(superclass)
|
10
|
+
end
|
11
|
+
|
12
|
+
def setup_class
|
13
|
+
setup_layout
|
14
|
+
setup_constants
|
15
|
+
end
|
16
|
+
|
17
|
+
def superclass
|
18
|
+
BoxedBase
|
19
|
+
end
|
20
|
+
|
21
|
+
def layout_superclass
|
22
|
+
FFI::Struct
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -35,11 +35,11 @@ module GirFFI
|
|
35
35
|
end
|
36
36
|
|
37
37
|
def parent_info
|
38
|
-
@
|
38
|
+
@info.parent
|
39
39
|
end
|
40
40
|
|
41
41
|
def parent_gtype
|
42
|
-
@parent_gtype
|
42
|
+
@info.parent_gtype
|
43
43
|
end
|
44
44
|
|
45
45
|
def interface_gtypes
|
@@ -4,7 +4,7 @@ module GirFFI
|
|
4
4
|
module Builders
|
5
5
|
# Implements the creation of classes representing types with layout,
|
6
6
|
# i.e., :union, :struct, :object.
|
7
|
-
#
|
7
|
+
# NOTE: This module depends on methods in RegisteredTypeBuilder.
|
8
8
|
module WithLayout
|
9
9
|
def layout_specification
|
10
10
|
spec = base_layout_specification
|
@@ -31,25 +31,33 @@ module GirFFI
|
|
31
31
|
from_native ptr, nil
|
32
32
|
end
|
33
33
|
|
34
|
-
CALLBACKS =
|
34
|
+
CALLBACKS = {}
|
35
35
|
|
36
36
|
def self.store_callback(prc)
|
37
|
-
CALLBACKS
|
37
|
+
CALLBACKS[prc.object_id] = prc
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.drop_callback(key)
|
41
|
+
CALLBACKS.delete key
|
38
42
|
end
|
39
43
|
|
40
44
|
# Create Callback from a Proc. Makes sure arguments are properly wrapped,
|
41
45
|
# and the callback is stored to prevent garbage collection.
|
42
46
|
def self.from(prc)
|
43
|
-
|
47
|
+
wrap_proc(prc).tap do |cb|
|
44
48
|
store_callback cb
|
45
49
|
end
|
46
50
|
end
|
47
51
|
|
48
|
-
def self.
|
52
|
+
def self.wrap_proc(prc)
|
49
53
|
return unless prc
|
50
54
|
|
51
55
|
new do |*args|
|
52
|
-
|
56
|
+
begin
|
57
|
+
call_with_argument_mapping(prc, *args)
|
58
|
+
rescue => e
|
59
|
+
GLib::MainLoop.handle_exception e
|
60
|
+
end
|
53
61
|
end
|
54
62
|
end
|
55
63
|
|
data/lib/gir_ffi/core.rb
CHANGED
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'gir_ffi/registered_type_base'
|
2
|
+
|
3
|
+
module GirFFI
|
4
|
+
# Base module for flags.
|
5
|
+
module FlagsBase
|
6
|
+
include FFI::DataConverter
|
7
|
+
include RegisteredTypeBase
|
8
|
+
|
9
|
+
def native_type
|
10
|
+
self::BitMask.native_type
|
11
|
+
end
|
12
|
+
|
13
|
+
def to_native(value, context)
|
14
|
+
case value
|
15
|
+
when Symbol
|
16
|
+
value = { value => true }
|
17
|
+
end
|
18
|
+
self::BitMask.to_native(value, context)
|
19
|
+
end
|
20
|
+
|
21
|
+
def from_native(*args)
|
22
|
+
self::BitMask.from_native(*args).select { |_k, v| v }
|
23
|
+
end
|
24
|
+
|
25
|
+
def [](arg)
|
26
|
+
self::BitMask[arg]
|
27
|
+
end
|
28
|
+
|
29
|
+
def wrap(arg)
|
30
|
+
self[arg]
|
31
|
+
end
|
32
|
+
|
33
|
+
def from(arg)
|
34
|
+
self[arg]
|
35
|
+
end
|
36
|
+
|
37
|
+
def copy_value_to_pointer(value, pointer)
|
38
|
+
pointer.put_int32 0, to_native(value, nil)
|
39
|
+
end
|
40
|
+
|
41
|
+
def get_value_from_pointer(pointer, offset)
|
42
|
+
from_native pointer.get_int32(offset), nil
|
43
|
+
end
|
44
|
+
|
45
|
+
def setup_and_call(method, arguments, &block)
|
46
|
+
result = setup_method method.to_s
|
47
|
+
|
48
|
+
unless result
|
49
|
+
raise "Unable to set up method #{method} in #{self}"
|
50
|
+
end
|
51
|
+
|
52
|
+
send method, *arguments, &block
|
53
|
+
end
|
54
|
+
|
55
|
+
def to_ffi_type
|
56
|
+
self
|
57
|
+
end
|
58
|
+
|
59
|
+
def setup_method(name)
|
60
|
+
gir_ffi_builder.setup_method name
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
data/lib/gir_ffi/in_pointer.rb
CHANGED
data/lib/gir_ffi/object_base.rb
CHANGED
@@ -5,6 +5,10 @@ module GirFFI
|
|
5
5
|
class ObjectBase < ClassBase
|
6
6
|
extend FFI::DataConverter
|
7
7
|
|
8
|
+
def object_class
|
9
|
+
self.class.object_class
|
10
|
+
end
|
11
|
+
|
8
12
|
def self.native_type
|
9
13
|
FFI::Type::POINTER
|
10
14
|
end
|
@@ -54,7 +58,11 @@ module GirFFI
|
|
54
58
|
end
|
55
59
|
|
56
60
|
def self.object_class
|
57
|
-
|
61
|
+
@object_class ||=
|
62
|
+
begin
|
63
|
+
ptr = GObject.type_class_ref(gtype).to_ptr
|
64
|
+
gir_ffi_builder.object_class_struct.wrap ptr
|
65
|
+
end
|
58
66
|
end
|
59
67
|
end
|
60
68
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module GirFFI
|
2
|
+
# Helper class for storing objects for later retrieval. Used to store user
|
3
|
+
# data arguments.
|
4
|
+
class ObjectStore
|
5
|
+
def initialize
|
6
|
+
@store = {}
|
7
|
+
end
|
8
|
+
|
9
|
+
def store(obj)
|
10
|
+
# FIXME: Don't use object_id!
|
11
|
+
key = obj.object_id
|
12
|
+
@store[key] = obj
|
13
|
+
FFI::Pointer.new(key)
|
14
|
+
end
|
15
|
+
|
16
|
+
def fetch(ptr)
|
17
|
+
return if ptr.null?
|
18
|
+
key = ptr.address
|
19
|
+
if @store.key? key
|
20
|
+
@store[key]
|
21
|
+
else
|
22
|
+
ptr
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'gir_ffi/info_ext/full_type_name'
|
2
|
+
|
3
|
+
module GirFFI
|
4
|
+
# Represents a boxed type not found in the GIR, conforming, as needed, to the
|
5
|
+
# interface of GObjectIntrospection::IUnionInfo and GObjectIntrospection::IStructInfo.
|
6
|
+
class UnintrospectableBoxedInfo
|
7
|
+
attr_reader :g_type
|
8
|
+
|
9
|
+
def initialize(gtype)
|
10
|
+
@g_type = gtype
|
11
|
+
end
|
12
|
+
|
13
|
+
def info_type
|
14
|
+
:unintrospectable_boxed
|
15
|
+
end
|
16
|
+
|
17
|
+
def safe_name
|
18
|
+
GObject.type_name g_type
|
19
|
+
end
|
20
|
+
|
21
|
+
DEFAULT_BOXED_NAMESPACE = 'GLib'
|
22
|
+
|
23
|
+
def namespace
|
24
|
+
DEFAULT_BOXED_NAMESPACE
|
25
|
+
end
|
26
|
+
|
27
|
+
def fields
|
28
|
+
[]
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -35,10 +35,29 @@ module GirFFI
|
|
35
35
|
nil
|
36
36
|
end
|
37
37
|
|
38
|
+
def parent_gtype
|
39
|
+
@parent_gtype ||= GType.new(@klass.superclass.gtype)
|
40
|
+
end
|
41
|
+
|
42
|
+
def parent
|
43
|
+
@parent ||= gir.find_by_gtype(parent_gtype.to_i)
|
44
|
+
end
|
45
|
+
|
46
|
+
# TODO: Create custom class that includes the interfaces instead
|
47
|
+
def class_struct
|
48
|
+
parent.class_struct
|
49
|
+
end
|
50
|
+
|
38
51
|
attr_writer :g_name
|
39
52
|
|
40
53
|
def g_name
|
41
54
|
@g_name ||= @klass.name
|
42
55
|
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
def gir
|
60
|
+
@gir ||= GObjectIntrospection::IRepository.default
|
61
|
+
end
|
43
62
|
end
|
44
63
|
end
|
data/lib/gir_ffi/version.rb
CHANGED
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'gir_ffi_test_helper'
|
2
|
+
|
3
|
+
describe GLib::DestroyNotify do
|
4
|
+
describe '.default' do
|
5
|
+
it 'removes the passed-in key from the callback store' do
|
6
|
+
dummy_proc = 'some-callback'
|
7
|
+
GirFFI::CallbackBase.store_callback dummy_proc
|
8
|
+
user_data = GirFFI::InPointer.from_closure_data dummy_proc.object_id
|
9
|
+
GLib::DestroyNotify.default.call user_data
|
10
|
+
GirFFI::CallbackBase::CALLBACKS[dummy_proc.object_id].must_be_nil
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -6,9 +6,9 @@ describe GLib::MainLoop do
|
|
6
6
|
main_loop = GLib::MainLoop.new nil, false
|
7
7
|
|
8
8
|
a = []
|
9
|
-
GLib.timeout_add
|
10
|
-
|
11
|
-
|
9
|
+
GLib.timeout_add GLib::PRIORITY_DEFAULT, 150 do
|
10
|
+
main_loop.quit
|
11
|
+
end
|
12
12
|
|
13
13
|
slow_thread = Thread.new do
|
14
14
|
sleep 0.001
|
@@ -18,4 +18,12 @@ describe GObject::ObjectClass do
|
|
18
18
|
prop_names.sort.must_equal expected_props.sort
|
19
19
|
end
|
20
20
|
end
|
21
|
+
|
22
|
+
describe '#gtype' do
|
23
|
+
it 'returns the correct GType' do
|
24
|
+
obj = GIMarshallingTests::OverridesObject.new
|
25
|
+
object_class = GObject.object_class_from_instance obj
|
26
|
+
object_class.gtype.must_equal GIMarshallingTests::OverridesObject.gtype
|
27
|
+
end
|
28
|
+
end
|
21
29
|
end
|
@@ -1,11 +1,25 @@
|
|
1
1
|
require 'gir_ffi_test_helper'
|
2
2
|
|
3
3
|
require 'ffi-gobject'
|
4
|
+
GirFFI.setup :GIMarshallingTests
|
4
5
|
|
5
6
|
describe GObject::Object do
|
6
7
|
describe '.new' do
|
7
8
|
it 'is overridden to take only one argument' do
|
8
|
-
GObject::Object.new(
|
9
|
+
GObject::Object.new({}).must_be_instance_of GObject::Object
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'can be used to create objects with properties' do
|
13
|
+
obj = GIMarshallingTests::SubObject.new(int: 13)
|
14
|
+
obj.int.must_equal 13
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'allows omission of the first argument' do
|
18
|
+
GObject::Object.new.must_be_instance_of GObject::Object
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'raises an error for properties that do not exist' do
|
22
|
+
proc { GObject::Object.new(dog: 'bark') }.must_raise ArgumentError
|
9
23
|
end
|
10
24
|
end
|
11
25
|
|
@@ -26,7 +40,7 @@ describe GObject::Object do
|
|
26
40
|
end
|
27
41
|
end
|
28
42
|
|
29
|
-
subject { AccessorTest.new
|
43
|
+
subject { AccessorTest.new }
|
30
44
|
|
31
45
|
it 'reads x by calling get_x' do
|
32
46
|
subject.set_x(1)
|
@@ -40,7 +54,7 @@ describe GObject::Object do
|
|
40
54
|
end
|
41
55
|
|
42
56
|
describe '#signal_connect' do
|
43
|
-
subject { GObject::Object.new
|
57
|
+
subject { GObject::Object.new }
|
44
58
|
|
45
59
|
it 'delegates to GObject' do
|
46
60
|
expect(GObject).to receive(:signal_connect).with(subject, 'some-event', nil)
|
@@ -58,7 +72,7 @@ describe GObject::Object do
|
|
58
72
|
end
|
59
73
|
|
60
74
|
describe '#signal_connect_after' do
|
61
|
-
subject { GObject::Object.new
|
75
|
+
subject { GObject::Object.new }
|
62
76
|
|
63
77
|
it 'delegates to GObject' do
|
64
78
|
expect(GObject).to receive(:signal_connect_after).with(subject, 'some-event', nil)
|
@@ -76,12 +90,16 @@ describe GObject::Object do
|
|
76
90
|
end
|
77
91
|
|
78
92
|
describe 'upon garbage collection' do
|
93
|
+
# FIXME: Test this some other way
|
79
94
|
it 'lowers the reference count' do
|
80
95
|
if defined?(RUBY_ENGINE) && %w(jruby rbx).include?(RUBY_ENGINE)
|
81
96
|
skip 'cannot be reliably tested on JRuby and Rubinius'
|
82
97
|
end
|
98
|
+
if RUBY_VERSION >= '2.3.0'
|
99
|
+
skip 'cannot be reliably tested on CRuby >= 2.3'
|
100
|
+
end
|
83
101
|
|
84
|
-
object = GObject::Object.new
|
102
|
+
object = GObject::Object.new
|
85
103
|
ptr = object.to_ptr
|
86
104
|
ref_count(ptr).must_equal 1
|
87
105
|
|