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
@@ -0,0 +1,19 @@
1
+ #-------------------------------------------------
2
+ #
3
+ # Project created by QtCreator 2015-05-16T11:55:09
4
+ #
5
+ #-------------------------------------------------
6
+
7
+ QT += core gui qml
8
+
9
+ TARGET = rubyqml-plugin
10
+ TEMPLATE = lib
11
+ CONFIG += plugin
12
+
13
+ SOURCES += \
14
+ rubyqmlplugin.cpp \
15
+ listmodel.cpp
16
+
17
+ HEADERS += \
18
+ rubyqmlplugin.h \
19
+ listmodel.h
@@ -0,0 +1,25 @@
1
+ #include "rubyqmlplugin.h"
2
+ #include "listmodel.h"
3
+ #include <QQmlEngine>
4
+ #include <QQmlContext>
5
+
6
+ namespace RubyQml {
7
+
8
+ RubyQmlPlugin::RubyQmlPlugin(QObject *parent) :
9
+ QObject(parent)
10
+ {
11
+ }
12
+
13
+ QJSValue RubyQmlPlugin::createListModel(const QJSValue &rubyModelAccess)
14
+ {
15
+ QObject *access = rubyModelAccess.toQObject();
16
+ Q_ASSERT(access);
17
+ QQmlEngine *engine = QQmlEngine::contextForObject(access)->engine();
18
+
19
+ ListModel *listModel = new ListModel(rubyModelAccess);
20
+ QQmlEngine::setObjectOwnership(listModel, QQmlEngine::JavaScriptOwnership);
21
+
22
+ return engine->newQObject(listModel);
23
+ }
24
+
25
+ }
@@ -0,0 +1,19 @@
1
+ #pragma once
2
+
3
+ #include <QObject>
4
+ #include <QJSValue>
5
+
6
+ namespace RubyQml {
7
+
8
+ class RubyQmlPlugin : public QObject
9
+ {
10
+ Q_OBJECT
11
+ Q_PLUGIN_METADATA(IID "org.ruby-qml.RubyQml")
12
+
13
+ public:
14
+ RubyQmlPlugin(QObject *parent = 0);
15
+
16
+ Q_INVOKABLE QJSValue createListModel(const QJSValue &rubyModelAccess);
17
+ };
18
+
19
+ }
@@ -0,0 +1,71 @@
1
+ #include "signal_emitter.h"
2
+ #include "conversion.h"
3
+ #include "engine.h"
4
+
5
+ VALUE rbqml_cSignalEmitter;
6
+
7
+ typedef struct {
8
+ qmlbind_signal_emitter emitter;
9
+ } emitter_t;
10
+
11
+ static void emitter_free(void *p) {
12
+ emitter_t *data = (emitter_t *)p;
13
+ qmlbind_signal_emitter_release(data->emitter);
14
+ xfree(data);
15
+ }
16
+
17
+ static const rb_data_type_t data_type = {
18
+ "QML::SignalEmitter",
19
+ { NULL, &emitter_free }
20
+ };
21
+
22
+ VALUE rbqml_signal_emitter_new(qmlbind_signal_emitter emitter) {
23
+ emitter_t *data = ALLOC(emitter_t);
24
+ data->emitter = emitter;
25
+ return TypedData_Wrap_Struct(rbqml_cSignalEmitter, &data_type, data);
26
+ }
27
+
28
+ static VALUE emitter_alloc(VALUE klass) {
29
+ rb_raise(rb_eTypeError, "QML::SignalEmitter cannot be created from Ruby");
30
+ }
31
+
32
+ typedef struct {
33
+ qmlbind_signal_emitter emitter;
34
+ const char *name;
35
+ int argc;
36
+ qmlbind_value *argv;
37
+ } emit_data;
38
+
39
+ static void *emit_impl(void *p) {
40
+ emit_data *data = p;
41
+ qmlbind_signal_emitter_emit(data->emitter, data->name, data->argc, data->argv);
42
+ return NULL;
43
+ }
44
+
45
+ static VALUE emitter_emit(VALUE self, VALUE name, VALUE args) {
46
+ emitter_t *d;
47
+ TypedData_Get_Struct(self, emitter_t, &data_type, d);
48
+
49
+ int argc = RARRAY_LEN(args);
50
+ qmlbind_value *qmlArgs = malloc(argc * sizeof(qmlbind_value));
51
+
52
+ for (int i = 0; i < argc; ++i) {
53
+ qmlbind_value value = rbqml_to_qml(RARRAY_AREF(args, i));
54
+ qmlArgs[i] = value;
55
+ }
56
+
57
+ emit_data data;
58
+ data.emitter = d->emitter;
59
+ data.name = rb_id2name(SYM2ID(name));
60
+ data.argc = argc;
61
+ data.argv = qmlArgs;
62
+
63
+ rb_thread_call_without_gvl(&emit_impl, &data, RUBY_UBF_IO, NULL);
64
+ return self;
65
+ }
66
+
67
+ void rbqml_init_signal_emitter(void) {
68
+ rbqml_cSignalEmitter = rb_define_class_under(rb_path2class("QML"), "SignalEmitter", rb_cObject);
69
+ rb_define_alloc_func(rbqml_cSignalEmitter, &emitter_alloc);
70
+ rb_define_method(rbqml_cSignalEmitter, "emit", &emitter_emit, 2);
71
+ }
@@ -0,0 +1,9 @@
1
+ #pragma once
2
+
3
+ #include "qml.h"
4
+
5
+ extern VALUE rbqml_cSignalEmitter;
6
+
7
+ VALUE rbqml_signal_emitter_new(qmlbind_signal_emitter emitter);
8
+
9
+ void rbqml_init_signal_emitter(void);
data/lib/qml.rb CHANGED
@@ -1,22 +1,23 @@
1
1
  require 'qml/version'
2
+ require 'qml/errors'
2
3
  require 'qml/qml'
3
4
 
4
- require 'qml/geometry'
5
- require 'qml/reactive'
5
+ require 'qml/core_ext'
6
6
 
7
- require 'qml/init'
8
- require 'qml/meta_object'
9
7
  require 'qml/plugin_loader'
8
+ require 'qml/plugins'
10
9
  require 'qml/component'
11
10
  require 'qml/engine'
12
- require 'qml/context'
13
11
  require 'qml/application'
14
- require 'qml/image_provider'
15
- require 'qml/qt'
12
+ require 'qml/dispatcher'
13
+ require 'qml/signal'
14
+ require 'qml/reactive'
16
15
  require 'qml/access'
16
+ require 'qml/qt'
17
17
  require 'qml/root_path'
18
- require 'qml/dispatcher'
19
- require 'qml/dispatchable'
18
+ require 'qml/js_object'
19
+ require 'qml/js_array'
20
+ require 'qml/js_util'
21
+ require 'qml/proc_access'
20
22
 
21
23
  require 'qml/data'
22
- require 'qml/test_util'
@@ -1,33 +1,29 @@
1
- require 'ostruct'
2
- require 'qml/qml'
3
- require 'qml/dispatchable'
4
- require 'qml/wrappable'
5
-
6
1
  module QML
7
2
 
8
3
  # {Access} enables classes to be exposed to QML.
9
4
  #
10
5
  module Access
11
- include Dispatchable
12
- include Wrappable
13
- # @!parse include Reactive::Object
6
+ # @!parse include Reactive
14
7
  # @!parse extend ClassMethods
15
8
 
9
+ def set_signal_emitter(emitter)
10
+ self.class.signals.each do |name|
11
+ __send__(name).connect do |*args|
12
+ emitter.emit(name, args)
13
+ end
14
+ end
15
+ end
16
+ private :set_signal_emitter
17
+
16
18
  def self.included(derived)
17
19
  derived.class_eval do
18
- include Reactive::Object
20
+ include Reactive
19
21
  extend ClassMethods
20
22
  end
21
23
  end
22
24
 
23
- # @api private
24
- def self.unregistered_classes
25
- @unregistered_classes ||= []
26
- end
27
-
28
- # @api private
29
- def self.register_classes
30
- unregistered_classes.each(&:register_to_qml_real)
25
+ def to_qml
26
+ @qml_value ||= self.class.meta_object.wrap(self)
31
27
  end
32
28
 
33
29
  # allowed name patterns for exposed method names
@@ -35,12 +31,62 @@ module QML
35
31
 
36
32
  module ClassMethods
37
33
 
34
+ def meta_object
35
+ @meta_object ||= begin
36
+ exporter = Exporter.new(self, name)
37
+
38
+ signals = self.signals.grep(ALLOWED_PATTERN)
39
+ properties = self.properties.grep(ALLOWED_PATTERN)
40
+
41
+ signals.each do |signal|
42
+ exporter.add_signal(signal, signal_infos[signal].params)
43
+ end
44
+
45
+ properties.each do |prop|
46
+ exporter.add_property(prop, :"#{prop}_changed")
47
+ end
48
+
49
+ methods = ancestors.take_while { |k| k.include?(Access) }
50
+ .map { |k| k.instance_methods(false) }.inject(&:|)
51
+ .grep(ALLOWED_PATTERN)
52
+ ignored_methods = signals | properties.flat_map { |p| [p, :"#{p}=", :"#{p}_changed"] }
53
+
54
+ (methods - ignored_methods).each do |method|
55
+ instance_method = self.instance_method(method)
56
+ # ignore variadic methods
57
+ if instance_method.arity >= 0
58
+ exporter.add_method(method, instance_method.arity)
59
+ end
60
+ end
61
+ exporter.to_meta_object
62
+ end
63
+ end
64
+
38
65
  # Registers the class as a QML type.
39
66
  # @param opts [Hash]
40
67
  # @option opts [String] :under the namespece which encapsulates the exported QML type. If not specified, automatically inferred from the module nesting of the class.
41
68
  # @option opts [String] :version the version of the type. Defaults to VERSION constant of the encapsulating module / class of the class.
42
69
  # @option opts [String] :name the name of the type. Defaults to the name of the class.
43
70
  def register_to_qml(opts = {})
71
+ QML.on_init do
72
+ register_to_qml_impl(opts)
73
+ end
74
+ end
75
+
76
+ def register_to_qml_impl(opts)
77
+ metadata = guess_metadata(opts)
78
+
79
+ meta_object.register(
80
+ metadata[:under],
81
+ metadata[:versions][0],
82
+ metadata[:versions][1],
83
+ metadata[:name]
84
+ )
85
+ end
86
+
87
+ private
88
+
89
+ def guess_metadata(opts)
44
90
  under = opts[:under]
45
91
  version = opts[:version]
46
92
  name = opts[:name]
@@ -59,76 +105,8 @@ module QML
59
105
  fail AccessError, 'insufficient version (major and minor versions required)' unless versions.size >= 2
60
106
  name ||= path.last
61
107
 
62
- @qml_registeration = {
63
- under: under,
64
- version_major: versions[0],
65
- version_minor: versions[1],
66
- name: name
67
- }
68
- Access.unregistered_classes << self
69
- end
70
-
71
- # @api private
72
- def register_to_qml_real
73
- access_wrapper_factory.register_to_qml(
74
- @qml_registeration[:under],
75
- @qml_registeration[:version_major],
76
- @qml_registeration[:version_minor],
77
- @qml_registeration[:name])
78
- end
79
-
80
- # @api private
81
- def access_wrapper_factory
82
- @access_wrapper_factory ||= create_access_wrapper_factory
83
- end
84
-
85
- private
86
-
87
- def create_access_wrapper_factory
88
- classname = "RubyQml::Access::#{name}"
89
-
90
- signals = instance_signals.grep(ALLOWED_PATTERN)
91
- properties = instance_properties.grep(ALLOWED_PATTERN)
92
-
93
- signal_infos = signals
94
- .map { |name| instance_signal(name) }
95
- .reject(&:variadic?)
96
- .map { |signal| OpenStruct.new(name: signal.name, params: signal.parameters.map(&:last)) }
97
-
98
- property_infos = properties
99
- .map { |name| OpenStruct.new(name: name, getter: name, setter: :"#{name}=", notifier: :"#{name}_changed") }
100
-
101
- methods = ancestors.take_while { |k| k.include?(Access) }
102
- .map { |k| k.instance_methods(false) }.inject(&:|)
103
- .grep(ALLOWED_PATTERN)
104
- ignored_methods = signals | property_infos.flat_map { |p| [p.getter, p.setter, p.notifier] }
105
- method_infos = (methods - ignored_methods)
106
- .map { |name| instance_method(name) }
107
- .select { |method| method.parameters.all? { |param| param[0] == :req } }
108
- .map { |method| OpenStruct.new(name: method.name, params: method.parameters.map(&:last)) }
109
-
110
- AccessWrapperFactory.new(self, classname, method_infos, signal_infos, property_infos)
111
- end
112
- end
113
-
114
- # @api private
115
- attr_reader :access_wrappers
116
-
117
- def initialize(*args, &block)
118
- signal_names = signals + properties.map { |name| :"#{name}_changed" }
119
- signal_names.each do |name|
120
- __send__(name).connect do |*args|
121
- @access_wrappers.each do |obj|
122
- obj.class.meta_object.invoke_method(obj.pointer, name, args)
123
- end
124
- end
108
+ {under: under, versions: versions, name: name}
125
109
  end
126
- @access_wrappers = []
127
- super
128
- end
129
-
130
- def create_wrapper
131
- self.class.access_wrapper_factory.create(self)
132
110
  end
133
111
  end
134
112
  end
@@ -1,42 +1,13 @@
1
- require 'qml/qt_classes'
2
-
3
1
  module QML
4
- # @!parse class Application < QtObjectBase; end
5
-
6
2
  # {Application} represents a Qt application instance.
7
3
  # It provides the event loop and manages Application-level configurations.
8
4
  #
9
5
  # @see http://qt-project.org/doc/qt-5/qapplication.html QApplication (C++)
10
6
  class Application
11
7
 
12
- # @return [Application] The application instance.
13
- def self.instance
14
- Kernel.application
15
- end
16
-
17
- def self.notify_error(error)
18
- instance.notify_error(error)
19
- end
20
-
21
- # @note This method cannot be called because {Application} is singleton.
22
- def self.new
23
- fail ApplicationError, "cannot create Application instance manually"
24
- end
25
-
26
- def initialize
27
- super()
28
- @extension = Plugins.core.createApplicationExtension(self)
29
- end
30
-
31
8
  # @return [Engine] The engine of the application.
32
9
  def engine
33
- Kernel.engine
34
- end
35
-
36
- # @return [Context] The root context of the engine.
37
- # @see #engine
38
- def context
39
- engine.context
10
+ QML.engine
40
11
  end
41
12
 
42
13
  # @return [Component] The root component of the application that represents the loaded QML file.
@@ -48,12 +19,11 @@ module QML
48
19
  end
49
20
 
50
21
  # Loads a QML file. The loaded component can be accessed by {#root_component}
51
- # @param [Hash] opts
52
- # @option opts [String] :data
53
- # @option opts [String] :path
22
+ # @param [String] data
23
+ # @param [String] path
54
24
  # @see Component
55
- def load(opts)
56
- @root_component = Component.new(data: opts[:data], path: opts[:path])
25
+ def load(data: nil, path: nil)
26
+ @root_component = Component.new(data: data, path: path)
57
27
  @root = @root_component.create
58
28
  end
59
29
 
@@ -74,58 +44,37 @@ module QML
74
44
  @root or fail "QML data or file has not been loaded"
75
45
  end
76
46
 
77
- # Starts the event loop of the application.
78
- # This method never returns until the application quits.
79
- def exec
80
- @extension.exec
81
- end
82
-
83
- # Processes queued events in the event loop manually.
84
- # This method is useful when you are combining an external event loop like EventMachine.
85
- def process_events
86
- @extension.process_events
47
+ # Quits the application.
48
+ def quit
49
+ QML.qt.quit
87
50
  end
51
+ end
88
52
 
89
- def force_deferred_deletes
90
- @extension.force_deferred_deletes
91
- end
53
+ INIT_BLOCKS = []
92
54
 
93
- # Runs garbage collection of Ruby and QML and deletes unused objects.
94
- def collect_garbage
95
- ::GC.start
96
- engine.collect_garbage
97
- force_deferred_deletes
98
- end
55
+ module_function
99
56
 
100
- # Called when an Ruby error is occured in executing Qt code.
101
- # @param error The error (or the exception)
102
- def notify_error(error)
103
- warn "-- An error occured when running Ruby code from Qt --"
104
- warn "#{error.class.name}: #{error.message}"
105
- warn "Backtrace: \n\t#{error.backtrace.join("\n\t")}"
106
- end
57
+ def on_init(&block)
58
+ INIT_BLOCKS << block
107
59
  end
108
60
 
109
- # Returns the instance of {Application}.
110
- # @return [Application]
111
- def application
112
- Application.instance
61
+ # Initializes ruby-qml.
62
+ # @param [Array<String>] args Arguments to pass to the application
63
+ def init(args = [])
64
+ init_impl(args)
113
65
  end
114
66
 
115
- # Call {init} if ruby-qml is not initialized, then yields the application instance and then call {Application#exec}.
67
+ # Creates an {Application}, yields it and then call {QML::Application#exec}.
116
68
  # @return [Application]
117
69
  # @example
118
70
  # QML.run do |app|
119
- # app.context[:foo] = 'foo'
120
71
  # app.load_path Pathname(__FILE__) + '../main.qml'
121
72
  # end
122
73
  def run
123
- QML.init unless QML.initialized?
124
- Application.instance.tap do |app|
74
+ QML.init
75
+ QML.application.tap do |app|
125
76
  yield app
126
77
  app.exec
127
78
  end
128
79
  end
129
-
130
- module_function :application, :run
131
80
  end