qml 0.0.7 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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