Module: Qt::ObjectWrapper
- Defined in:
- lib/qt/object_wrapper.rb
Overview
Wrap native QObject-derived pointers into generated Ruby wrapper instances.
Defined Under Namespace
Modules: ConstructorCacheHook
Class Method Summary
collapse
Class Method Details
.cache_wrapper(wrapper) ⇒ Object
97
98
99
100
101
102
|
# File 'lib/qt/object_wrapper.rb', line 97
def cache_wrapper(wrapper)
pointer = wrapper.handle
wrapper_cache[pointer.address] = wrapper
ensure_destroy_hook(wrapper, pointer)
wrapper
end
|
.cached_wrapper_for(pointer) ⇒ Object
80
81
82
|
# File 'lib/qt/object_wrapper.rb', line 80
def cached_wrapper_for(pointer)
wrapper_cache[pointer.address]
end
|
.candidate_wrapper_classes(expected_qt_class) ⇒ Object
38
39
40
41
42
43
44
45
46
47
|
# File 'lib/qt/object_wrapper.rb', line 38
def candidate_wrapper_classes(expected_qt_class)
normalized_qt_class = normalize_expected_qt_class(expected_qt_class)
@candidate_wrapper_classes ||= {}
@candidate_wrapper_classes[normalized_qt_class] ||= begin
base = fallback_wrapper_class(normalized_qt_class)
wrappers = qobject_wrapper_classes
wrappers = wrappers.select { |klass| klass <= base } if base
wrappers.sort_by { |klass| -inheritance_depth(klass) }
end
end
|
.destroy_hook_addresses ⇒ Object
131
132
133
|
# File 'lib/qt/object_wrapper.rb', line 131
def destroy_hook_addresses
@destroy_hook_addresses ||= {}
end
|
.ensure_destroy_hook(wrapper, pointer) ⇒ Object
135
136
137
138
139
140
141
142
143
144
145
146
147
148
|
# File 'lib/qt/object_wrapper.rb', line 135
def ensure_destroy_hook(wrapper, pointer)
address = pointer.address
return if destroy_hook_addresses[address]
destroy_hook_addresses[address] = true
Qt::EventRuntime.on_internal_signal(pointer, 'destroyed()') do |_payload|
destroy_hook_addresses.delete(address)
Qt::EventRuntime.clear_signal_registrations_for_address(address)
invalidate_cached_wrapper(address, wrapper)
end
rescue StandardError
destroy_hook_addresses.delete(address)
raise
end
|
.fallback_wrapper_class(expected_qt_class) ⇒ Object
60
61
62
63
64
65
66
67
68
69
70
71
72
|
# File 'lib/qt/object_wrapper.rb', line 60
def fallback_wrapper_class(expected_qt_class)
normalized_qt_class = normalize_expected_qt_class(expected_qt_class)
return nil unless normalized_qt_class
return nil unless Qt.const_defined?(normalized_qt_class, false)
klass = Qt.const_get(normalized_qt_class, false)
return nil unless klass.is_a?(Class)
return nil unless klass.const_defined?(:QT_CLASS, false)
klass
rescue NameError
nil
end
|
.inheritance_depth(klass) ⇒ Object
150
151
152
153
154
155
156
157
158
|
# File 'lib/qt/object_wrapper.rb', line 150
def inheritance_depth(klass)
depth = 0
current = klass
while current.is_a?(Class)
depth += 1
current = current.superclass
end
depth
end
|
.install_constructor_cache_hooks! ⇒ Object
118
119
120
121
122
123
124
125
|
# File 'lib/qt/object_wrapper.rb', line 118
def install_constructor_cache_hooks!
qobject_wrapper_classes.each do |klass|
next if klass.instance_variable_defined?(:@__qt_object_wrapper_constructor_hook_installed)
klass.prepend(ConstructorCacheHook)
klass.instance_variable_set(:@__qt_object_wrapper_constructor_hook_installed, true)
end
end
|
.instantiate_wrapper(klass, pointer) ⇒ Object
74
75
76
77
78
|
# File 'lib/qt/object_wrapper.rb', line 74
def instantiate_wrapper(klass, pointer)
wrapped = klass.allocate
wrapped.instance_variable_set(:@handle, pointer)
wrapped
end
|
.invalidate_cached_wrapper(pointer_or_address, expected_wrapper = nil) ⇒ Object
104
105
106
107
108
109
110
111
|
# File 'lib/qt/object_wrapper.rb', line 104
def invalidate_cached_wrapper(pointer_or_address, expected_wrapper = nil)
address = pointer_or_address.is_a?(Integer) ? pointer_or_address : pointer_or_address.address
cached = wrapper_cache[address]
return unless cached
return if expected_wrapper && !cached.equal?(expected_wrapper)
wrapper_cache.delete(address)
end
|
.normalize_expected_qt_class(expected_qt_class) ⇒ Object
164
165
166
167
168
169
170
171
172
173
174
|
# File 'lib/qt/object_wrapper.rb', line 164
def normalize_expected_qt_class(expected_qt_class)
return nil if expected_qt_class.nil?
value = expected_qt_class.to_s.strip
return nil if value.empty?
value = value.delete_prefix('Qt::')
return nil unless value.match?(/\A[A-Z]\w*\z/)
value
end
|
.null_pointer?(pointer) ⇒ Boolean
28
29
30
|
# File 'lib/qt/object_wrapper.rb', line 28
def null_pointer?(pointer)
pointer.nil? || (pointer.respond_to?(:null?) && pointer.null?)
end
|
.qobject_wrapper?(klass) ⇒ Boolean
160
161
162
|
# File 'lib/qt/object_wrapper.rb', line 160
def qobject_wrapper?(klass)
klass.is_a?(Class) && klass <= Qt::QObject
end
|
.qobject_wrapper_classes ⇒ Object
49
50
51
52
53
54
55
56
57
58
|
# File 'lib/qt/object_wrapper.rb', line 49
def qobject_wrapper_classes
Qt.constants(false).filter_map do |const_name|
klass = Qt.const_get(const_name, false)
next unless klass.is_a?(Class)
next unless klass.const_defined?(:QT_CLASS, false)
next unless klass <= Qt::QObject
klass
end
end
|
.register_wrapper(wrapper) ⇒ Object
84
85
86
87
88
89
90
91
92
93
94
95
|
# File 'lib/qt/object_wrapper.rb', line 84
def register_wrapper(wrapper)
return wrapper unless wrapper.respond_to?(:handle)
pointer = wrapper.handle
return wrapper if null_pointer?(pointer)
return wrapper unless qobject_wrapper?(wrapper.class)
cached = cached_wrapper_for(pointer)
return cached if cached
cache_wrapper(wrapper)
end
|
.reset_cache! ⇒ Object
113
114
115
116
|
# File 'lib/qt/object_wrapper.rb', line 113
def reset_cache!
@wrapper_cache = {}
@destroy_hook_addresses = {}
end
|
.resolve_wrapper_class(pointer, expected_qt_class) ⇒ Object
32
33
34
35
36
|
# File 'lib/qt/object_wrapper.rb', line 32
def resolve_wrapper_class(pointer, expected_qt_class)
candidate_wrapper_classes(expected_qt_class).find do |klass|
Native.qobject_inherits(pointer, klass::QT_CLASS)
end
end
|
.wrap(pointer, expected_qt_class = nil) ⇒ Object
15
16
17
18
19
20
21
22
23
24
25
26
|
# File 'lib/qt/object_wrapper.rb', line 15
def wrap(pointer, expected_qt_class = nil)
return nil if null_pointer?(pointer)
return pointer if pointer.respond_to?(:handle)
cached = cached_wrapper_for(pointer)
return cached if cached
klass = resolve_wrapper_class(pointer, expected_qt_class) || fallback_wrapper_class(expected_qt_class)
return pointer unless klass
register_wrapper(instantiate_wrapper(klass, pointer))
end
|
.wrapper_cache ⇒ Object
127
128
129
|
# File 'lib/qt/object_wrapper.rb', line 127
def wrapper_cache
@wrapper_cache ||= {}
end
|