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,81 +0,0 @@
1
- #include "ext_kernel.h"
2
- #include "kernel.h"
3
- #include "rubyvalue.h"
4
- #include "rubyclass.h"
5
- #include <QTimer>
6
-
7
- namespace RubyQml {
8
- namespace Ext_Kernel {
9
-
10
- namespace {
11
-
12
- RubyValue application(RubyValue self)
13
- {
14
- Q_UNUSED(self);
15
- return RubyValue::from(Kernel::instance()->application());
16
- }
17
-
18
- RubyValue engine(RubyValue self)
19
- {
20
- Q_UNUSED(self);
21
- return RubyValue::from(Kernel::instance()->engine());
22
- }
23
-
24
- RubyValue eventLoopHookTimer(RubyValue self)
25
- {
26
- Q_UNUSED(self);
27
- return RubyValue::from(Kernel::instance()->eventLoopHookTimer());
28
- }
29
-
30
- RubyValue setEventLoopHookEnabledLater(RubyValue self, RubyValue enabled)
31
- {
32
- Q_UNUSED(self);
33
- auto timer = Kernel::instance()->eventLoopHookTimer();
34
- if (enabled) {
35
- timer->metaObject()->invokeMethod(timer, "start", Qt::QueuedConnection);
36
- } else {
37
- timer->metaObject()->invokeMethod(timer, "stop", Qt::QueuedConnection);
38
- }
39
- return enabled;
40
- }
41
-
42
- RubyValue applicationMetaObject()
43
- {
44
- return RubyValue::from(&QApplication::staticMetaObject);
45
- }
46
-
47
- RubyValue engineMetaObject()
48
- {
49
- return RubyValue::from(&QQmlEngine::staticMetaObject);
50
- }
51
-
52
- RubyValue init(RubyValue self, RubyValue argv)
53
- {
54
- Q_UNUSED(self);
55
- Kernel::init(argv.to<QList<QByteArray>>());
56
- return Qnil;
57
- }
58
-
59
- RubyValue initialized(RubyValue self)
60
- {
61
- Q_UNUSED(self);
62
- return RubyValue::from(Kernel::initialized());
63
- }
64
-
65
- }
66
-
67
- void defineModule()
68
- {
69
- RubyModule kernel(RubyModule::fromPath("QML"), "Kernel");
70
- kernel.defineModuleFunction("application", RUBYQML_FUNCTION_INFO(&application));
71
- kernel.defineModuleFunction("engine", RUBYQML_FUNCTION_INFO(&engine));
72
- kernel.defineModuleFunction("event_loop_hook_timer", RUBYQML_FUNCTION_INFO(&eventLoopHookTimer));
73
- kernel.defineModuleFunction("set_event_loop_hook_enabled_later", RUBYQML_FUNCTION_INFO(&setEventLoopHookEnabledLater));
74
- kernel.defineModuleFunction("application_meta_object", RUBYQML_FUNCTION_INFO(&applicationMetaObject));
75
- kernel.defineModuleFunction("engine_meta_object", RUBYQML_FUNCTION_INFO(&engineMetaObject));
76
- kernel.defineModuleFunction("init", RUBYQML_FUNCTION_INFO(&init));
77
- kernel.defineModuleFunction("initialized?", RUBYQML_FUNCTION_INFO(&initialized));
78
- }
79
-
80
- } // namespace Kernel
81
- } // namespace RubyQml
@@ -1,9 +0,0 @@
1
- #pragma once
2
-
3
- namespace RubyQml {
4
- namespace Ext_Kernel {
5
-
6
- void defineModule();
7
-
8
- } // namespace Kernel
9
- } // namespace RubyQml
@@ -1,399 +0,0 @@
1
- #include "ext_metaobject.h"
2
- #include "util.h"
3
- #include "ext_pointer.h"
4
- #include "rubyclass.h"
5
- #include "signalforwarder.h"
6
- #include <QtCore/QMetaObject>
7
- #include <QtCore/QMetaMethod>
8
- #include <QtCore/QMetaProperty>
9
- #include <QtCore/QMetaEnum>
10
- #include <QtCore/QVariant>
11
- #include <array>
12
- #include <QtCore/QDebug>
13
- #include <QtQml/QQmlEngine>
14
-
15
- namespace RubyQml {
16
-
17
- namespace {
18
-
19
- RubyValue idListToArray(const QList<ID> &xs)
20
- {
21
- auto ary = rb_ary_new();
22
- for (ID id : xs) {
23
- rb_ary_push(ary, ID2SYM(id));
24
- }
25
- return ary;
26
- }
27
-
28
- }
29
-
30
- Ext_MetaObject::Ext_MetaObject(RubyValue self) :
31
- self(self)
32
- {
33
- setMetaObject(&QObject::staticMetaObject);
34
- }
35
-
36
- RubyValue Ext_MetaObject::className() const
37
- {
38
- return rb_str_new_cstr(mMetaObject->className());
39
- }
40
-
41
- RubyValue Ext_MetaObject::methodNames() const
42
- {
43
- return idListToArray(mMethodHash.keys());
44
- }
45
-
46
- RubyValue Ext_MetaObject::isPublic(RubyValue name) const
47
- {
48
- auto methods = findMethods(name);
49
- return RubyValue::from(mMetaObject->method(methods.first()).access() == QMetaMethod::Public);
50
- }
51
- RubyValue Ext_MetaObject::isProtected(RubyValue name) const
52
- {
53
- auto methods = findMethods(name);
54
- return RubyValue::from(mMetaObject->method(methods.first()).access() == QMetaMethod::Protected);
55
- }
56
- RubyValue Ext_MetaObject::isPrivate(RubyValue name) const
57
- {
58
- auto methods = findMethods(name);
59
- return RubyValue::from(mMetaObject->method(methods.first()).access() == QMetaMethod::Private);
60
- }
61
- RubyValue Ext_MetaObject::isSignal(RubyValue name) const
62
- {
63
- auto methods = findMethods(name);
64
- return RubyValue::from(mMetaObject->method(methods.first()).methodType() == QMetaMethod::Signal);
65
- }
66
-
67
- class MethodInvoker
68
- {
69
- public:
70
- MethodInvoker(RubyValue args, const QMetaMethod &method) :
71
- mArgs(args), mMethod(method) {}
72
-
73
- bool isArgsCompatible() const
74
- {
75
- int count = RARRAY_LEN(VALUE(mArgs));
76
- if (mMethod.parameterCount() != count) {
77
- return false;
78
- }
79
- for (int i = 0; i < count; ++i) {
80
- auto metaType = mMethod.parameterType(i);
81
- RubyValue arg = RARRAY_AREF(VALUE(mArgs), i);
82
- if (!arg.isConvertibleTo(metaType)) {
83
- return false;
84
- }
85
- }
86
- return true;
87
- }
88
-
89
- RubyValue invoke(QObject *obj)
90
- {
91
- std::array<QVariant, 10> argVariants;
92
- std::array<QGenericArgument, 10> args;
93
- for (int i = 0; i < mMethod.parameterCount(); ++i) {
94
- auto metaType = mMethod.parameterType(i);
95
- argVariants[i] = RubyValue(RARRAY_AREF(VALUE(mArgs), i)).toVariant(metaType);
96
- args[i] = QGenericArgument(QMetaType::typeName(metaType), argVariants[i].data());
97
- }
98
-
99
- int returnType = mMethod.returnType();
100
- if (returnType == QMetaType::UnknownType) {
101
- fail("QML::MethodError", "unknown return metatype");
102
- }
103
- bool voidReturning = (returnType == QMetaType::Void);
104
- QVariant returnValue;
105
- if (!voidReturning) {
106
- auto data = QMetaType::create(returnType);
107
- returnValue = QVariant(returnType, data);
108
- QMetaType::destroy(returnType, data);
109
- }
110
-
111
- bool result;
112
- withoutGvl([&] {
113
- result = mMethod.invoke(
114
- obj,
115
- Qt::DirectConnection,
116
- QGenericReturnArgument(QMetaType::typeName(returnType), returnValue.data()),
117
- args[0],args[1],args[2],args[3],args[4],
118
- args[5],args[6],args[7],args[8],args[9]);
119
- });
120
-
121
- if (!result) {
122
- QString error;
123
- QDebug(&error) << "failed to call method" << mMethod.methodSignature();
124
- fail("QML::MethodError", error);
125
- }
126
- if (voidReturning) {
127
- return Qnil;
128
- } else {
129
- auto ret = RubyValue::from(returnValue);
130
- static auto objectBaseClass = RubyClass::fromPath("QML::QtObjectBase");
131
- if (ret.isKindOf(objectBaseClass)) {
132
- auto pointer = wrapperRubyClass<Ext_Pointer>().unwrap(ret.send("pointer"));
133
- pointer->preferManaged(true);
134
- }
135
- return ret;
136
- }
137
- }
138
- private:
139
- RubyValue mArgs;
140
- QMetaMethod mMethod;
141
- };
142
-
143
- RubyValue Ext_MetaObject::invokeMethod(RubyValue object, RubyValue methodName, RubyValue args) const
144
- {
145
- checkThread();
146
-
147
- auto methodIndexes = findMethods(methodName);
148
-
149
- args = rb_check_array_type(args);
150
-
151
- auto obj = wrapperRubyClass<Ext_Pointer>().unwrap(object)->fetchQObject();
152
- for (int i : methodIndexes) {
153
- MethodInvoker invoker(args, mMetaObject->method(i));
154
- if (invoker.isArgsCompatible()) {
155
- return invoker.invoke(obj);
156
- }
157
- }
158
-
159
- auto to_class = rb_funcall(ID2SYM(rb_intern("class")), rb_intern("to_proc"), 0);
160
- auto classes = rb_funcall_with_block(args, rb_intern("map"), 0, nullptr, to_class);
161
- auto classes_str = rb_funcall(classes, rb_intern("to_s"), 0);
162
-
163
- rb_raise(rb_path2class("QML::MethodError"),
164
- "method mismatch (%s with params %s in %s)",
165
- mMetaObject->method(methodIndexes.first()).name().data(),
166
- StringValueCStr(classes_str),
167
- mMetaObject->className());
168
-
169
- return Qnil;
170
- }
171
-
172
- RubyValue Ext_MetaObject::connectSignal(RubyValue object, RubyValue signalName, RubyValue proc) const
173
- {
174
- auto id = signalName.toID();
175
- auto obj = wrapperRubyClass<Ext_Pointer>().unwrap(object)->fetchQObject();
176
-
177
- proc = proc.send("to_proc");
178
-
179
- auto methodIndexes = mMethodHash.values(id);
180
- std::reverse(methodIndexes.begin(), methodIndexes.end());
181
-
182
- for (int i : methodIndexes) {
183
- auto method = mMetaObject->method(i);
184
- if (method.methodType() != QMetaMethod::Signal) {
185
- continue;
186
- }
187
- new SignalForwarder(obj, method, proc);
188
- return Qnil;
189
- }
190
- rb_raise(rb_path2class("QML::MethodError"),
191
- "signal not found (%s in %s)",
192
- rb_id2name(id), mMetaObject->className());
193
- return Qnil;
194
- }
195
-
196
- RubyValue Ext_MetaObject::propertyNames() const
197
- {
198
- return idListToArray(mPropertyHash.keys());
199
- }
200
-
201
- RubyValue Ext_MetaObject::getProperty(RubyValue object, RubyValue name) const
202
- {
203
- checkThread();
204
-
205
- auto metaProperty = mMetaObject->property(findProperty(name));
206
-
207
- auto qobj = wrapperRubyClass<Ext_Pointer>().unwrap(object)->fetchQObject();
208
- QVariant result;
209
- withoutGvl([&] {
210
- result = metaProperty.read(qobj);
211
- });
212
- return RubyValue::from(result);
213
- }
214
-
215
- RubyValue Ext_MetaObject::setProperty(RubyValue object, RubyValue name, RubyValue newValue) const
216
- {
217
- checkThread();
218
-
219
- auto metaProperty = mMetaObject->property(findProperty(name));
220
- if (!newValue.isConvertibleTo(metaProperty.userType())) {
221
- rb_raise(rb_path2class("QML::PropertyError"),
222
- "type mismatch (%s for %s)",
223
- rb_obj_classname(newValue), metaProperty.typeName());
224
- }
225
-
226
- auto qobj = wrapperRubyClass<Ext_Pointer>().unwrap(object)->fetchQObject();
227
- auto variant = newValue.to<QVariant>();
228
- QVariant result;
229
- withoutGvl([&] {
230
- metaProperty.write(qobj, variant);
231
- result = metaProperty.read(qobj);
232
- });
233
- return RubyValue::from(result);
234
- }
235
-
236
- RubyValue Ext_MetaObject::notifySignal(RubyValue name) const
237
- {
238
- auto metaProperty = mMetaObject->property(findProperty(name));
239
- auto signal = metaProperty.notifySignal();
240
- if (signal.isValid()) {
241
- return ID2SYM(rb_intern(metaProperty.notifySignal().name()));
242
- }
243
- else {
244
- return Qnil;
245
- }
246
- }
247
-
248
- void Ext_MetaObject::checkThread() const
249
- {
250
- if (rb_thread_current() != rb_thread_main()) {
251
- fail("QML::InvalidThreadError", "Qt object accessed from non-main thread");
252
- }
253
- }
254
-
255
- QList<int> Ext_MetaObject::findMethods(RubyValue name) const
256
- {
257
- auto id = name.toID();
258
- auto methodIndexes = mMethodHash.values(id);
259
- if (methodIndexes.size() == 0) {
260
- rb_raise(rb_path2class("QML::MethodError"),
261
- "method not found (%s in %s)",
262
- rb_id2name(id),
263
- mMetaObject->className());
264
- }
265
- return methodIndexes;
266
- }
267
-
268
- int Ext_MetaObject::findProperty(RubyValue name) const
269
- {
270
- auto id = name.toID();
271
- if (!mPropertyHash.contains(id)) {
272
- rb_raise(rb_path2class("QML::PropertyError"),
273
- "property not found (%s in %s)",
274
- rb_id2name(id), mMetaObject->className());
275
- }
276
- return mPropertyHash[id];
277
- }
278
-
279
- RubyValue Ext_MetaObject::enumerators() const
280
- {
281
- QHash<QByteArray, QHash<QByteArray, int>> enums;
282
-
283
- for (int i = mMetaObject->enumeratorOffset(); i < mMetaObject->enumeratorCount(); ++i) {
284
- auto metaEnum = mMetaObject->enumerator(i);
285
- if (metaEnum.isFlag()) {
286
- continue;
287
- }
288
-
289
- QHash<QByteArray, int> enumHash;
290
- for (int j = 0; j < metaEnum.keyCount(); ++j) {
291
- enumHash[metaEnum.key(j)] = metaEnum.value(j);
292
- }
293
- enums[metaEnum.name()] = enumHash;
294
- }
295
-
296
- return RubyValue::from(enums);
297
- }
298
-
299
- RubyValue Ext_MetaObject::superClass() const
300
- {
301
- auto superclass = mMetaObject->superClass();
302
- if (!superclass) {
303
- return Qnil;
304
- }
305
- return fromMetaObject(superclass);
306
- }
307
-
308
- RubyValue Ext_MetaObject::isEqual(RubyValue other) const
309
- {
310
- return RubyValue::from(mMetaObject == wrapperRubyClass<Ext_MetaObject>().unwrap(other)->mMetaObject);
311
- }
312
-
313
- RubyValue Ext_MetaObject::hash() const
314
- {
315
- return RubyValue::from(reinterpret_cast<size_t>(mMetaObject)).send("hash");
316
- }
317
-
318
- void Ext_MetaObject::setMetaObject(const QMetaObject *metaObject)
319
- {
320
- int methodCount = metaObject->methodCount() - metaObject->methodOffset();
321
-
322
- QMultiHash<ID, int> methodHash;
323
- QHash<ID, int> propertyHash;
324
-
325
- for (int i = 0; i < methodCount; ++i) {
326
-
327
- auto index = i + metaObject->methodOffset();
328
- auto method = metaObject->method(index);
329
-
330
- if (method.methodType() == QMetaMethod::Constructor) {
331
- continue;
332
- }
333
-
334
- methodHash.insert(rb_intern(method.name()), index);
335
- }
336
-
337
- int propertyCount = metaObject->propertyCount() - metaObject->propertyOffset();
338
-
339
- for (int i = 0; i < propertyCount; ++i) {
340
- auto index = i + metaObject->propertyOffset();
341
- auto property = metaObject->property(index);
342
- propertyHash[rb_intern(property.name())] = index;
343
- }
344
-
345
- int enumCount = metaObject->enumeratorCount() - metaObject->enumeratorOffset();
346
- for (int i = 0; i < enumCount; ++i) {
347
- auto index = i + metaObject->enumeratorOffset();
348
- auto metaEnum = metaObject->enumerator(index);
349
- auto typeName = QByteArray(metaObject->className()) + "::" + QByteArray(metaEnum.name());
350
- auto metaType = QMetaType::type(typeName);
351
- if (metaType != QMetaType::UnknownType) {
352
- RubyValue::addEnumeratorMetaType(metaType);
353
- }
354
- }
355
-
356
- mMetaObject = metaObject;
357
- mMethodHash = methodHash;
358
- mPropertyHash = propertyHash;
359
- }
360
-
361
- RubyValue Ext_MetaObject::fromMetaObject(const QMetaObject *metaObject)
362
- {
363
- auto klass = wrapperRubyClass<Ext_MetaObject>();
364
- auto value = klass.newInstance();
365
- klass.unwrap(value)->setMetaObject(metaObject);
366
- return value;
367
- }
368
-
369
- void Ext_MetaObject::defineClass()
370
- {
371
- WrapperRubyClass<Ext_MetaObject> klass(RubyModule::fromPath("QML"), "MetaObject");
372
-
373
- klass.defineMethod("name", RUBYQML_MEMBER_FUNCTION_INFO(&Ext_MetaObject::className));
374
-
375
- klass.defineMethod("method_names", RUBYQML_MEMBER_FUNCTION_INFO(&Ext_MetaObject::methodNames));
376
- klass.defineMethod("public?", RUBYQML_MEMBER_FUNCTION_INFO(&Ext_MetaObject::isPublic));
377
- klass.defineMethod("protected?", RUBYQML_MEMBER_FUNCTION_INFO(&Ext_MetaObject::isProtected));
378
- klass.defineMethod("private?", RUBYQML_MEMBER_FUNCTION_INFO(&Ext_MetaObject::isPrivate));
379
- klass.defineMethod("signal?", RUBYQML_MEMBER_FUNCTION_INFO(&Ext_MetaObject::isSignal));
380
-
381
- klass.defineMethod("invoke_method", RUBYQML_MEMBER_FUNCTION_INFO(&Ext_MetaObject::invokeMethod));
382
- klass.defineMethod("connect_signal", RUBYQML_MEMBER_FUNCTION_INFO(&Ext_MetaObject::connectSignal));
383
-
384
- klass.defineMethod("property_names", RUBYQML_MEMBER_FUNCTION_INFO(&Ext_MetaObject::propertyNames));
385
- klass.defineMethod("get_property", RUBYQML_MEMBER_FUNCTION_INFO(&Ext_MetaObject::getProperty));
386
- klass.defineMethod("set_property", RUBYQML_MEMBER_FUNCTION_INFO(&Ext_MetaObject::setProperty));
387
- klass.defineMethod("notify_signal", RUBYQML_MEMBER_FUNCTION_INFO(&Ext_MetaObject::notifySignal));
388
-
389
- klass.defineMethod("enumerators", RUBYQML_MEMBER_FUNCTION_INFO(&Ext_MetaObject::enumerators));
390
-
391
- klass.defineMethod("super_class", RUBYQML_MEMBER_FUNCTION_INFO(&Ext_MetaObject::superClass));
392
-
393
- klass.defineMethod("==", RUBYQML_MEMBER_FUNCTION_INFO(&Ext_MetaObject::isEqual));
394
- klass.defineMethod("hash", RUBYQML_MEMBER_FUNCTION_INFO(&Ext_MetaObject::hash));
395
-
396
- klass.aliasMethod("eql?", "==");
397
- }
398
-
399
- } // namespace RubyQml