qml 0.0.1
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 +7 -0
- data/.gitignore +46 -0
- data/.rspec +2 -0
- data/.travis.yml +15 -0
- data/.yardopts +4 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +351 -0
- data/Rakefile +6 -0
- data/examples/assets/fonts/fontawesome-webfont.ttf +0 -0
- data/examples/fizzbuzz/fizzbuzz.rb +43 -0
- data/examples/fizzbuzz/main.qml +38 -0
- data/examples/imageprovider/imageprovider.rb +57 -0
- data/examples/imageprovider/main.qml +51 -0
- data/examples/todo/main.qml +70 -0
- data/examples/todo/todo.rb +36 -0
- data/examples/twitter/main.qml +36 -0
- data/examples/twitter/twitter.rb +55 -0
- data/ext/qml/accessclass.cpp +71 -0
- data/ext/qml/accessclass.h +19 -0
- data/ext/qml/accessobject.cpp +30 -0
- data/ext/qml/accessobject.h +22 -0
- data/ext/qml/application.cpp +54 -0
- data/ext/qml/application.h +17 -0
- data/ext/qml/common.h +18 -0
- data/ext/qml/ext_accesssupport.cpp +77 -0
- data/ext/qml/ext_accesssupport.h +42 -0
- data/ext/qml/ext_gcmarker.cpp +39 -0
- data/ext/qml/ext_gcmarker.h +27 -0
- data/ext/qml/ext_kernel.cpp +62 -0
- data/ext/qml/ext_kernel.h +11 -0
- data/ext/qml/ext_metaobject.cpp +410 -0
- data/ext/qml/ext_metaobject.h +62 -0
- data/ext/qml/ext_pluginloader.cpp +55 -0
- data/ext/qml/ext_pluginloader.h +32 -0
- data/ext/qml/ext_pointer.cpp +134 -0
- data/ext/qml/ext_pointer.h +43 -0
- data/ext/qml/ext_testutil.cpp +42 -0
- data/ext/qml/ext_testutil.h +11 -0
- data/ext/qml/extconf.rb +84 -0
- data/ext/qml/foreignclass.cpp +72 -0
- data/ext/qml/foreignclass.h +88 -0
- data/ext/qml/foreignmetaobject.cpp +345 -0
- data/ext/qml/foreignmetaobject.h +46 -0
- data/ext/qml/foreignobject.cpp +22 -0
- data/ext/qml/foreignobject.h +21 -0
- data/ext/qml/functioninfo.h +16 -0
- data/ext/qml/init.cpp +69 -0
- data/ext/qml/listmodel.cpp +112 -0
- data/ext/qml/listmodel.h +43 -0
- data/ext/qml/markable.h +12 -0
- data/ext/qml/objectdata.cpp +26 -0
- data/ext/qml/objectdata.h +20 -0
- data/ext/qml/objectgc.cpp +69 -0
- data/ext/qml/objectgc.h +28 -0
- data/ext/qml/plugins/core/applicationextension.cpp +34 -0
- data/ext/qml/plugins/core/applicationextension.h +28 -0
- data/ext/qml/plugins/core/componentextension.cpp +41 -0
- data/ext/qml/plugins/core/componentextension.h +28 -0
- data/ext/qml/plugins/core/contextextension.cpp +39 -0
- data/ext/qml/plugins/core/contextextension.h +29 -0
- data/ext/qml/plugins/core/core.pro +29 -0
- data/ext/qml/plugins/core/coreplugin.cpp +87 -0
- data/ext/qml/plugins/core/coreplugin.h +49 -0
- data/ext/qml/plugins/core/engineextension.cpp +27 -0
- data/ext/qml/plugins/core/engineextension.h +28 -0
- data/ext/qml/plugins/core/imageprovider.cpp +38 -0
- data/ext/qml/plugins/core/imageprovider.h +18 -0
- data/ext/qml/plugins/core/imagerequestpromise.cpp +19 -0
- data/ext/qml/plugins/core/imagerequestpromise.h +21 -0
- data/ext/qml/plugins/core/qmlexception.cpp +11 -0
- data/ext/qml/plugins/core/qmlexception.h +17 -0
- data/ext/qml/plugins/testutil/objectlifechecker.cpp +17 -0
- data/ext/qml/plugins/testutil/objectlifechecker.h +24 -0
- data/ext/qml/plugins/testutil/ownershiptest.cpp +26 -0
- data/ext/qml/plugins/testutil/ownershiptest.h +30 -0
- data/ext/qml/plugins/testutil/testobject.cpp +6 -0
- data/ext/qml/plugins/testutil/testobject.h +108 -0
- data/ext/qml/plugins/testutil/testobjectsubclass.cpp +10 -0
- data/ext/qml/plugins/testutil/testobjectsubclass.h +19 -0
- data/ext/qml/plugins/testutil/testutil.pro +20 -0
- data/ext/qml/plugins/testutil/testutilplugin.cpp +47 -0
- data/ext/qml/plugins/testutil/testutilplugin.h +32 -0
- data/ext/qml/qmltyperegisterer.cpp +74 -0
- data/ext/qml/qmltyperegisterer.h +30 -0
- data/ext/qml/rubyclass.cpp +94 -0
- data/ext/qml/rubyclass.h +234 -0
- data/ext/qml/rubyvalue.cpp +690 -0
- data/ext/qml/rubyvalue.h +256 -0
- data/ext/qml/signalforwarder.cpp +66 -0
- data/ext/qml/signalforwarder.h +29 -0
- data/ext/qml/util.cpp +120 -0
- data/ext/qml/util.h +101 -0
- data/ext/qml/valuereference.cpp +50 -0
- data/ext/qml/valuereference.h +22 -0
- data/ext/qml/weakvaluereference.cpp +27 -0
- data/ext/qml/weakvaluereference.h +19 -0
- data/lib/qml.rb +41 -0
- data/lib/qml/access.rb +137 -0
- data/lib/qml/application.rb +139 -0
- data/lib/qml/class_builder.rb +126 -0
- data/lib/qml/component.rb +53 -0
- data/lib/qml/context.rb +71 -0
- data/lib/qml/data.rb +2 -0
- data/lib/qml/data/array_model.rb +103 -0
- data/lib/qml/data/error.rb +5 -0
- data/lib/qml/data/list_model.rb +146 -0
- data/lib/qml/dispatchable.rb +34 -0
- data/lib/qml/dispatcher.rb +61 -0
- data/lib/qml/engine.rb +54 -0
- data/lib/qml/error_converter.rb +15 -0
- data/lib/qml/errors.rb +26 -0
- data/lib/qml/geometry.rb +3 -0
- data/lib/qml/geometry/point.rb +5 -0
- data/lib/qml/geometry/rectangle.rb +5 -0
- data/lib/qml/geometry/size.rb +5 -0
- data/lib/qml/image_provider.rb +87 -0
- data/lib/qml/meta_object.rb +20 -0
- data/lib/qml/models.rb +1 -0
- data/lib/qml/name_helper.rb +12 -0
- data/lib/qml/platform.rb +15 -0
- data/lib/qml/plugin_loader.rb +46 -0
- data/lib/qml/plugins.rb +26 -0
- data/lib/qml/qml.rb +1 -0
- data/lib/qml/qt.rb +6 -0
- data/lib/qml/qt_classes.rb +9 -0
- data/lib/qml/qt_object_base.rb +108 -0
- data/lib/qml/reactive.rb +8 -0
- data/lib/qml/reactive/bindable.rb +79 -0
- data/lib/qml/reactive/chained_signal.rb +25 -0
- data/lib/qml/reactive/error.rb +5 -0
- data/lib/qml/reactive/object.rb +278 -0
- data/lib/qml/reactive/property.rb +19 -0
- data/lib/qml/reactive/signal.rb +116 -0
- data/lib/qml/reactive/signal_spy.rb +27 -0
- data/lib/qml/reactive/signals/map_signal.rb +21 -0
- data/lib/qml/reactive/signals/merge_signal.rb +21 -0
- data/lib/qml/reactive/signals/select_signal.rb +21 -0
- data/lib/qml/reactive/simple_property.rb +17 -0
- data/lib/qml/reactive/unbound_property.rb +42 -0
- data/lib/qml/reactive/unbound_signal.rb +51 -0
- data/lib/qml/root_path.rb +3 -0
- data/lib/qml/test_util.rb +1 -0
- data/lib/qml/test_util/object_life_checker.rb +17 -0
- data/lib/qml/version.rb +3 -0
- data/lib/qml/wrappable.rb +9 -0
- data/qml.gemspec +28 -0
- data/spec/assets/testobj.qml +5 -0
- data/spec/qml/.access_spec.rb.swp +0 -0
- data/spec/qml/access_spec.rb +162 -0
- data/spec/qml/application_spec.rb +43 -0
- data/spec/qml/component_spec.rb +44 -0
- data/spec/qml/context_spec.rb +43 -0
- data/spec/qml/conversion_spec.rb +59 -0
- data/spec/qml/data/array_model_spec.rb +215 -0
- data/spec/qml/dispatchable_spec.rb +26 -0
- data/spec/qml/dispatcher_spec.rb +48 -0
- data/spec/qml/geometry/point_spec.rb +4 -0
- data/spec/qml/geometry/rectangle_spec.rb +4 -0
- data/spec/qml/geometry/size_spec.rb +4 -0
- data/spec/qml/plugin_loader_spec.rb +33 -0
- data/spec/qml/qt_object_base_spec.rb +119 -0
- data/spec/qml/reactive/object_spec.rb +273 -0
- data/spec/qml/reactive/property_spec.rb +70 -0
- data/spec/qml/reactive/signal_spec.rb +191 -0
- data/spec/qml/reactive/signal_spy_spec.rb +26 -0
- data/spec/qml/test_object_spec.rb +186 -0
- data/spec/qml_spec.rb +7 -0
- data/spec/spec_helper.rb +5 -0
- metadata +321 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
module QML
|
|
2
|
+
|
|
3
|
+
# {Dispatchable} provides a handy way for asynchronous (queued) method calls
|
|
4
|
+
# which actually processed later in the event loop.
|
|
5
|
+
# @see QML.later
|
|
6
|
+
module Dispatchable
|
|
7
|
+
|
|
8
|
+
class Proxy < BasicObject
|
|
9
|
+
def initialize(obj)
|
|
10
|
+
@obj = obj
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# Actually enqueues the method call using {QML.later}.
|
|
14
|
+
def method_missing(name, *args, &block)
|
|
15
|
+
::QML.later do
|
|
16
|
+
@obj.__send__(name, *args, &block)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Returns a proxy object for calling a method asynchronously within the event loop.
|
|
22
|
+
# @return [Proxy]
|
|
23
|
+
# @example
|
|
24
|
+
# def on_button_clicked
|
|
25
|
+
# Thread.new do
|
|
26
|
+
# result = do_task
|
|
27
|
+
# later.set_result_to_ui(result)
|
|
28
|
+
# end
|
|
29
|
+
# end
|
|
30
|
+
def later
|
|
31
|
+
Proxy.new(self)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
require 'singleton'
|
|
2
|
+
require 'monitor'
|
|
3
|
+
|
|
4
|
+
module QML
|
|
5
|
+
|
|
6
|
+
class Dispatcher
|
|
7
|
+
include Singleton
|
|
8
|
+
include MonitorMixin
|
|
9
|
+
|
|
10
|
+
MAX_DURATION = 1/10.to_r
|
|
11
|
+
|
|
12
|
+
def initialize
|
|
13
|
+
@tasks = []
|
|
14
|
+
super
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def add_task(&task)
|
|
18
|
+
synchronize do
|
|
19
|
+
@tasks << task
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def empty?
|
|
24
|
+
synchronize do
|
|
25
|
+
@tasks.empty?
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def run_tasks
|
|
30
|
+
synchronize do
|
|
31
|
+
start_time = Time.now
|
|
32
|
+
loop do
|
|
33
|
+
break if @tasks.empty?
|
|
34
|
+
break if start_time.to_r - Time.now.to_r > MAX_DURATION
|
|
35
|
+
task = @tasks.shift
|
|
36
|
+
task.call
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Runs a block asynchronously within the event loop.
|
|
43
|
+
#
|
|
44
|
+
# QML UI is not thread-safe and can only be accessed from the main thread.
|
|
45
|
+
# Use this method to set results of asynchronous tasks to UI.
|
|
46
|
+
# @example
|
|
47
|
+
# def on_button_clicked
|
|
48
|
+
# Thread.new do
|
|
49
|
+
# result = do_task
|
|
50
|
+
# QML.later do
|
|
51
|
+
# set_result_to_ui(result)
|
|
52
|
+
# end
|
|
53
|
+
# end
|
|
54
|
+
# end
|
|
55
|
+
# @see Dispatchable#later
|
|
56
|
+
# @see Dispatcher#add_task
|
|
57
|
+
def later(&block)
|
|
58
|
+
Dispatcher.instance.add_task(&block)
|
|
59
|
+
end
|
|
60
|
+
module_function :later
|
|
61
|
+
end
|
data/lib/qml/engine.rb
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
require 'qml/qt_classes'
|
|
2
|
+
|
|
3
|
+
module QML
|
|
4
|
+
# @!parse class Engine < QtObjectBase; end
|
|
5
|
+
|
|
6
|
+
# {Engine} provides a QML engine.
|
|
7
|
+
#
|
|
8
|
+
# @see http://qt-project.org/doc/qt-5/qqmlengine.html QQmlEngine (C++)
|
|
9
|
+
class Engine
|
|
10
|
+
|
|
11
|
+
# @return [Engine] the instance of {Engine}.
|
|
12
|
+
# @see QML.engine
|
|
13
|
+
def self.instance
|
|
14
|
+
Kernel.engine
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# @note This method cannot be called because {Engine} is singleton.
|
|
18
|
+
def self.new
|
|
19
|
+
fail EngineError, "cannot create Engine instance manually"
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def initialize
|
|
23
|
+
super()
|
|
24
|
+
@extension = Plugins.core.createEngineExtension(self)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# @return [Context] the root {Context} the {Engine}.
|
|
28
|
+
def context
|
|
29
|
+
@extension.rootContext
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Starts garbage collection on the {Engine}.
|
|
33
|
+
def collect_garbage
|
|
34
|
+
@extension.collect_garbage
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Adds an {ImageProvider} to the {Engine}.
|
|
38
|
+
# @param id [String]
|
|
39
|
+
# @param provider [ImageProvider]
|
|
40
|
+
# @return [ImageProvider]
|
|
41
|
+
# @see ImageProvider
|
|
42
|
+
def add_image_provider(id, provider)
|
|
43
|
+
@extension.add_image_provider(id, provider.qt_image_provider)
|
|
44
|
+
provider
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# @return [Engine] the instance of {Engine}.
|
|
49
|
+
# @see Engine.instance
|
|
50
|
+
def engine
|
|
51
|
+
Kernel.engine
|
|
52
|
+
end
|
|
53
|
+
module_function :engine
|
|
54
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
module QML
|
|
2
|
+
module ErrorConverter
|
|
3
|
+
|
|
4
|
+
class << self
|
|
5
|
+
attr_reader :patterns
|
|
6
|
+
|
|
7
|
+
def add_pattern(cpp_classname, ruby_class)
|
|
8
|
+
@patterns ||= {}
|
|
9
|
+
@patterns[cpp_classname] = ruby_class
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
add_pattern 'RubyQml::QmlException', QMLError
|
|
14
|
+
end
|
|
15
|
+
end
|
data/lib/qml/errors.rb
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
module QML
|
|
2
|
+
|
|
3
|
+
class MethodError < StandardError; end
|
|
4
|
+
class SignalError < StandardError; end
|
|
5
|
+
class PropertyError < StandardError; end
|
|
6
|
+
class PluginError < StandardError; end
|
|
7
|
+
class QtObjectError < StandardError; end
|
|
8
|
+
class ConversionError < StandardError; end
|
|
9
|
+
class QMLError < StandardError; end
|
|
10
|
+
class AccessError < StandardError; end
|
|
11
|
+
class ApplicationError < StandardError; end
|
|
12
|
+
class EngineError < StandardError; end
|
|
13
|
+
class InvalidThreadError < StandardError; end
|
|
14
|
+
class UninitializedError < StandardError; end
|
|
15
|
+
class AlreadyInitializedError < StandardError; end
|
|
16
|
+
|
|
17
|
+
class CppError < StandardError
|
|
18
|
+
attr_reader :class_name, :raw_message
|
|
19
|
+
|
|
20
|
+
def initialize(classname, message)
|
|
21
|
+
super("<#{classname}> #{message}")
|
|
22
|
+
@class_name = classname
|
|
23
|
+
@raw_message = message
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
data/lib/qml/geometry.rb
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
require 'qml/access'
|
|
2
|
+
|
|
3
|
+
module QML
|
|
4
|
+
|
|
5
|
+
# {ImageProvider} is used to provide images manually to QML.
|
|
6
|
+
#
|
|
7
|
+
# QML requests images to ImageProviders when you use "image:" URL scheme
|
|
8
|
+
# (like "image://my_image_provider/foo.png") in source specification of Image elements.
|
|
9
|
+
#
|
|
10
|
+
# @example
|
|
11
|
+
# class MyImageProvider < QML::ImageProvider
|
|
12
|
+
# def request(req)
|
|
13
|
+
# Thread.new do
|
|
14
|
+
# image_data = load_image_data()
|
|
15
|
+
# req.finish(image_data)
|
|
16
|
+
# end
|
|
17
|
+
# end
|
|
18
|
+
# end
|
|
19
|
+
# QML.engine.add_image_provider(MyImageProvider.new)
|
|
20
|
+
#
|
|
21
|
+
# @see Engine#add_image_provider
|
|
22
|
+
# @see http://qt-project.org/doc/qt-5/qquickimageprovider.html QQuickImageProvider (C++)
|
|
23
|
+
# @see http://qt-project.org/doc/qt-5/qml-qtquick-image.html Image (QML)
|
|
24
|
+
|
|
25
|
+
class ImageProvider
|
|
26
|
+
|
|
27
|
+
# {Request} represents a image request from QML.
|
|
28
|
+
# @see ImageProvider#request
|
|
29
|
+
class Request
|
|
30
|
+
# The image ID.
|
|
31
|
+
# If you requested "image://my_image_provider/foo/bar.png", the ID would be "foo/bar.png".
|
|
32
|
+
attr_reader :id
|
|
33
|
+
|
|
34
|
+
# Finishes the image request.
|
|
35
|
+
# @param data [String] The image file data
|
|
36
|
+
def finish(data)
|
|
37
|
+
fail ::TypeError, "data must be a String" unless data.is_a? ::String
|
|
38
|
+
QML.later do
|
|
39
|
+
@promise.set_data(data)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
private
|
|
44
|
+
|
|
45
|
+
def initialize(id, promise)
|
|
46
|
+
@id = id;
|
|
47
|
+
@promise = promise
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
attr_reader :qt_image_provider
|
|
52
|
+
|
|
53
|
+
def initialize
|
|
54
|
+
@callback = Callback.new(self)
|
|
55
|
+
@qt_image_provider = Plugins.core.createImageProvider(@callback)
|
|
56
|
+
@qt_image_provider.prefer_managed false
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# @abstract
|
|
60
|
+
# @param req [Request]
|
|
61
|
+
#
|
|
62
|
+
# Implement this method to handle image requests from QML.
|
|
63
|
+
#
|
|
64
|
+
# Call {Request#finish} to finish image loading.
|
|
65
|
+
# Image loading should be done asynchnorously because this method is called within the event loop.
|
|
66
|
+
|
|
67
|
+
def request(req)
|
|
68
|
+
fail ::NotImplementedError
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
private
|
|
72
|
+
|
|
73
|
+
class Callback
|
|
74
|
+
include QML::Access
|
|
75
|
+
|
|
76
|
+
def initialize(provider)
|
|
77
|
+
super()
|
|
78
|
+
@provider = provider
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def request(id, promise)
|
|
82
|
+
promise.prefer_managed true
|
|
83
|
+
@provider.request(Request.new(id, promise))
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
require 'qml/qml'
|
|
2
|
+
require 'qml/class_builder'
|
|
3
|
+
|
|
4
|
+
module QML
|
|
5
|
+
class MetaObject
|
|
6
|
+
alias_method :to_s, :name
|
|
7
|
+
|
|
8
|
+
def inspect
|
|
9
|
+
"<QML::MetaObject:#{self}>"
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def build_class
|
|
13
|
+
@@classes ||= {}
|
|
14
|
+
klass = @@classes[name]
|
|
15
|
+
builder = ClassBuilder.new(self, klass)
|
|
16
|
+
builder.build
|
|
17
|
+
@@classes[name] = builder.klass
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
data/lib/qml/models.rb
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
require 'qml/models/array_model'
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
module QML
|
|
2
|
+
module NameHelper
|
|
3
|
+
module_function
|
|
4
|
+
|
|
5
|
+
def to_underscore(sym)
|
|
6
|
+
sym.to_s.gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').gsub(/([a-z\d])([A-Z])/,'\1_\2').downcase.to_sym
|
|
7
|
+
end
|
|
8
|
+
def to_upper_underscore(sym)
|
|
9
|
+
to_underscore(sym).upcase
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
data/lib/qml/platform.rb
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
require 'pathname'
|
|
2
|
+
require 'qml/platform'
|
|
3
|
+
|
|
4
|
+
module QML
|
|
5
|
+
# {PluginLoader} loads Qt C++ plugins and enables you to use your Qt C++ codes from Ruby easily.
|
|
6
|
+
# @see http://qt-project.org/doc/qt-5/qpluginloader.html QPluginLoader (C++)
|
|
7
|
+
class PluginLoader
|
|
8
|
+
|
|
9
|
+
alias_method :initialize_orig, :initialize
|
|
10
|
+
private :initialize_orig
|
|
11
|
+
|
|
12
|
+
# @overload initialize(path)
|
|
13
|
+
# @param [String|Pathname] path the library path (may be platform-dependent).
|
|
14
|
+
# @example
|
|
15
|
+
# loader = QML::PluginLoader.new('path/to/libhoge.dylib')
|
|
16
|
+
# @overload initialize(dir, libname)
|
|
17
|
+
# @param [String|Pathname] dir the library directory.
|
|
18
|
+
# @param [String] libname the platform-independent library name.
|
|
19
|
+
# @example
|
|
20
|
+
# loader = QML::PluginLoader.new('path/to', 'hoge')
|
|
21
|
+
def initialize(path, libname = nil)
|
|
22
|
+
path = Pathname(path) + self.class.lib_filename(libname) if libname
|
|
23
|
+
initialize_orig(path.to_s)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# @!method instance
|
|
27
|
+
# Loads the plugin and returns the instance of the plugin.
|
|
28
|
+
# @return [QtObjectBase]
|
|
29
|
+
|
|
30
|
+
# @param [String] libname
|
|
31
|
+
# @return [String] platform-dependent library file name.
|
|
32
|
+
# @example
|
|
33
|
+
# # on Mac
|
|
34
|
+
# QML::PluginLoader.lib_filename("hoge") #=> "libhoge.dylib"
|
|
35
|
+
def self.lib_filename(libname)
|
|
36
|
+
case
|
|
37
|
+
when Platform::windows?
|
|
38
|
+
"#{libname}.dll"
|
|
39
|
+
when Platform::mac?
|
|
40
|
+
"lib#{libname}.dylib"
|
|
41
|
+
else
|
|
42
|
+
"lib#{libname}.so"
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
data/lib/qml/plugins.rb
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
require 'qml/plugin_loader'
|
|
2
|
+
require 'qml/root_path'
|
|
3
|
+
require 'pathname'
|
|
4
|
+
|
|
5
|
+
module QML
|
|
6
|
+
module Plugins
|
|
7
|
+
|
|
8
|
+
PATH = ROOT_PATH + 'ext/qml/plugins'
|
|
9
|
+
|
|
10
|
+
class << self
|
|
11
|
+
def core
|
|
12
|
+
@core ||= load('core')
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def test_util
|
|
16
|
+
@test_util ||= load('testutil')
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
private
|
|
20
|
+
|
|
21
|
+
def load(name)
|
|
22
|
+
QML::PluginLoader.new(PATH + name, "rubyqml-#{name}").instance
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
data/lib/qml/qml.rb
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
require_relative '../../ext/qml/qml'
|