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,10 @@
1
+ #pragma once
2
+
3
+ #include <ruby/ruby.h>
4
+ #include <qmlbind.h>
5
+
6
+ extern VALUE rbqml_cEngine;
7
+
8
+ qmlbind_engine rbqml_get_engine(VALUE value);
9
+
10
+ void rbqml_init_engine(void);
@@ -0,0 +1,93 @@
1
+ #include "exporter.h"
2
+ #include "conversion.h"
3
+ #include "application.h"
4
+ #include "interface.h"
5
+ #include "engine.h"
6
+ #include "meta_object.h"
7
+
8
+ static VALUE referenced_objects;
9
+ VALUE rbqml_cExporter;
10
+
11
+
12
+ typedef struct {
13
+ qmlbind_exporter exporter;
14
+ } exporter;
15
+
16
+ static void exporter_free(void *p) {
17
+ exporter *data = (exporter *)p;
18
+
19
+ rb_thread_call_without_gvl((void *(*)(void *))&qmlbind_exporter_release, data->exporter, RUBY_UBF_IO, NULL);
20
+ xfree(data);
21
+ }
22
+
23
+ static const rb_data_type_t data_type = {
24
+ "QML::Exporter",
25
+ { NULL, &exporter_free }
26
+ };
27
+
28
+ qmlbind_exporter rbqml_get_exporter(VALUE self) {
29
+ exporter *data;
30
+ TypedData_Get_Struct(self, exporter, &data_type, data);
31
+ return data->exporter;
32
+ }
33
+
34
+ static VALUE exporter_alloc(VALUE klass) {
35
+ exporter *data = ALLOC(exporter);
36
+ data->exporter = NULL;
37
+ return TypedData_Wrap_Struct(klass, &data_type, data);
38
+ }
39
+
40
+
41
+
42
+ static VALUE exporter_initialize(VALUE self, VALUE klass, VALUE name) {
43
+ exporter *data;
44
+ TypedData_Get_Struct(self, exporter, &data_type, data);
45
+ data->exporter = qmlbind_exporter_new((qmlbind_backref)klass, rb_string_value_cstr(&name), rbqml_get_interface());
46
+
47
+ return self;
48
+ }
49
+
50
+ static VALUE exporter_add_method(VALUE self, VALUE name, VALUE arity) {
51
+ qmlbind_exporter exporter = rbqml_get_exporter(self);
52
+ qmlbind_exporter_add_method(exporter, rb_id2name(SYM2ID(name)), NUM2INT(arity));
53
+ return Qnil;
54
+ }
55
+
56
+ static VALUE exporter_add_signal(VALUE self, VALUE name, VALUE params) {
57
+ qmlbind_exporter exporter = rbqml_get_exporter(self);
58
+
59
+ int arity = RARRAY_LEN(params);
60
+
61
+ const char **paramStrs = alloca(arity * sizeof(char *));
62
+ for (int i = 0; i < arity; ++i) {
63
+ paramStrs[i] = rb_id2name(SYM2ID(RARRAY_AREF(params, i)));
64
+ }
65
+
66
+ qmlbind_exporter_add_signal(exporter, rb_id2name(SYM2ID(name)), arity, paramStrs);
67
+ return Qnil;
68
+ }
69
+
70
+ static VALUE exporter_add_property(VALUE self, VALUE name, VALUE notifier) {
71
+ qmlbind_exporter exporter = rbqml_get_exporter(self);
72
+ qmlbind_exporter_add_property(exporter, rb_id2name(SYM2ID(name)), rb_id2name(SYM2ID(notifier)));
73
+ return Qnil;
74
+ }
75
+
76
+ static VALUE exporter_to_metaobject(VALUE self) {
77
+ qmlbind_exporter exporter = rbqml_get_exporter(self);
78
+ qmlbind_metaobject metaobj = qmlbind_metaobject_new(exporter);
79
+ return rbqml_metaobject_new(metaobj);
80
+ }
81
+
82
+ void rbqml_init_exporter() {
83
+ VALUE mQML = rb_define_module("QML");
84
+ rbqml_cExporter = rb_define_class_under(mQML, "Exporter", rb_cObject);
85
+
86
+ rb_define_alloc_func(rbqml_cExporter, &exporter_alloc);
87
+
88
+ rb_define_private_method(rbqml_cExporter, "initialize", exporter_initialize, 2);
89
+ rb_define_method(rbqml_cExporter, "add_method", exporter_add_method, 2);
90
+ rb_define_method(rbqml_cExporter, "add_signal", exporter_add_signal, 2);
91
+ rb_define_method(rbqml_cExporter, "add_property", exporter_add_property, 2);
92
+ rb_define_method(rbqml_cExporter, "to_meta_object", exporter_to_metaobject, 0);
93
+ }
@@ -0,0 +1,7 @@
1
+ #pragma once
2
+
3
+ #include <ruby/ruby.h>
4
+ #include <qmlbind.h>
5
+ #include <stdbool.h>
6
+
7
+ void rbqml_init_exporter();
@@ -1,114 +1,55 @@
1
1
  require 'mkmf'
2
2
  require 'pathname'
3
+ require '../../lib/qml/platform'
3
4
 
4
- class Configurator
5
+ # find qmake
5
6
 
6
- PKGS = %w{Qt5Core Qt5Gui Qt5Widgets Qt5Qml Qt5Quick libffi}
7
- HEADERS = %w{QObject QVariant QApplication QQmlEngine QQmlComponent QQmlContext ffi.h}
8
- CLASSES = %w{listmodel}
7
+ qmake = with_config('qmake') || find_executable('qmake')
8
+ debug_enabled = enable_config('debug')
9
+ clean_enabled = enable_config('clean')
10
+ qmake_opts = debug_enabled ? 'CONFIG+=debug' : ''
9
11
 
10
- def initialize
11
- find_dependencies
12
- @cppflags = []
13
- @ldflags = []
14
- @debug_enabled = enable_config('debug')
15
- end
12
+ # build libqmlbind
16
13
 
17
- def find_dependencies
18
- @pkgconfig = with_config('pkg-config') || find_executable('pkg-config')
19
- abort 'pkg-config executable not found' unless @pkgconfig
14
+ qmlbind_dir = Pathname.pwd + 'lib/libqmlbind/qmlbind'
20
15
 
21
- @qt_path = with_config('qt-dir')
22
- @qt_path &&= Pathname(@qt_path).realpath
23
-
24
- @ffi_path = with_config('libffi-dir')
25
- @ffi_path &&= Pathname(@ffi_path).realpath
26
-
27
- [@qt_path, @ffi_path].compact.each do |path|
28
- ENV['PKG_CONFIG_PATH'] = "#{path + 'lib/pkgconfig'}:#{ENV['PKG_CONFIG_PATH']}"
29
- end
30
-
31
- @qmake = @qt_path ? @qt_path + 'bin/qmake' : find_executable('qmake')
32
- @moc = @qt_path ? @qt_path + 'bin/moc' : find_executable('moc')
33
- abort 'qmake executable not found' unless @qmake
34
- abort 'moc executable not found' unless @moc
35
- end
36
-
37
- def build_plugins
38
- puts "building plugins..."
39
- qmake_opts = @debug_enabled ? 'CONFIG+=debug' : ''
40
- Pathname(__FILE__).+("../plugins").children.select(&:directory?).each do |dir|
41
- Dir.chdir(dir) do
42
- system("#{@qmake} #{qmake_opts}") or abort "failed to configurate plugin: #{dir.basename}"
43
- system('make clean') if enable_config('clean-plugin', false)
44
- system('make') or abort "failed to build plugin: #{dir.basename}"
45
- end
46
- end
47
- end
48
-
49
- def configure_extension
50
- RbConfig::CONFIG['CPP'].gsub!(RbConfig::CONFIG['CC'], RbConfig::CONFIG['CXX'])
51
-
52
- PKGS.each do |mod|
53
- @cppflags << `#{@pkgconfig} --cflags #{mod}`.chomp
54
-
55
- libs =`#{@pkgconfig} --libs #{mod}`.chomp
56
- @ldflags << libs
57
-
58
- # add framework search path to cppflags
59
- libs.split.each do |lib|
60
- @cppflags << lib if /^-F/ =~ lib
61
- end
62
- end
16
+ Dir.chdir(qmlbind_dir) do
17
+ puts " >>> building libqmlbind..."
18
+ system "#{qmake} #{qmake_opts}"
19
+ system "make clean" if clean_enabled
20
+ system "make -j4" or abort "ERROR: Failed to build libqmlbind"
21
+ end
63
22
 
64
- # add private header directory of QtCore
65
- qtversion = `#{@pkgconfig} --modversion Qt5Core`.chomp
66
- `#{@pkgconfig} --cflags-only-I Qt5Core`.split.map { |i| Pathname(i.gsub("-I", "")) }.each do |dir|
67
- private_dir = dir + "#{qtversion}/QtCore"
68
- @cppflags << "-I#{private_dir}" if private_dir.exist?
69
- end
23
+ case
24
+ when QML::Platform.mac?
25
+ lib_path = qmlbind_dir + 'libqmlbind.dylib'
26
+ system "install_name_tool -id #{lib_path} #{lib_path}"
27
+ when QML::Platform.windows?
28
+ # TODO
29
+ else
30
+ $LDFLAGS << " -Wl,-rpath #{qmlbind_dir}"
31
+ end
70
32
 
71
- # include framework headers in Mac
72
- # (Qt official installer for Mac does not install header files in /include directory)
73
- if /darwin/ =~ RUBY_PLATFORM
74
- PKGS.map { |pkg| pkg.gsub(/^Qt5/, 'Qt') }.each do |framework|
75
- @cppflags << "-I#{@qt_path + "lib/#{framework}.framework/Headers"}"
76
- end
77
- # add private header directory of QtCore
78
- @cppflags << "-I#{@qt_path}/lib/QtCore.framework/Headers/#{qtversion}/QtCore"
79
- end
33
+ # build plugin
80
34
 
81
- $CPPFLAGS += " #{@cppflags.join(" ")}"
82
- $LDFLAGS += " #{@ldflags.join(" ")}"
83
- $CPPFLAGS += " -fPIC"
35
+ Dir.chdir "rubyqml-plugin" do
36
+ puts " >>> building rubyqml-plugin..."
37
+ system "#{qmake} #{qmake_opts}"
38
+ system "make clean" if clean_enabled
39
+ system "make -j4" or abort "ERROR: Failed to build plugin"
40
+ end
84
41
 
85
- HEADERS.each do |h|
86
- abort "header not found: #{h}" unless have_header(h)
87
- end
42
+ puts " >>> configuring..."
88
43
 
89
- unless have_func('rb_thread_call_with_gvl') && have_func('rb_thread_call_without_gvl')
90
- abort "rb_thread_call_with_gvl and rb_thread_call_without_gvl not found"
91
- end
92
- $CPPFLAGS += " -DHAVE_RUBY_THREAD_H" if have_header('ruby/thread.h')
44
+ # create makefile
93
45
 
94
- have_func('rb_rational_num')
95
- have_func('rb_rational_den')
46
+ $LDFLAGS << " -L#{qmlbind_dir} -lqmlbind"
47
+ $CPPFLAGS << " -I#{qmlbind_dir + 'include'}"
96
48
 
97
- $CPPFLAGS += " -std=c++11 -Wall -Wextra -pipe -Wno-reserved-user-defined-literal"
98
- if @debug_enabled
99
- $CPPFLAGS += " -O0 -ggdb3"
100
- else
101
- $CPPFLAGS += " -O3"
102
- end
49
+ $CPPFLAGS << " -g" if debug_enabled
103
50
 
104
- CLASSES.each do |header|
105
- File.write("moc_#{header}.cpp", `#{@moc} #{header}.h`)
106
- end
51
+ $CPPFLAGS << " -std=c99"
107
52
 
108
- create_makefile 'qml/qml'
109
- end
110
- end
53
+ # create makefile
111
54
 
112
- configurator = Configurator.new
113
- configurator.build_plugins
114
- configurator.configure_extension
55
+ create_makefile 'qml/qml'
@@ -0,0 +1,156 @@
1
+ #include "engine.h"
2
+ #include "conversion.h"
3
+ #include "signal_emitter.h"
4
+ #include "interface.h"
5
+
6
+ VALUE rbqml_mInterface;
7
+ static qmlbind_interface interface;
8
+ static VALUE referenced_objects;
9
+
10
+ qmlbind_interface rbqml_get_interface(void) {
11
+ return interface;
12
+ }
13
+
14
+ typedef struct {
15
+ qmlbind_backref class_handle;
16
+ qmlbind_signal_emitter emitter;
17
+ } new_object_data;
18
+
19
+ static void *new_object_impl(void *p) {
20
+ new_object_data *data = p;
21
+
22
+ VALUE klass = (VALUE)data->class_handle;
23
+ VALUE obj = rb_funcall(klass, rb_intern("new"), 0);
24
+ VALUE emitterValue = rbqml_signal_emitter_new(data->emitter);
25
+ rb_funcall(obj, rb_intern("set_signal_emitter"), 1, emitterValue);
26
+
27
+ rb_hash_aset(referenced_objects, obj, Qnil);
28
+ return (void *)obj;
29
+ }
30
+
31
+ static qmlbind_backref new_object(qmlbind_backref class_handle, qmlbind_signal_emitter emitter) {
32
+ new_object_data data;
33
+ data.class_handle = class_handle;
34
+ data.emitter = emitter;
35
+
36
+ return rb_thread_call_with_gvl(&new_object_impl, &data);
37
+ }
38
+
39
+ static void *delete_object_impl(void *data) {
40
+ rb_hash_delete(referenced_objects, (VALUE)data);
41
+ return NULL;
42
+ }
43
+
44
+ static void delete_object(qmlbind_backref handle) {
45
+ rb_thread_call_with_gvl(&delete_object_impl, handle);
46
+ }
47
+
48
+ typedef struct {
49
+ qmlbind_backref backref;
50
+ const char *name;
51
+ int argc;
52
+ qmlbind_value *argv;
53
+ } call_method_data;
54
+
55
+ static void *call_method_impl(void *p) {
56
+ call_method_data *data = p;
57
+
58
+ VALUE obj = (VALUE)data->backref;
59
+ VALUE method = ID2SYM(rb_intern(data->name));
60
+
61
+ VALUE *args = alloca(data->argc * sizeof(VALUE));
62
+ for (int i = 0; i < data->argc; ++i) {
63
+ args[i] = rbqml_to_ruby(data->argv[i]);
64
+ }
65
+
66
+ VALUE result = rb_funcall(rbqml_mInterface, rb_intern("call_method"), 3,
67
+ obj, method, rb_ary_new_from_values(data->argc, args));
68
+
69
+ return rbqml_to_qml(result);
70
+ }
71
+
72
+ static qmlbind_value call_method(
73
+ qmlbind_engine engine,
74
+ qmlbind_backref object_backref, const char *name,
75
+ int argc, qmlbind_value *argv) {
76
+
77
+ call_method_data data;
78
+ data.backref = object_backref;
79
+ data.name = name;
80
+ data.argc = argc;
81
+ data.argv = argv;
82
+
83
+ return rb_thread_call_with_gvl(&call_method_impl, &data);
84
+ }
85
+
86
+ typedef struct {
87
+ qmlbind_backref backref;
88
+ const char *name;
89
+ } get_property_data;
90
+
91
+ static void *get_property_impl(void *p) {
92
+ get_property_data *data = p;
93
+
94
+ VALUE obj = (VALUE)data->backref;
95
+ VALUE method = ID2SYM(rb_intern(data->name));
96
+
97
+ VALUE result = rb_funcall(rbqml_mInterface, rb_intern("call_method"), 3,
98
+ obj, method, rb_ary_new());
99
+
100
+ return rbqml_to_qml(result);
101
+ }
102
+
103
+ static qmlbind_value get_property(
104
+ qmlbind_engine engine,
105
+ qmlbind_backref object_backref, const char *name) {
106
+
107
+ get_property_data data;
108
+ data.backref = object_backref;
109
+ data.name = name;
110
+
111
+ return rb_thread_call_with_gvl(&get_property_impl, &data);
112
+ }
113
+
114
+ typedef struct {
115
+ qmlbind_backref backref;
116
+ const char *name;
117
+ qmlbind_value value;
118
+ } set_property_data;
119
+
120
+ static void *set_property_impl(void *p) {
121
+ set_property_data* data = p;
122
+
123
+ VALUE obj = (VALUE)data->backref;
124
+ VALUE method = rb_str_intern(rb_sprintf("%s=", data->name));
125
+
126
+ VALUE ruby_value = rbqml_to_ruby(data->value);
127
+
128
+ rb_funcall(rbqml_mInterface, rb_intern("call_method"), 3,
129
+ obj, method, rb_ary_new_from_args(1, ruby_value));
130
+
131
+ return NULL;
132
+ }
133
+
134
+ static void set_property(
135
+ qmlbind_engine engine,
136
+ qmlbind_backref object_backref, const char *name, qmlbind_value value) {
137
+
138
+ set_property_data data;
139
+ data.backref = object_backref;
140
+ data.name = name;
141
+ data.value = value;
142
+
143
+ rb_thread_call_with_gvl(&set_property_impl, &data);
144
+ }
145
+
146
+ qmlbind_interface_handlers handlers = {
147
+ &new_object, &delete_object, &call_method, &get_property, &set_property
148
+ };
149
+
150
+ void rbqml_init_interface(void) {
151
+ rb_require("qml/interface");
152
+ rbqml_mInterface = rb_path2class("QML::Interface");
153
+ interface = qmlbind_interface_new(handlers);
154
+ referenced_objects = rb_hash_new();
155
+ rb_gc_register_address(&referenced_objects);
156
+ }
@@ -0,0 +1,11 @@
1
+ #ifndef INTERFACE_H
2
+ #define INTERFACE_H
3
+
4
+ #include "qml.h"
5
+
6
+ extern VALUE rbqml_mInterface;
7
+ qmlbind_interface rbqml_get_interface(void);
8
+
9
+ void rbqml_init_interface(void);
10
+
11
+ #endif // INTERFACE_H
@@ -0,0 +1,47 @@
1
+ #include "js_array.h"
2
+ #include "conversion.h"
3
+ #include "engine.h"
4
+
5
+ VALUE rbqml_cJSArray;
6
+
7
+ /*
8
+ * @return [Integer]
9
+ */
10
+ static VALUE js_array_length(VALUE self)
11
+ {
12
+ qmlbind_value array = rbqml_js_object_get(self);
13
+
14
+ qmlbind_value lenValue = qmlbind_value_get_property(array, "length");
15
+ int len = qmlbind_value_get_number(lenValue);
16
+ qmlbind_value_release(lenValue);
17
+
18
+ return INT2NUM(len);
19
+ }
20
+
21
+ static VALUE js_array_each(VALUE self)
22
+ {
23
+ RETURN_SIZED_ENUMERATOR(self, 0, 0, &js_array_length);
24
+
25
+ qmlbind_value array = rbqml_js_object_get(self);
26
+
27
+ qmlbind_value lenValue = qmlbind_value_get_property(array, "length");
28
+ int len = qmlbind_value_get_number(lenValue);
29
+ qmlbind_value_release(lenValue);
30
+
31
+ for (int i = 0; i < len; ++i) {
32
+ qmlbind_value elem = qmlbind_value_get_array_item(array, i);
33
+ VALUE rubyElem = rb_ensure(&rbqml_to_ruby, (VALUE)elem, (VALUE (*)())&qmlbind_value_release, (VALUE)elem);
34
+ rb_yield(rubyElem);
35
+ }
36
+
37
+ return self;
38
+ }
39
+
40
+ void rbqml_init_js_array(void)
41
+ {
42
+ VALUE mQML = rb_define_module("QML");
43
+ rbqml_cJSArray = rb_define_class_under(mQML, "JSArray", rbqml_cJSObject);
44
+
45
+ rb_define_method(rbqml_cJSArray, "length", js_array_length, 0);
46
+ rb_define_method(rbqml_cJSArray, "each", js_array_each, 0);
47
+ }