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,46 @@
1
+ #pragma once
2
+
3
+ #include "qmlbind/qmlbind_global.h"
4
+ #include "backref.h"
5
+ #include <private/qmetaobjectbuilder_p.h>
6
+ #include <QSharedPointer>
7
+
8
+ namespace QmlBind {
9
+
10
+ class Exporter
11
+ {
12
+ public:
13
+
14
+ struct Method {
15
+ QByteArray name;
16
+ int arity;
17
+ };
18
+
19
+ struct Property {
20
+ QByteArray name;
21
+ };
22
+
23
+ Exporter(const char *className, const Backref &classRef);
24
+
25
+ QMetaMethodBuilder addMethod(const char *name, int arity);
26
+ QMetaMethodBuilder addSignal(const char *name, const QList<QByteArray> &args);
27
+ QMetaPropertyBuilder addProperty(const char *name, const char *notifier);
28
+ QSharedPointer<Interface> interface() const { return mClassRef.interface(); }
29
+
30
+ Backref classRef() const { return mClassRef; }
31
+ const QMetaObjectBuilder &metaObjectBuilder() const { return mBuilder; }
32
+ QHash<int, Method> methodMap() const { return mMethodMap; }
33
+ QHash<int, Property> propertyMap() const { return mPropertyMap; }
34
+ QHash<QByteArray, int> signalIndexMap() const { return mSignalIndexMap; }
35
+
36
+ private:
37
+
38
+ Backref mClassRef;
39
+ QHash<int, Method> mMethodMap;
40
+ QHash<int, Property> mPropertyMap;
41
+ QHash<QByteArray, int> mSignalIndexMap;
42
+
43
+ QMetaObjectBuilder mBuilder;
44
+ };
45
+
46
+ } // namespace QmlBind
@@ -0,0 +1,75 @@
1
+ #include "interface.h"
2
+ #include "backref.h"
3
+ #include "engine.h"
4
+ #include <QDebug>
5
+
6
+ namespace QmlBind {
7
+
8
+ Interface::Interface(qmlbind_interface_handlers handlers) :
9
+ mHandlers(handlers)
10
+ {
11
+ if (!handlers.call_method) {
12
+ qFatal("qmlbind: call_method handler not specified");
13
+ }
14
+ if (!handlers.set_property) {
15
+ qFatal("qmlbind: set_property handler not specified");
16
+ }
17
+ if (!handlers.get_property) {
18
+ qFatal("qmlbind: get_property handler not specified");
19
+ }
20
+ if (!handlers.new_object) {
21
+ qFatal("qmlbind: new_object handler not specified");
22
+ }
23
+ if (!handlers.delete_object) {
24
+ qFatal("qmlbind: delete_object handler not specified");
25
+ }
26
+ }
27
+
28
+ QJSValue Interface::callMethod(QQmlEngine *engine, const Backref &obj, const QByteArray &method, int argc, QJSValue **argv) const
29
+ {
30
+ QScopedPointer<const QJSValue> result(mHandlers.call_method(qobject_cast<Engine *>(engine), obj.backref(), method, argc, argv));
31
+ return *result;
32
+ }
33
+
34
+ QJSValue Interface::getProperty(QQmlEngine *engine, const Backref &obj, const QByteArray &property) const
35
+ {
36
+ QScopedPointer<const QJSValue> result(mHandlers.get_property(qobject_cast<Engine *>(engine), obj.backref(), property));
37
+ return *result;
38
+ }
39
+
40
+ void Interface::setProperty(QQmlEngine *engine, const Backref &obj, const QByteArray &property, const QJSValue &value) const
41
+ {
42
+ QJSValue val = value;
43
+ mHandlers.set_property(qobject_cast<Engine *>(engine), obj.backref(), property, &val);
44
+ }
45
+
46
+ Backref Interface::newObject(const Backref &klass, SignalEmitter *signalEmitter)
47
+ {
48
+ return Backref(mHandlers.new_object(klass.backref(), signalEmitter), sharedFromThis());
49
+ }
50
+
51
+ void Interface::retainObject(qmlbind_backref ref)
52
+ {
53
+ QMutexLocker locker(&mRefCountMutex);
54
+
55
+ if (mRefCount.contains(ref)) {
56
+ ++mRefCount[ref];
57
+ }
58
+ else {
59
+ mRefCount[ref] = 1;
60
+ }
61
+ }
62
+
63
+ void Interface::releaseObject(qmlbind_backref ref)
64
+ {
65
+ QMutexLocker locker(&mRefCountMutex);
66
+
67
+ Q_ASSERT(mRefCount.contains(ref));
68
+ if (--mRefCount[ref] == 0) {
69
+ mHandlers.delete_object(ref);
70
+ mRefCount.remove(ref);
71
+ }
72
+ }
73
+
74
+ }
75
+
@@ -0,0 +1,37 @@
1
+ #pragma once
2
+
3
+ #include "qmlbind/qmlbind_global.h"
4
+ #include <QJSValue>
5
+ #include <QSharedPointer>
6
+ #include <QMutex>
7
+
8
+ class QQmlEngine;
9
+
10
+ namespace QmlBind {
11
+
12
+ class Backref;
13
+
14
+ class Interface : public QEnableSharedFromThis<Interface>
15
+ {
16
+ public:
17
+ Interface(qmlbind_interface_handlers handlers);
18
+
19
+ QJSValue callMethod(QQmlEngine *engine, const Backref &obj, const QByteArray &method, int argc, QJSValue **argv) const;
20
+ QJSValue getProperty(QQmlEngine *engine, const Backref &obj, const QByteArray &property) const;
21
+ void setProperty(QQmlEngine *engine, const Backref &obj, const QByteArray &property, const QJSValue &value) const;
22
+
23
+ Backref newObject(const Backref &klass, SignalEmitter *signalEmitter);
24
+
25
+ private:
26
+
27
+ friend class Backref;
28
+
29
+ void retainObject(qmlbind_backref ref);
30
+ void releaseObject(qmlbind_backref ref);
31
+
32
+ qmlbind_interface_handlers mHandlers;
33
+ QHash<qmlbind_backref, int> mRefCount;
34
+ QMutex mRefCountMutex;
35
+ };
36
+
37
+ } // namespace QmlBind
@@ -0,0 +1,101 @@
1
+ #include "metaobject.h"
2
+ #include "exporter.h"
3
+ #include "interface.h"
4
+ #include "wrapper.h"
5
+ #include <QJSValue>
6
+ #include <QMetaMethod>
7
+ #include <QDebug>
8
+ #include <QQmlEngine>
9
+ #include <QQmlContext>
10
+
11
+ namespace QmlBind {
12
+
13
+ MetaObject::MetaObject(const QSharedPointer<const Exporter> &exporter) :
14
+ mExporter(exporter),
15
+ mPrototype(exporter->metaObjectBuilder().toMetaObject())
16
+ {
17
+ d = mPrototype->d;
18
+ }
19
+
20
+ MetaObject::~MetaObject()
21
+ {
22
+ }
23
+
24
+ int MetaObject::metaCall(QObject *object, Call call, int index, void **argv) const
25
+ {
26
+ index = object->QObject::qt_metacall(call, index ,argv);
27
+ if (index < 0) {
28
+ return index;
29
+ }
30
+
31
+ Backref ref = static_cast<Wrapper *>(object)->backref();
32
+
33
+ QQmlContext *context = QQmlEngine::contextForObject(object);
34
+ QQmlEngine *engine = context ? context->engine() : 0;
35
+
36
+ QSharedPointer<const Exporter> exporter = mExporter;
37
+ QSharedPointer<Interface> interface = ref.interface();
38
+
39
+ switch(call) {
40
+ case QMetaObject::ReadProperty:
41
+ {
42
+ int count = propertyCount() - propertyOffset();
43
+ if (index < count) {
44
+ *static_cast<QJSValue *>(argv[0]) = interface->getProperty(engine, ref, exporter->propertyMap()[index].name);
45
+ }
46
+ index -= count;
47
+ break;
48
+ }
49
+ case QMetaObject::WriteProperty:
50
+ {
51
+ int count = propertyCount() - propertyOffset();
52
+ if (index < count) {
53
+ interface->setProperty(engine, ref, exporter->propertyMap()[index].name, *static_cast<QJSValue *>(argv[0]));
54
+ }
55
+ index -= count;
56
+ break;
57
+ }
58
+ case QMetaObject::InvokeMetaMethod:
59
+ {
60
+ int count = methodCount() - methodOffset();
61
+ if (index < count) {
62
+ if (method(index + methodOffset()).methodType() == QMetaMethod::Signal) {
63
+ QMetaObject::activate(object, this, index, argv);
64
+ }
65
+ else {
66
+ Exporter::Method method = exporter->methodMap()[index];
67
+ *static_cast<QJSValue *>(argv[0]) = interface->callMethod(engine, ref, method.name, method.arity, reinterpret_cast<QJSValue **>(argv + 1));
68
+ }
69
+ }
70
+ index -= count;
71
+ break;
72
+ }
73
+ case QMetaObject::ResetProperty:
74
+ case QMetaObject::QueryPropertyDesignable:
75
+ case QMetaObject::QueryPropertyScriptable:
76
+ case QMetaObject::QueryPropertyStored:
77
+ case QMetaObject::QueryPropertyEditable:
78
+ case QMetaObject::QueryPropertyUser:
79
+ {
80
+ int count = propertyCount() - propertyOffset();
81
+ index -= count;
82
+ break;
83
+ }
84
+ case QMetaObject::RegisterPropertyMetaType:
85
+ {
86
+ int count = propertyCount() - propertyOffset();
87
+
88
+ if (index < count) {
89
+ *static_cast<int *>(argv[0]) = -1;
90
+ }
91
+ index -= count;
92
+ break;
93
+ }
94
+ default:
95
+ break;
96
+ }
97
+
98
+ return index;
99
+ }
100
+
101
+ } // namespace QmlBind
@@ -0,0 +1,29 @@
1
+ #pragma once
2
+
3
+ #include "qmlbind/qmlbind_global.h"
4
+ #include "exporter.h"
5
+ #include <QScopedPointer>
6
+ #include <QSharedPointer>
7
+ #include <private/qobject_p.h>
8
+
9
+ namespace QmlBind {
10
+
11
+ class Exporter;
12
+ class Wrapper;
13
+
14
+ class MetaObject : public QMetaObject
15
+ {
16
+ public:
17
+ MetaObject(const QSharedPointer<const Exporter> &exporter);
18
+ ~MetaObject();
19
+
20
+ QSharedPointer<const Exporter> exporter() const { return mExporter; }
21
+ int metaCall(QObject *object, Call call, int index, void **argv) const;
22
+
23
+ private:
24
+
25
+ QSharedPointer<const Exporter> mExporter;
26
+ QScopedPointer<QMetaObject, QScopedPointerPodDeleter> mPrototype;
27
+ };
28
+
29
+ } // namespace QmlBind
@@ -0,0 +1,33 @@
1
+ #include "signalemitter.h"
2
+ #include "metaobject.h"
3
+ #include "exporter.h"
4
+ #include <QDebug>
5
+
6
+ namespace QmlBind {
7
+
8
+ SignalEmitter::SignalEmitter()
9
+ {
10
+ }
11
+
12
+ void SignalEmitter::emitSignal(const QByteArray &name, int argc, QJSValue **argv)
13
+ {
14
+ QSharedPointer<const MetaObject> metaObj = mWrapper->qmlbindMetaObject();
15
+ int index = metaObj->exporter()->signalIndexMap().value(name, -1);
16
+ if (index == -1) {
17
+ qWarning() << "no such signal found:" << name;
18
+ return;
19
+ }
20
+ int offset = metaObj->methodOffset();
21
+
22
+ QMetaMethod signal = metaObj->method(index + offset);
23
+ if (signal.parameterCount() != argc) {
24
+ qWarning() << "parameter count wrong:" << name;
25
+ return;
26
+ }
27
+ Q_ASSERT(signal.name() == name);
28
+
29
+ QMetaObject::activate(mWrapper, metaObj.data(), index, reinterpret_cast<void **>(argv - 1));
30
+ }
31
+
32
+ } // namespace QmlBind
33
+
@@ -0,0 +1,25 @@
1
+ #pragma once
2
+
3
+ #include <QPointer>
4
+ #include "wrapper.h"
5
+
6
+ class QByteArray;
7
+
8
+ namespace QmlBind {
9
+
10
+ class Wrapper;
11
+
12
+ class SignalEmitter
13
+ {
14
+ public:
15
+ SignalEmitter();
16
+
17
+ void setWrapper(Wrapper *wrapper) { mWrapper = wrapper; }
18
+ Wrapper *wrapper() { return mWrapper; }
19
+ void emitSignal(const QByteArray &name, int argc, QJSValue **argv);
20
+
21
+ private:
22
+ QPointer<Wrapper> mWrapper;
23
+ };
24
+
25
+ } // namespace QmlBind
@@ -0,0 +1,15 @@
1
+ #include "ticktimer.h"
2
+
3
+ TickTimer::TickTimer(Callback *whereCallback, QObject *parent) : QTimer(parent), mWhereCallback(whereCallback)
4
+ {
5
+ setInterval(0);
6
+ setSingleShot(false);
7
+ connect(this, SIGNAL(timeout()), this, SLOT(onTimeout()));
8
+ }
9
+
10
+ void TickTimer::onTimeout()
11
+ {
12
+ if (*mWhereCallback) {
13
+ (*mWhereCallback)();
14
+ }
15
+ }
@@ -0,0 +1,19 @@
1
+ #pragma once
2
+
3
+ #include <QTimer>
4
+
5
+ class TickTimer : public QTimer
6
+ {
7
+ Q_OBJECT
8
+ public:
9
+ typedef void (*Callback)();
10
+
11
+ explicit TickTimer(Callback *whereCallback, QObject *parent = 0);
12
+
13
+ private slots:
14
+ void onTimeout();
15
+
16
+ private:
17
+ Callback *mWhereCallback;
18
+ };
19
+
@@ -0,0 +1,112 @@
1
+ #include "typeregisterer.h"
2
+ #include "metaobject.h"
3
+ #include "wrapper.h"
4
+ #include "interface.h"
5
+ #include "signalemitter.h"
6
+ #include <QVector>
7
+ #include <QtQml>
8
+
9
+ #define MAX_CALLBACK_COUNT 256
10
+
11
+ namespace QmlBind {
12
+
13
+ template <int Index>
14
+ void TypeRegisterer::create(void *memory)
15
+ {
16
+ QSharedPointer<const MetaObject> metaobj = TypeRegisterer::instance().mMetaObjects[Index];
17
+ Backref classRef = metaobj->exporter()->classRef();
18
+ SignalEmitter *emitter = new SignalEmitter();
19
+ Backref ref = classRef.interface()->newObject(classRef, emitter);
20
+
21
+ Wrapper *wrapper = new (memory) Wrapper(metaobj, ref);
22
+ emitter->setWrapper(wrapper);
23
+ }
24
+
25
+ // statically generates callback array
26
+
27
+ template <int Count, int Offset>
28
+ struct TypeRegisterer::CreationCallbacksSetter
29
+ {
30
+ void set(TypeRegisterer *self)
31
+ {
32
+ CreationCallbacksSetter<Count / 2, Offset>().set(self);
33
+ CreationCallbacksSetter<Count - Count / 2, Offset + Count / 2>().set(self);
34
+ }
35
+ };
36
+
37
+ template <int Offset>
38
+ struct TypeRegisterer::CreationCallbacksSetter<1, Offset>
39
+ {
40
+ void set(TypeRegisterer *self)
41
+ {
42
+ self->mCreationCallbacks[Offset] = create<Offset>;
43
+ }
44
+ };
45
+
46
+ TypeRegisterer::TypeRegisterer() :
47
+ mCreationCallbacks(MAX_CALLBACK_COUNT)
48
+ {
49
+ CreationCallbacksSetter<MAX_CALLBACK_COUNT>().set(this);
50
+ }
51
+
52
+ int TypeRegisterer::registerType(const QSharedPointer<const MetaObject> &metaObject, const char *uri, int versionMajor, int versionMinor, const char *qmlName)
53
+ {
54
+ int index = mMetaObjects.size();
55
+ if (MAX_CALLBACK_COUNT <= index) {
56
+ qWarning() << "Cannot register QML types more than" << MAX_CALLBACK_COUNT;
57
+ return false;
58
+ }
59
+ mMetaObjects << metaObject;
60
+
61
+ CreationCallback create = mCreationCallbacks[index];
62
+
63
+ registerType(metaObject, create, uri, versionMajor, versionMinor, qmlName);
64
+
65
+ return true;
66
+ }
67
+
68
+ void TypeRegisterer::registerType(const QSharedPointer<const MetaObject> &metaObject, CreationCallback create, const char *uri, int versionMajor, int versionMinor, const char *qmlName)
69
+ {
70
+ QByteArray className;
71
+ className += metaObject->className();
72
+ className += "*";
73
+
74
+ QByteArray listName;
75
+ listName += "QQmlListProperty<";
76
+ listName += metaObject->className();
77
+ listName += ">";
78
+
79
+ QQmlPrivate::RegisterType type = {
80
+ 0,
81
+ qRegisterNormalizedMetaType<Wrapper *>(className),
82
+ qRegisterNormalizedMetaType<QQmlListProperty<Wrapper> >(listName),
83
+ sizeof(Wrapper), create,
84
+ QString(),
85
+
86
+ uri, versionMajor, versionMinor, qmlName, metaObject.data(),
87
+
88
+ 0, 0,
89
+
90
+ QQmlPrivate::StaticCastSelector<Wrapper,QQmlParserStatus>::cast(),
91
+ QQmlPrivate::StaticCastSelector<Wrapper,QQmlPropertyValueSource>::cast(),
92
+ QQmlPrivate::StaticCastSelector<Wrapper,QQmlPropertyValueInterceptor>::cast(),
93
+
94
+ 0, 0,
95
+
96
+ 0,
97
+ 0
98
+ };
99
+
100
+ QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type);
101
+ }
102
+
103
+ TypeRegisterer &TypeRegisterer::instance()
104
+ {
105
+ static TypeRegisterer *i = 0;
106
+ if (!i) {
107
+ i = new TypeRegisterer();
108
+ }
109
+ return *i;
110
+ }
111
+
112
+ } // namespace QmlBind