qml 0.0.7 → 1.0.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.
Files changed (296) hide show
  1. checksums.yaml +4 -4
  2. data/.gitmodules +3 -0
  3. data/.travis.yml +5 -9
  4. data/LICENSE.txt +1 -1
  5. data/README.md +84 -114
  6. data/changes.md +5 -0
  7. data/examples/fizzbuzz/fizzbuzz.rb +3 -4
  8. data/examples/todo_array/todo_array.rb +4 -4
  9. data/examples/todo_sequel/todo_sequel.rb +7 -7
  10. data/examples/twitter/twitter.rb +5 -3
  11. data/ext/qml/application.c +88 -0
  12. data/ext/qml/application.h +9 -0
  13. data/ext/qml/component.c +89 -0
  14. data/ext/qml/component.h +10 -0
  15. data/ext/qml/conversion.c +60 -0
  16. data/ext/qml/conversion.h +8 -0
  17. data/ext/qml/dispatcher.c +31 -0
  18. data/ext/qml/dispatcher.h +7 -0
  19. data/ext/qml/engine.c +135 -0
  20. data/ext/qml/engine.h +10 -0
  21. data/ext/qml/exporter.c +93 -0
  22. data/ext/qml/exporter.h +7 -0
  23. data/ext/qml/extconf.rb +38 -97
  24. data/ext/qml/interface.c +156 -0
  25. data/ext/qml/interface.h +11 -0
  26. data/ext/qml/js_array.c +47 -0
  27. data/ext/qml/js_array.h +7 -0
  28. data/ext/qml/js_function.c +109 -0
  29. data/ext/qml/js_function.h +7 -0
  30. data/ext/qml/js_object.c +284 -0
  31. data/ext/qml/js_object.h +19 -0
  32. data/ext/qml/js_wrapper.c +19 -0
  33. data/ext/qml/js_wrapper.h +7 -0
  34. data/ext/qml/lib/libqmlbind/.gitignore +38 -0
  35. data/ext/qml/lib/libqmlbind/.gitmodules +3 -0
  36. data/ext/qml/lib/libqmlbind/.travis.yml +14 -0
  37. data/ext/qml/lib/libqmlbind/LICENSE.txt +22 -0
  38. data/ext/qml/lib/libqmlbind/libqmlbind.pro +3 -0
  39. data/ext/qml/lib/libqmlbind/qmlbind/include/qmlbind.h +14 -0
  40. data/ext/qml/lib/libqmlbind/qmlbind/include/qmlbind/application.h +18 -0
  41. data/ext/qml/lib/libqmlbind/qmlbind/include/qmlbind/component.h +21 -0
  42. data/ext/qml/lib/libqmlbind/qmlbind/include/qmlbind/engine.h +34 -0
  43. data/ext/qml/lib/libqmlbind/qmlbind/include/qmlbind/exporter.h +37 -0
  44. data/ext/qml/lib/libqmlbind/qmlbind/include/qmlbind/interface.h +16 -0
  45. data/ext/qml/lib/libqmlbind/qmlbind/include/qmlbind/iterator.h +19 -0
  46. data/ext/qml/lib/libqmlbind/qmlbind/include/qmlbind/metaobject.h +13 -0
  47. data/ext/qml/lib/libqmlbind/qmlbind/include/qmlbind/plugin.h +17 -0
  48. data/ext/qml/lib/libqmlbind/qmlbind/include/qmlbind/qmlbind_global.h +78 -0
  49. data/ext/qml/lib/libqmlbind/qmlbind/include/qmlbind/register.h +17 -0
  50. data/ext/qml/lib/libqmlbind/qmlbind/include/qmlbind/signal_emitter.h +15 -0
  51. data/ext/qml/lib/libqmlbind/qmlbind/include/qmlbind/string.h +15 -0
  52. data/ext/qml/lib/libqmlbind/qmlbind/include/qmlbind/value.h +100 -0
  53. data/ext/qml/lib/libqmlbind/qmlbind/qmlbind.pro +62 -0
  54. data/ext/qml/lib/libqmlbind/qmlbind/src/api_application.cpp +103 -0
  55. data/ext/qml/lib/libqmlbind/qmlbind/src/api_component.cpp +54 -0
  56. data/ext/qml/lib/libqmlbind/qmlbind/src/api_engine.cpp +65 -0
  57. data/ext/qml/lib/libqmlbind/qmlbind/src/api_exporter.cpp +52 -0
  58. data/ext/qml/lib/libqmlbind/qmlbind/src/api_interface.cpp +19 -0
  59. data/ext/qml/lib/libqmlbind/qmlbind/src/api_iterator.cpp +32 -0
  60. data/ext/qml/lib/libqmlbind/qmlbind/src/api_metaobject.cpp +19 -0
  61. data/ext/qml/lib/libqmlbind/qmlbind/src/api_plugin.cpp +27 -0
  62. data/ext/qml/lib/libqmlbind/qmlbind/src/api_register.cpp +17 -0
  63. data/ext/qml/lib/libqmlbind/qmlbind/src/api_signal_emitter.cpp +27 -0
  64. data/ext/qml/lib/libqmlbind/qmlbind/src/api_string.cpp +22 -0
  65. data/ext/qml/lib/libqmlbind/qmlbind/src/api_value.cpp +215 -0
  66. data/ext/qml/lib/libqmlbind/qmlbind/src/backref.cpp +54 -0
  67. data/ext/qml/lib/libqmlbind/qmlbind/src/backref.h +29 -0
  68. data/ext/qml/lib/libqmlbind/qmlbind/src/engine.cpp +32 -0
  69. data/ext/qml/lib/libqmlbind/qmlbind/src/engine.h +27 -0
  70. data/ext/qml/lib/libqmlbind/qmlbind/src/exporter.cpp +73 -0
  71. data/ext/qml/lib/libqmlbind/qmlbind/src/exporter.h +46 -0
  72. data/ext/qml/lib/libqmlbind/qmlbind/src/interface.cpp +75 -0
  73. data/ext/qml/lib/libqmlbind/qmlbind/src/interface.h +37 -0
  74. data/ext/qml/lib/libqmlbind/qmlbind/src/metaobject.cpp +101 -0
  75. data/ext/qml/lib/libqmlbind/qmlbind/src/metaobject.h +29 -0
  76. data/ext/qml/lib/libqmlbind/qmlbind/src/signalemitter.cpp +33 -0
  77. data/ext/qml/lib/libqmlbind/qmlbind/src/signalemitter.h +25 -0
  78. data/ext/qml/lib/libqmlbind/qmlbind/src/ticktimer.cpp +15 -0
  79. data/ext/qml/lib/libqmlbind/qmlbind/src/ticktimer.h +19 -0
  80. data/ext/qml/lib/libqmlbind/qmlbind/src/typeregisterer.cpp +112 -0
  81. data/ext/qml/lib/libqmlbind/qmlbind/src/typeregisterer.h +28 -0
  82. data/ext/qml/lib/libqmlbind/qmlbind/src/util.h +13 -0
  83. data/ext/qml/lib/libqmlbind/qmlbind/src/wrapper.cpp +23 -0
  84. data/ext/qml/lib/libqmlbind/qmlbind/src/wrapper.h +29 -0
  85. data/ext/qml/lib/libqmlbind/readme.md +14 -0
  86. data/ext/qml/lib/libqmlbind/test/api.c +1 -0
  87. data/ext/qml/lib/libqmlbind/test/application_test.cpp +16 -0
  88. data/ext/qml/lib/libqmlbind/test/component_test.cpp +57 -0
  89. data/ext/qml/lib/libqmlbind/test/engine_test.cpp +94 -0
  90. data/ext/qml/lib/libqmlbind/test/exporter_test.cpp +312 -0
  91. data/ext/qml/lib/libqmlbind/test/fixtures/emptyhandlers.cpp +36 -0
  92. data/ext/qml/lib/libqmlbind/test/fixtures/emptyhandlers.h +6 -0
  93. data/ext/qml/lib/libqmlbind/test/fixtures/test.qml +5 -0
  94. data/ext/qml/lib/libqmlbind/test/fixtures/testmodule/qmldir +2 -0
  95. data/ext/qml/lib/libqmlbind/test/fixtures/testmodule/test.qml +5 -0
  96. data/ext/qml/lib/libqmlbind/test/iterator_test.cpp +37 -0
  97. data/ext/qml/lib/libqmlbind/test/main.cpp +11 -0
  98. data/ext/qml/lib/libqmlbind/test/plugin_test.cpp +41 -0
  99. data/ext/qml/lib/libqmlbind/test/test.pro +26 -0
  100. data/ext/qml/lib/libqmlbind/test/test_helper.h +20 -0
  101. data/ext/qml/lib/libqmlbind/test/value_test.cpp +252 -0
  102. data/ext/qml/lib/libqmlbind/testplugin/testplugin.cpp +11 -0
  103. data/ext/qml/lib/libqmlbind/testplugin/testplugin.h +21 -0
  104. data/ext/qml/lib/libqmlbind/testplugin/testplugin.json +3 -0
  105. data/ext/qml/lib/libqmlbind/testplugin/testplugin.pro +21 -0
  106. data/ext/qml/meta_object.c +81 -0
  107. data/ext/qml/meta_object.h +8 -0
  108. data/ext/qml/plugin_loader.c +71 -0
  109. data/ext/qml/plugin_loader.h +7 -0
  110. data/ext/qml/qml.c +95 -0
  111. data/ext/qml/qml.h +10 -0
  112. data/ext/qml/rubyqml-plugin/listmodel.cpp +102 -0
  113. data/ext/qml/rubyqml-plugin/listmodel.h +37 -0
  114. data/ext/qml/rubyqml-plugin/rubyqml-plugin.pro +19 -0
  115. data/ext/qml/rubyqml-plugin/rubyqmlplugin.cpp +25 -0
  116. data/ext/qml/rubyqml-plugin/rubyqmlplugin.h +19 -0
  117. data/ext/qml/signal_emitter.c +71 -0
  118. data/ext/qml/signal_emitter.h +9 -0
  119. data/lib/qml.rb +11 -10
  120. data/lib/qml/access.rb +64 -86
  121. data/lib/qml/application.rb +20 -71
  122. data/lib/qml/component.rb +41 -33
  123. data/lib/qml/core_ext.rb +1 -0
  124. data/lib/qml/core_ext/to_qml.rb +70 -0
  125. data/lib/qml/data.rb +1 -0
  126. data/lib/qml/data/array_model.rb +99 -101
  127. data/lib/qml/data/list_model.rb +107 -131
  128. data/lib/qml/data/list_model_access.rb +44 -0
  129. data/lib/qml/data/query_model.rb +45 -47
  130. data/lib/qml/dispatcher.rb +5 -13
  131. data/lib/qml/engine.rb +9 -58
  132. data/lib/qml/errors.rb +0 -21
  133. data/lib/qml/interface.rb +21 -0
  134. data/lib/qml/js_array.rb +8 -0
  135. data/lib/qml/js_object.rb +69 -0
  136. data/lib/qml/js_util.rb +18 -0
  137. data/lib/qml/plugin_loader.rb +1 -13
  138. data/lib/qml/plugins.rb +3 -17
  139. data/lib/qml/proc_access.rb +28 -0
  140. data/lib/qml/qt.rb +21 -3
  141. data/lib/qml/reactive.rb +147 -8
  142. data/lib/qml/signal.rb +67 -0
  143. data/lib/qml/version.rb +1 -1
  144. data/qml.gemspec +8 -2
  145. data/spec/qml/access_spec.rb +33 -120
  146. data/spec/qml/application_spec.rb +11 -24
  147. data/spec/qml/component_spec.rb +4 -4
  148. data/spec/qml/data/array_model_spec.rb +2 -2
  149. data/spec/qml/data/list_model_spec.rb +2 -2
  150. data/spec/qml/data/query_model_spec.rb +4 -4
  151. data/spec/qml/engine_spec.rb +23 -21
  152. data/spec/qml/interface_spec.rb +20 -0
  153. data/spec/qml/js_array_spec.rb +29 -0
  154. data/spec/qml/js_function_spec.rb +32 -0
  155. data/spec/qml/js_object_spec.rb +113 -0
  156. data/spec/qml/plugin_loader_spec.rb +9 -11
  157. data/spec/qml/qt_spec.rb +9 -0
  158. data/spec/qml/reactive_spec.rb +37 -0
  159. data/spec/qml/signal_connect_spec.rb +27 -0
  160. data/spec/qml/signal_spec.rb +73 -0
  161. data/spec/qml/to_qml_spec.rb +76 -0
  162. data/spec/shared/qml/access_example.rb +21 -0
  163. data/spec/shared/qml/data/list_model.rb +12 -13
  164. data/spec/spec_helper.rb +2 -3
  165. metadata +141 -166
  166. data/examples/imageprovider/imageprovider.rb +0 -57
  167. data/examples/imageprovider/main.qml +0 -51
  168. data/ext/qml/accessclass.cpp +0 -65
  169. data/ext/qml/accessclass.h +0 -19
  170. data/ext/qml/accessobject.cpp +0 -30
  171. data/ext/qml/accessobject.h +0 -22
  172. data/ext/qml/common.h +0 -18
  173. data/ext/qml/conversionerror.h +0 -14
  174. data/ext/qml/ext_accesswrapperfactory.cpp +0 -75
  175. data/ext/qml/ext_accesswrapperfactory.h +0 -39
  176. data/ext/qml/ext_anywrapper.cpp +0 -34
  177. data/ext/qml/ext_anywrapper.h +0 -23
  178. data/ext/qml/ext_kernel.cpp +0 -81
  179. data/ext/qml/ext_kernel.h +0 -9
  180. data/ext/qml/ext_metaobject.cpp +0 -399
  181. data/ext/qml/ext_metaobject.h +0 -60
  182. data/ext/qml/ext_pluginloader.cpp +0 -53
  183. data/ext/qml/ext_pluginloader.h +0 -30
  184. data/ext/qml/ext_pointer.cpp +0 -132
  185. data/ext/qml/ext_pointer.h +0 -41
  186. data/ext/qml/ext_testutil.cpp +0 -40
  187. data/ext/qml/ext_testutil.h +0 -9
  188. data/ext/qml/foreignclass.cpp +0 -72
  189. data/ext/qml/foreignclass.h +0 -88
  190. data/ext/qml/foreignmetaobject.cpp +0 -345
  191. data/ext/qml/foreignmetaobject.h +0 -46
  192. data/ext/qml/foreignobject.cpp +0 -22
  193. data/ext/qml/foreignobject.h +0 -21
  194. data/ext/qml/functioninfo.h +0 -16
  195. data/ext/qml/init.cpp +0 -67
  196. data/ext/qml/kernel.cpp +0 -39
  197. data/ext/qml/kernel.h +0 -32
  198. data/ext/qml/listmodel.cpp +0 -137
  199. data/ext/qml/listmodel.h +0 -45
  200. data/ext/qml/markable.h +0 -12
  201. data/ext/qml/objectdata.cpp +0 -26
  202. data/ext/qml/objectdata.h +0 -20
  203. data/ext/qml/objectgc.cpp +0 -69
  204. data/ext/qml/objectgc.h +0 -28
  205. data/ext/qml/plugins/core/applicationextension.cpp +0 -29
  206. data/ext/qml/plugins/core/applicationextension.h +0 -25
  207. data/ext/qml/plugins/core/componentextension.cpp +0 -41
  208. data/ext/qml/plugins/core/componentextension.h +0 -28
  209. data/ext/qml/plugins/core/contextextension.cpp +0 -39
  210. data/ext/qml/plugins/core/contextextension.h +0 -29
  211. data/ext/qml/plugins/core/core.pro +0 -29
  212. data/ext/qml/plugins/core/coreplugin.cpp +0 -87
  213. data/ext/qml/plugins/core/coreplugin.h +0 -49
  214. data/ext/qml/plugins/core/engineextension.cpp +0 -43
  215. data/ext/qml/plugins/core/engineextension.h +0 -31
  216. data/ext/qml/plugins/core/imageprovider.cpp +0 -38
  217. data/ext/qml/plugins/core/imageprovider.h +0 -18
  218. data/ext/qml/plugins/core/imagerequestpromise.cpp +0 -19
  219. data/ext/qml/plugins/core/imagerequestpromise.h +0 -21
  220. data/ext/qml/plugins/core/qmlexception.cpp +0 -11
  221. data/ext/qml/plugins/core/qmlexception.h +0 -17
  222. data/ext/qml/plugins/testutil/imageprovidertest.cpp +0 -40
  223. data/ext/qml/plugins/testutil/imageprovidertest.h +0 -17
  224. data/ext/qml/plugins/testutil/objectlifechecker.cpp +0 -17
  225. data/ext/qml/plugins/testutil/objectlifechecker.h +0 -24
  226. data/ext/qml/plugins/testutil/ownershiptest.cpp +0 -26
  227. data/ext/qml/plugins/testutil/ownershiptest.h +0 -30
  228. data/ext/qml/plugins/testutil/testobject.cpp +0 -6
  229. data/ext/qml/plugins/testutil/testobject.h +0 -108
  230. data/ext/qml/plugins/testutil/testobjectsubclass.cpp +0 -10
  231. data/ext/qml/plugins/testutil/testobjectsubclass.h +0 -19
  232. data/ext/qml/plugins/testutil/testutil.pro +0 -22
  233. data/ext/qml/plugins/testutil/testutilplugin.cpp +0 -55
  234. data/ext/qml/plugins/testutil/testutilplugin.h +0 -36
  235. data/ext/qml/qmltyperegisterer.cpp +0 -74
  236. data/ext/qml/qmltyperegisterer.h +0 -30
  237. data/ext/qml/rubyclass.cpp +0 -82
  238. data/ext/qml/rubyclass.h +0 -230
  239. data/ext/qml/rubyvalue.cpp +0 -656
  240. data/ext/qml/rubyvalue.h +0 -224
  241. data/ext/qml/signalforwarder.cpp +0 -64
  242. data/ext/qml/signalforwarder.h +0 -29
  243. data/ext/qml/util.cpp +0 -112
  244. data/ext/qml/util.h +0 -82
  245. data/ext/qml/valuereference.cpp +0 -50
  246. data/ext/qml/valuereference.h +0 -22
  247. data/ext/qml/weakvaluereference.cpp +0 -51
  248. data/ext/qml/weakvaluereference.h +0 -21
  249. data/lib/qml/context.rb +0 -71
  250. data/lib/qml/data/error.rb +0 -5
  251. data/lib/qml/dispatchable.rb +0 -34
  252. data/lib/qml/error_converter.rb +0 -16
  253. data/lib/qml/geometry.rb +0 -3
  254. data/lib/qml/geometry/point.rb +0 -5
  255. data/lib/qml/geometry/rectangle.rb +0 -5
  256. data/lib/qml/geometry/size.rb +0 -5
  257. data/lib/qml/image_provider.rb +0 -87
  258. data/lib/qml/init.rb +0 -29
  259. data/lib/qml/meta_object.rb +0 -20
  260. data/lib/qml/models.rb +0 -1
  261. data/lib/qml/qt_classes.rb +0 -9
  262. data/lib/qml/qt_object_base.rb +0 -233
  263. data/lib/qml/reactive/bindable.rb +0 -79
  264. data/lib/qml/reactive/chained_signal.rb +0 -25
  265. data/lib/qml/reactive/error.rb +0 -5
  266. data/lib/qml/reactive/object.rb +0 -293
  267. data/lib/qml/reactive/property.rb +0 -19
  268. data/lib/qml/reactive/signal.rb +0 -115
  269. data/lib/qml/reactive/signal_spy.rb +0 -27
  270. data/lib/qml/reactive/signals/map_signal.rb +0 -21
  271. data/lib/qml/reactive/signals/merge_signal.rb +0 -21
  272. data/lib/qml/reactive/signals/select_signal.rb +0 -21
  273. data/lib/qml/reactive/simple_property.rb +0 -17
  274. data/lib/qml/reactive/unbound_property.rb +0 -42
  275. data/lib/qml/reactive/unbound_signal.rb +0 -51
  276. data/lib/qml/test_util.rb +0 -1
  277. data/lib/qml/test_util/object_life_checker.rb +0 -17
  278. data/lib/qml/wrappable.rb +0 -9
  279. data/spec/qml/context_spec.rb +0 -43
  280. data/spec/qml/conversion_spec.rb +0 -60
  281. data/spec/qml/dispatchable_spec.rb +0 -26
  282. data/spec/qml/dispatcher_spec.rb +0 -71
  283. data/spec/qml/geometry/point_spec.rb +0 -4
  284. data/spec/qml/geometry/rectangle_spec.rb +0 -4
  285. data/spec/qml/geometry/size_spec.rb +0 -4
  286. data/spec/qml/image_provider_spec.rb +0 -33
  287. data/spec/qml/qt_object_base_spec.rb +0 -119
  288. data/spec/qml/reactive/object_spec.rb +0 -249
  289. data/spec/qml/reactive/property_spec.rb +0 -70
  290. data/spec/qml/reactive/signal_spec.rb +0 -191
  291. data/spec/qml/reactive/signal_spy_spec.rb +0 -26
  292. data/spec/qml/reactive/unbound_property_spec.rb +0 -40
  293. data/spec/qml/reactive/unbound_signal_spec.rb +0 -70
  294. data/spec/qml/test_object_spec.rb +0 -186
  295. data/spec/qml/wrappable_spec.rb +0 -10
  296. data/spec/shared/qml/reactive/object.rb +0 -39
@@ -1,25 +1,11 @@
1
- require 'qml/plugin_loader'
2
- require 'qml/root_path'
3
1
  require 'pathname'
4
2
 
5
3
  module QML
4
+ # @api private
6
5
  module Plugins
7
-
8
- PATH = ROOT_PATH + 'ext/qml/plugins'
9
-
10
6
  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
7
+ def rubyqml
8
+ @plugin ||= QML::PluginLoader.new(ROOT_PATH + "ext/qml/rubyqml-plugin", "rubyqml-plugin").instance
23
9
  end
24
10
  end
25
11
  end
@@ -0,0 +1,28 @@
1
+ module QML
2
+ class ProcAccess
3
+ include Access
4
+ register_to_qml under: 'RubyQml', version: QML::VERSION
5
+
6
+ def call(args)
7
+ @proc.call(*args)
8
+ end
9
+
10
+ # @return [QML::JSFunction]
11
+ def self.wrap_proc(prc)
12
+ @bind_call ||= QML.engine.evaluate <<-JS
13
+ (function (access) { return access.call.bind(access); })
14
+ JS
15
+
16
+ @component ||= QML::Component.new(data: <<-QML)
17
+ import RubyQml 1.0
18
+ ProcAccess {}
19
+ QML
20
+
21
+ access = @component.create
22
+ access.unwrap.instance_eval do
23
+ @proc = prc
24
+ end
25
+ @bind_call.call(access)
26
+ end
27
+ end
28
+ end
@@ -1,6 +1,24 @@
1
- require 'qml/qt_classes'
2
1
 
3
2
  module QML
4
- # @!parse class Qt < QtObjectBase; end
5
- class Qt; end
3
+ module_function
4
+
5
+ # @example
6
+ # def set_app_name
7
+ # QML.qt.application.name = 'appname'
8
+ # end
9
+ # @return [JSObject] QML Qt namespace object
10
+ # @see http://doc.qt.io/qt-5/qml-qtqml-qt.html
11
+ def qt
12
+ @qt ||= begin
13
+ component = QML::Component.new data: <<-QML
14
+ import QtQuick 2.0
15
+ QtObject {
16
+ function getQt() {
17
+ return Qt;
18
+ }
19
+ }
20
+ QML
21
+ component.create.getQt
22
+ end
23
+ end
6
24
  end
@@ -1,8 +1,147 @@
1
- require 'qml/reactive/signal'
2
- require 'qml/reactive/signals/map_signal'
3
- require 'qml/reactive/signals/select_signal'
4
- require 'qml/reactive/signals/merge_signal'
5
- require 'qml/reactive/signal_spy'
6
- require 'qml/reactive/property'
7
- require 'qml/reactive/object'
8
- require 'qml/reactive/error'
1
+ module QML
2
+
3
+ module Reactive
4
+ # @!parse extend ClassMethods
5
+
6
+ # @api private
7
+ class PropertyInfo
8
+ attr_accessor :initializer
9
+ end
10
+
11
+ # @api private
12
+ class SignalInfo
13
+ attr_accessor :params
14
+ attr_accessor :listeners
15
+
16
+ def initialize
17
+ @listeners = []
18
+ end
19
+ end
20
+
21
+ def initialize(*args, &block)
22
+
23
+ self.class.property_infos.each do |name, info|
24
+ if info.initializer
25
+ self.__send__ :"#{name}=", instance_eval(&info.initializer)
26
+ end
27
+ end
28
+
29
+ self.class.signal_infos.each do |name, info|
30
+ __send__(name).connect do |*args|
31
+ info.listeners.each do |listener|
32
+ instance_exec(*args, &listener)
33
+ end
34
+ end
35
+ end
36
+
37
+ super
38
+ end
39
+
40
+ def self.included(derived)
41
+ derived.class_eval do
42
+ extend ClassMethods
43
+ end
44
+ end
45
+
46
+ module ClassMethods
47
+
48
+ # @api public
49
+ # Defines a signal.
50
+ # @example
51
+ # class Button
52
+ # include QML::Reactive::Object
53
+ # signal :pressed, [:pos]
54
+ # ...
55
+ # end
56
+ def signal(name, params = [])
57
+ name = name.to_sym
58
+ signal_infos(false)[name] = SignalInfo.new.tap do |info|
59
+ info.params = params.map(&:to_sym)
60
+ end
61
+
62
+ class_eval <<-EOS, __FILE__, __LINE__ + 1
63
+ def #{name}
64
+ @_signal_#{name} ||= begin
65
+ args = self.class.signal_infos[:#{name}].params
66
+ Signal.new(args)
67
+ end
68
+ end
69
+ EOS
70
+
71
+ name
72
+ end
73
+
74
+ private :signal
75
+
76
+ def signals(include_super = true)
77
+ signal_infos(include_super).keys
78
+ end
79
+
80
+ def signal_infos(include_super = true)
81
+ if include_super && superclass.include?(Access)
82
+ superclass.signal_infos.merge(signal_infos(false))
83
+ else
84
+ @signal_infos ||= {}
85
+ end
86
+ end
87
+
88
+ # Defines a property.
89
+ # @example
90
+ # class Foo
91
+ # include QML::Access
92
+ # property(:name) { 'hogehoge' }
93
+ # ...
94
+ # end
95
+ def property(name, &block)
96
+ name = name.to_sym
97
+ signal(:"#{name}_changed", [:"new_#{name}"])
98
+
99
+ property_infos(false)[name] = PropertyInfo.new.tap do |info|
100
+ info.initializer = block
101
+ end
102
+
103
+ class_eval <<-EOS, __FILE__, __LINE__ + 1
104
+ attr_reader :#{name}
105
+ def #{name}=(new_value)
106
+ new_value = new_value
107
+ if @#{name} != new_value
108
+ @#{name} = new_value
109
+ #{name}_changed.emit(new_value)
110
+ end
111
+ end
112
+ EOS
113
+
114
+ name
115
+ end
116
+
117
+ private :property
118
+
119
+ def properties(include_super = true)
120
+ property_infos(include_super).keys
121
+ end
122
+
123
+ def property_infos(include_super = true)
124
+ if include_super && superclass.include?(Access)
125
+ superclass.property_infos.merge(property_infos(false))
126
+ else
127
+ @property_infos ||= {}
128
+ end
129
+ end
130
+
131
+ def on(signal, &block)
132
+ info = signal_infos(false)[signal.to_sym] or fail AccessError, "no signal `#{signal}` found"
133
+ info.listeners << block
134
+ block
135
+ end
136
+
137
+ def on_changed(property, &block)
138
+ on(:"#{property}_changed", &block)
139
+ end
140
+
141
+ private :on, :on_changed
142
+
143
+ end
144
+
145
+ end
146
+
147
+ end
@@ -0,0 +1,67 @@
1
+ module QML
2
+
3
+ class Signal
4
+
5
+ class Connection
6
+ def initialize(signal, listener)
7
+ @signal = signal
8
+ @listener = listener
9
+ end
10
+
11
+ # Disconnects the connection.
12
+ def disconnect
13
+ @signal.disconnect(@listener)
14
+ end
15
+ end
16
+
17
+ attr_reader :arity
18
+
19
+ # Initializes the Signal.
20
+ # @param [Array<#to_sym>, nil] params the parameter names (the signal will be variadic if nil).
21
+ def initialize(params)
22
+ @listeners = []
23
+ @params = params.map(&:to_sym)
24
+ @arity = params.size
25
+ end
26
+
27
+ # Calls every connected procedure with given arguments.
28
+ # Raises an ArgumentError when the arity is wrong.
29
+ # @param args the arguments.
30
+ def emit(*args)
31
+ if args.size != @arity
32
+ fail ::ArgumentError ,"wrong number of arguments for signal (#{args.size} for #{@arity})"
33
+ end
34
+ @listeners.each do |listener|
35
+ listener.call(*args)
36
+ end
37
+ end
38
+
39
+ # Returns the format of the parameters in the same format as Proc#parameters.
40
+ # @return [Array<Array<Symbol>>]
41
+ def parameters
42
+ @params ? @params.map { |arg| [:req, arg] } : [[:rest, :args]]
43
+ end
44
+
45
+ # Returns the number of connections.
46
+ # @return [Integer]
47
+ def connection_count
48
+ @listeners.size
49
+ end
50
+
51
+ # Connects a procedure.
52
+ # @yield called when #emit is called.
53
+ # @return [QML::Signal::Connection]
54
+ def connect(&listener)
55
+ @listeners << listener
56
+ Connection.new(self, listener)
57
+ end
58
+
59
+ # Disconnects a procedure.
60
+ # @param listener
61
+ # @return [self]
62
+ def disconnect(listener)
63
+ @listeners.delete(listener)
64
+ self
65
+ end
66
+ end
67
+ end
@@ -1,3 +1,3 @@
1
1
  module QML
2
- VERSION = '0.0.7'
2
+ VERSION = '1.0.0'
3
3
  end
@@ -13,7 +13,14 @@ Gem::Specification.new do |spec|
13
13
  spec.homepage = "http://seanchas116.github.io/ruby-qml/"
14
14
  spec.license = "MIT"
15
15
 
16
- spec.files = `git ls-files -z`.split("\x0")
16
+ qmlbind_dir = "ext/qml/lib/libqmlbind"
17
+ qmlbind_files = Dir.chdir(qmlbind_dir) do
18
+ `git ls-files -z`
19
+ .split("\x0")
20
+ .map { |file| "#{qmlbind_dir}/#{file}" }
21
+ end
22
+
23
+ spec.files = `git ls-files -z`.split("\x0") + qmlbind_files
17
24
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
25
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
26
  spec.require_paths = ["lib"]
@@ -25,7 +32,6 @@ Gem::Specification.new do |spec|
25
32
  spec.add_development_dependency "rake", "~> 10.3"
26
33
  spec.add_development_dependency "rspec", "~> 3.0"
27
34
  spec.add_development_dependency 'pry'
28
- spec.add_development_dependency 'celluloid'
29
35
  spec.add_development_dependency 'twitter', '~> 5.11'
30
36
  spec.add_development_dependency 'sequel', '~> 4.12'
31
37
  spec.add_development_dependency 'sqlite3', '~> 1.3'
@@ -1,93 +1,69 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe QML::Access do
4
- class Foo
5
- include QML::Access
6
4
 
7
- property :text
8
- signal :some_signal, [:arg]
9
-
10
- def some_method(a, b)
11
- a + b
12
- end
13
-
14
- def variadic_method(*args)
15
- end
16
- end
17
-
18
- class Bar < Foo
19
- def some_method(a, b)
20
- 'overridden'
21
- end
22
-
23
- def bar_method
24
- 'bar'
25
- end
26
- end
27
-
28
- let(:context) { QML::Context.new }
29
- let(:component) { QML::Component.new context: context, data: data }
5
+ let(:component) { QML::Component.new data: data }
30
6
  let(:root) { component.create }
31
7
 
32
8
  describe '.register_to_qml' do
33
9
 
34
10
  context 'when namespace, version, name are given' do
35
11
 
36
- class Hoge
37
- include QML::Access
38
-
39
- register_to_qml under: 'HogeNS', version: '1.2', name: 'Hoge'
40
-
41
- property :text
42
-
43
- def some_method(a, b)
44
- a + b
45
- end
46
- end
47
-
48
12
  let(:data) do
49
13
  <<-EOS
50
14
  import QtQuick 2.2
51
- import HogeNS 1.2
15
+ import AccessExampleNS 1.2
52
16
  Item {
53
17
  id: root
54
- property var bound: hoge.text + hoge.text
55
- Hoge { id: hoge }
18
+ property var bound: example.text + example.text
19
+ function getExample() {
20
+ return example;
21
+ }
22
+ function callSomeMethod() {
23
+ return example.some_method(100, 200);
24
+ }
25
+ AccessExample {
26
+ id: example
27
+ property var signalArg
28
+ onSome_signal: {
29
+ signalArg = arg;
30
+ }
31
+ }
56
32
  }
57
33
  EOS
58
34
  end
35
+ let(:example) { root.getExample }
36
+
59
37
  it 'registers the class as a QML type' do
60
38
  expect { component.create }.not_to raise_error
61
39
  end
62
- describe 'Hoge#some_method' do
40
+ describe 'AccessExamle#some_method' do
63
41
  it 'returns value' do
64
- expect(root.qml_eval('hoge.some_method(100, 200)')).to eq 300
42
+ expect(root.callSomeMethod()).to eq 300
65
43
  end
66
44
  end
67
- describe 'Hoge text property' do
45
+ describe 'AccessExamle text property' do
68
46
  it 'can be used to property binding' do
69
- root.qml_eval('hoge').text = "foo"
70
- expect(root.qml_eval('root').bound).to eq 'foofoo'
71
- root.qml_eval('hoge').text = "bar"
72
- expect(root.qml_eval('root').bound).to eq 'barbar'
47
+ example.text = "foo"
48
+ expect(root.bound).to eq 'foofoo'
49
+ example.text = "bar"
50
+ expect(root.bound).to eq 'barbar'
51
+ end
52
+ end
53
+ describe 'AccessExamle some_signal signal' do
54
+ it 'can be connected' do
55
+ example.unwrap.some_signal.emit('foo')
56
+ expect(example.signalArg).to eq 'foo'
73
57
  end
74
58
  end
75
59
  end
76
60
 
77
61
  context 'when arguments are omitted' do
78
62
 
79
- module HogeModule
80
- VERSION = '0.1.0'
81
- class Hoge
82
- include QML::Access
83
- register_to_qml
84
- end
85
- end
86
-
87
63
  let(:data) do
88
64
  <<-EOS
89
- import HogeModule 0.1
90
- Hoge {}
65
+ import AccessExampleModule 0.1
66
+ AccessExample {}
91
67
  EOS
92
68
  end
93
69
 
@@ -96,67 +72,4 @@ describe QML::Access do
96
72
  end
97
73
  end
98
74
  end
99
-
100
- context 'when used in context' do
101
-
102
- let(:data) do
103
- <<-EOS
104
- import QtQuick 2.2
105
- Item {
106
- id: root
107
- property string text: foo.text + foo.text
108
- Connections {
109
- id: connections
110
- target: foo
111
- property var args
112
- onSome_signal: {
113
- args = [arg]
114
- }
115
- }
116
- }
117
- EOS
118
- end
119
- let(:foo) { Foo.new }
120
- let(:bar) { Bar.new }
121
-
122
- before do
123
- context[:foo] = foo
124
- context[:bar] = bar
125
- root
126
- end
127
-
128
- describe 'Foo#some_method' do
129
- it 'returns value' do
130
- expect(root.qml_eval('foo.some_method(100, 200)')).to eq 300
131
- end
132
- end
133
- describe 'Bar#some_method' do
134
- it 'returns value' do
135
- expect(root.qml_eval('bar.some_method(100, 200)')).to eq 'overridden'
136
- end
137
- end
138
- describe 'Foo#variadic_method' do
139
- it 'will not be exported' do
140
- expect { root.qml_eval('foo.variadic_method()') }.to raise_error(QML::QMLError)
141
- end
142
- end
143
- describe 'Foo text property' do
144
- it 'can get and set value' do
145
- root.qml_eval('foo').text = 'test'
146
- expect(root.qml_eval('foo').text).to eq 'test'
147
- end
148
- it 'can be used for property binding' do
149
- foo.text = 'hoge'
150
- expect(root.qml_eval('root.text')).to eq 'hogehoge'
151
- foo.text = 'piyo'
152
- expect(root.qml_eval('root.text')).to eq 'piyopiyo'
153
- end
154
- end
155
- describe 'Foo some_signal signal' do
156
- it 'can be connected' do
157
- foo.some_signal.emit('foo')
158
- expect(root.qml_eval('connections.args')).to eq ['foo']
159
- end
160
- end
161
- end
162
75
  end