qml 0.0.1

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 (170) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +46 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +15 -0
  5. data/.yardopts +4 -0
  6. data/Gemfile +4 -0
  7. data/LICENSE.txt +22 -0
  8. data/README.md +351 -0
  9. data/Rakefile +6 -0
  10. data/examples/assets/fonts/fontawesome-webfont.ttf +0 -0
  11. data/examples/fizzbuzz/fizzbuzz.rb +43 -0
  12. data/examples/fizzbuzz/main.qml +38 -0
  13. data/examples/imageprovider/imageprovider.rb +57 -0
  14. data/examples/imageprovider/main.qml +51 -0
  15. data/examples/todo/main.qml +70 -0
  16. data/examples/todo/todo.rb +36 -0
  17. data/examples/twitter/main.qml +36 -0
  18. data/examples/twitter/twitter.rb +55 -0
  19. data/ext/qml/accessclass.cpp +71 -0
  20. data/ext/qml/accessclass.h +19 -0
  21. data/ext/qml/accessobject.cpp +30 -0
  22. data/ext/qml/accessobject.h +22 -0
  23. data/ext/qml/application.cpp +54 -0
  24. data/ext/qml/application.h +17 -0
  25. data/ext/qml/common.h +18 -0
  26. data/ext/qml/ext_accesssupport.cpp +77 -0
  27. data/ext/qml/ext_accesssupport.h +42 -0
  28. data/ext/qml/ext_gcmarker.cpp +39 -0
  29. data/ext/qml/ext_gcmarker.h +27 -0
  30. data/ext/qml/ext_kernel.cpp +62 -0
  31. data/ext/qml/ext_kernel.h +11 -0
  32. data/ext/qml/ext_metaobject.cpp +410 -0
  33. data/ext/qml/ext_metaobject.h +62 -0
  34. data/ext/qml/ext_pluginloader.cpp +55 -0
  35. data/ext/qml/ext_pluginloader.h +32 -0
  36. data/ext/qml/ext_pointer.cpp +134 -0
  37. data/ext/qml/ext_pointer.h +43 -0
  38. data/ext/qml/ext_testutil.cpp +42 -0
  39. data/ext/qml/ext_testutil.h +11 -0
  40. data/ext/qml/extconf.rb +84 -0
  41. data/ext/qml/foreignclass.cpp +72 -0
  42. data/ext/qml/foreignclass.h +88 -0
  43. data/ext/qml/foreignmetaobject.cpp +345 -0
  44. data/ext/qml/foreignmetaobject.h +46 -0
  45. data/ext/qml/foreignobject.cpp +22 -0
  46. data/ext/qml/foreignobject.h +21 -0
  47. data/ext/qml/functioninfo.h +16 -0
  48. data/ext/qml/init.cpp +69 -0
  49. data/ext/qml/listmodel.cpp +112 -0
  50. data/ext/qml/listmodel.h +43 -0
  51. data/ext/qml/markable.h +12 -0
  52. data/ext/qml/objectdata.cpp +26 -0
  53. data/ext/qml/objectdata.h +20 -0
  54. data/ext/qml/objectgc.cpp +69 -0
  55. data/ext/qml/objectgc.h +28 -0
  56. data/ext/qml/plugins/core/applicationextension.cpp +34 -0
  57. data/ext/qml/plugins/core/applicationextension.h +28 -0
  58. data/ext/qml/plugins/core/componentextension.cpp +41 -0
  59. data/ext/qml/plugins/core/componentextension.h +28 -0
  60. data/ext/qml/plugins/core/contextextension.cpp +39 -0
  61. data/ext/qml/plugins/core/contextextension.h +29 -0
  62. data/ext/qml/plugins/core/core.pro +29 -0
  63. data/ext/qml/plugins/core/coreplugin.cpp +87 -0
  64. data/ext/qml/plugins/core/coreplugin.h +49 -0
  65. data/ext/qml/plugins/core/engineextension.cpp +27 -0
  66. data/ext/qml/plugins/core/engineextension.h +28 -0
  67. data/ext/qml/plugins/core/imageprovider.cpp +38 -0
  68. data/ext/qml/plugins/core/imageprovider.h +18 -0
  69. data/ext/qml/plugins/core/imagerequestpromise.cpp +19 -0
  70. data/ext/qml/plugins/core/imagerequestpromise.h +21 -0
  71. data/ext/qml/plugins/core/qmlexception.cpp +11 -0
  72. data/ext/qml/plugins/core/qmlexception.h +17 -0
  73. data/ext/qml/plugins/testutil/objectlifechecker.cpp +17 -0
  74. data/ext/qml/plugins/testutil/objectlifechecker.h +24 -0
  75. data/ext/qml/plugins/testutil/ownershiptest.cpp +26 -0
  76. data/ext/qml/plugins/testutil/ownershiptest.h +30 -0
  77. data/ext/qml/plugins/testutil/testobject.cpp +6 -0
  78. data/ext/qml/plugins/testutil/testobject.h +108 -0
  79. data/ext/qml/plugins/testutil/testobjectsubclass.cpp +10 -0
  80. data/ext/qml/plugins/testutil/testobjectsubclass.h +19 -0
  81. data/ext/qml/plugins/testutil/testutil.pro +20 -0
  82. data/ext/qml/plugins/testutil/testutilplugin.cpp +47 -0
  83. data/ext/qml/plugins/testutil/testutilplugin.h +32 -0
  84. data/ext/qml/qmltyperegisterer.cpp +74 -0
  85. data/ext/qml/qmltyperegisterer.h +30 -0
  86. data/ext/qml/rubyclass.cpp +94 -0
  87. data/ext/qml/rubyclass.h +234 -0
  88. data/ext/qml/rubyvalue.cpp +690 -0
  89. data/ext/qml/rubyvalue.h +256 -0
  90. data/ext/qml/signalforwarder.cpp +66 -0
  91. data/ext/qml/signalforwarder.h +29 -0
  92. data/ext/qml/util.cpp +120 -0
  93. data/ext/qml/util.h +101 -0
  94. data/ext/qml/valuereference.cpp +50 -0
  95. data/ext/qml/valuereference.h +22 -0
  96. data/ext/qml/weakvaluereference.cpp +27 -0
  97. data/ext/qml/weakvaluereference.h +19 -0
  98. data/lib/qml.rb +41 -0
  99. data/lib/qml/access.rb +137 -0
  100. data/lib/qml/application.rb +139 -0
  101. data/lib/qml/class_builder.rb +126 -0
  102. data/lib/qml/component.rb +53 -0
  103. data/lib/qml/context.rb +71 -0
  104. data/lib/qml/data.rb +2 -0
  105. data/lib/qml/data/array_model.rb +103 -0
  106. data/lib/qml/data/error.rb +5 -0
  107. data/lib/qml/data/list_model.rb +146 -0
  108. data/lib/qml/dispatchable.rb +34 -0
  109. data/lib/qml/dispatcher.rb +61 -0
  110. data/lib/qml/engine.rb +54 -0
  111. data/lib/qml/error_converter.rb +15 -0
  112. data/lib/qml/errors.rb +26 -0
  113. data/lib/qml/geometry.rb +3 -0
  114. data/lib/qml/geometry/point.rb +5 -0
  115. data/lib/qml/geometry/rectangle.rb +5 -0
  116. data/lib/qml/geometry/size.rb +5 -0
  117. data/lib/qml/image_provider.rb +87 -0
  118. data/lib/qml/meta_object.rb +20 -0
  119. data/lib/qml/models.rb +1 -0
  120. data/lib/qml/name_helper.rb +12 -0
  121. data/lib/qml/platform.rb +15 -0
  122. data/lib/qml/plugin_loader.rb +46 -0
  123. data/lib/qml/plugins.rb +26 -0
  124. data/lib/qml/qml.rb +1 -0
  125. data/lib/qml/qt.rb +6 -0
  126. data/lib/qml/qt_classes.rb +9 -0
  127. data/lib/qml/qt_object_base.rb +108 -0
  128. data/lib/qml/reactive.rb +8 -0
  129. data/lib/qml/reactive/bindable.rb +79 -0
  130. data/lib/qml/reactive/chained_signal.rb +25 -0
  131. data/lib/qml/reactive/error.rb +5 -0
  132. data/lib/qml/reactive/object.rb +278 -0
  133. data/lib/qml/reactive/property.rb +19 -0
  134. data/lib/qml/reactive/signal.rb +116 -0
  135. data/lib/qml/reactive/signal_spy.rb +27 -0
  136. data/lib/qml/reactive/signals/map_signal.rb +21 -0
  137. data/lib/qml/reactive/signals/merge_signal.rb +21 -0
  138. data/lib/qml/reactive/signals/select_signal.rb +21 -0
  139. data/lib/qml/reactive/simple_property.rb +17 -0
  140. data/lib/qml/reactive/unbound_property.rb +42 -0
  141. data/lib/qml/reactive/unbound_signal.rb +51 -0
  142. data/lib/qml/root_path.rb +3 -0
  143. data/lib/qml/test_util.rb +1 -0
  144. data/lib/qml/test_util/object_life_checker.rb +17 -0
  145. data/lib/qml/version.rb +3 -0
  146. data/lib/qml/wrappable.rb +9 -0
  147. data/qml.gemspec +28 -0
  148. data/spec/assets/testobj.qml +5 -0
  149. data/spec/qml/.access_spec.rb.swp +0 -0
  150. data/spec/qml/access_spec.rb +162 -0
  151. data/spec/qml/application_spec.rb +43 -0
  152. data/spec/qml/component_spec.rb +44 -0
  153. data/spec/qml/context_spec.rb +43 -0
  154. data/spec/qml/conversion_spec.rb +59 -0
  155. data/spec/qml/data/array_model_spec.rb +215 -0
  156. data/spec/qml/dispatchable_spec.rb +26 -0
  157. data/spec/qml/dispatcher_spec.rb +48 -0
  158. data/spec/qml/geometry/point_spec.rb +4 -0
  159. data/spec/qml/geometry/rectangle_spec.rb +4 -0
  160. data/spec/qml/geometry/size_spec.rb +4 -0
  161. data/spec/qml/plugin_loader_spec.rb +33 -0
  162. data/spec/qml/qt_object_base_spec.rb +119 -0
  163. data/spec/qml/reactive/object_spec.rb +273 -0
  164. data/spec/qml/reactive/property_spec.rb +70 -0
  165. data/spec/qml/reactive/signal_spec.rb +191 -0
  166. data/spec/qml/reactive/signal_spy_spec.rb +26 -0
  167. data/spec/qml/test_object_spec.rb +186 -0
  168. data/spec/qml_spec.rb +7 -0
  169. data/spec/spec_helper.rb +5 -0
  170. metadata +321 -0
@@ -0,0 +1,72 @@
1
+ #include "foreignclass.h"
2
+ #include "foreignobject.h"
3
+ #include <QDebug>
4
+
5
+ namespace RubyQml {
6
+
7
+ ForeignClass::ForeignClass()
8
+ {
9
+ }
10
+
11
+ ForeignClass::~ForeignClass()
12
+ {
13
+ }
14
+
15
+ QList<ForeignClass::Method> ForeignClass::signalMethods() const
16
+ {
17
+ QList<Method> sigs;
18
+ std::copy_if(mMethods.begin(), mMethods.end(), std::back_inserter(sigs), [](const Method &m) {
19
+ return m.type == Method::Type::Signal;
20
+ });
21
+ return sigs;
22
+ }
23
+
24
+ QList<ForeignClass::Method> ForeignClass::nonSignalMethods() const
25
+ {
26
+ QList<Method> sigs;
27
+ std::copy_if(mMethods.begin(), mMethods.end(), std::back_inserter(sigs), [](const Method &m) {
28
+ return m.type != Method::Type::Signal;
29
+ });
30
+ return sigs;
31
+ }
32
+
33
+ QVariant ForeignClass::callMethod(ForeignObject *obj, size_t id, const QVariantList &args)
34
+ {
35
+ Q_UNUSED(obj);
36
+ Q_UNUSED(id);
37
+ Q_UNUSED(args);
38
+ return QVariant();
39
+ }
40
+
41
+ void ForeignClass::setProperty(ForeignObject *obj, size_t id, const QVariant &value)
42
+ {
43
+ Q_UNUSED(obj);
44
+ Q_UNUSED(id);
45
+ Q_UNUSED(value);
46
+ }
47
+
48
+ QVariant ForeignClass::getProperty(ForeignObject *obj, size_t id)
49
+ {
50
+ Q_UNUSED(obj);
51
+ Q_UNUSED(id);
52
+ return QVariant();
53
+ }
54
+
55
+ void ForeignClass::addMethod(const QByteArray &name, std::size_t id, const QList<QByteArray> &params, Method::Access access, Method::Type type)
56
+ {
57
+ Method method = { .name = name, .params = params, .access = access, .type = type, .id = id };
58
+ mMethods << method;
59
+ }
60
+
61
+ void ForeignClass::addSignal(const QByteArray &name, std::size_t id, const QList<QByteArray> &params)
62
+ {
63
+ addMethod(name, id, params, Method::Access::Protected, Method::Type::Signal);
64
+ }
65
+
66
+ void ForeignClass::addProperty(const QByteArray &name, std::size_t getterId, std::size_t setterId, Property::Flags flags, bool hasNotifySignal,std::size_t notifySignalId)
67
+ {
68
+ Property property = { .name = name, .flags = flags, .setterId = setterId, .getterId = getterId, .hasNotifySignal = hasNotifySignal, .notifySignalId = notifySignalId};
69
+ mProperties << property;
70
+ }
71
+
72
+ } // namespace RubyQml
@@ -0,0 +1,88 @@
1
+ #pragma once
2
+
3
+ #include <QVariant>
4
+ #include <QMetaMethod>
5
+ #include <QMetaProperty>
6
+ #include <QFlag>
7
+ #include "common.h"
8
+
9
+ class QByteArray;
10
+
11
+ namespace RubyQml {
12
+
13
+ class ForeignObject;
14
+
15
+ class ForeignClass
16
+ {
17
+ public:
18
+ ForeignClass();
19
+ virtual ~ForeignClass();
20
+
21
+ struct Method
22
+ {
23
+ enum class Access
24
+ {
25
+ Private,
26
+ Protected,
27
+ Public
28
+ };
29
+
30
+ enum class Type
31
+ {
32
+ Method,
33
+ Signal
34
+ };
35
+
36
+ QByteArray name;
37
+ QList<QByteArray> params;
38
+ Access access;
39
+ Type type;
40
+ std::size_t id;
41
+ };
42
+
43
+ struct Property
44
+ {
45
+ enum class Flag
46
+ {
47
+ Readable = 1,
48
+ Writable = 1 << 1,
49
+ Constant = 1 << 2,
50
+ };
51
+ Q_DECLARE_FLAGS(Flags, Flag)
52
+
53
+ QByteArray name;
54
+ Flags flags;
55
+ std::size_t setterId;
56
+ std::size_t getterId;
57
+ bool hasNotifySignal;
58
+ std::size_t notifySignalId;
59
+ };
60
+
61
+ QByteArray className() const { return mClassName; }
62
+ QList<Method> methods() const { return mMethods; }
63
+ QList<Method> signalMethods() const;
64
+ QList<Method> nonSignalMethods() const;
65
+ QList<Property> properties() const { return mProperties; }
66
+
67
+ void setClassName(const QByteArray &name) { mClassName = name; }
68
+ void addMethod(const QByteArray &name, std::size_t id, const QList<QByteArray> &params, Method::Access access = Method::Access::Public, Method::Type type = Method::Type::Method);
69
+ void addSignal(const QByteArray &name, std::size_t id, const QList<QByteArray> &params);
70
+ void addProperty(const QByteArray &name, std::size_t getterId, std::size_t setterId, Property::Flags flags, bool hasNotifySignal = false, std::size_t notifySignalId = 0);
71
+
72
+ virtual QVariant callMethod(ForeignObject *obj, size_t id, const QVariantList &args);
73
+ virtual void setProperty(ForeignObject *obj, size_t id, const QVariant &value);
74
+ virtual QVariant getProperty(ForeignObject *obj, size_t id);
75
+
76
+ protected:
77
+
78
+
79
+ private:
80
+
81
+ QByteArray mClassName;
82
+ QList<Method> mMethods;
83
+ QList<Property> mProperties;
84
+ };
85
+
86
+ Q_DECLARE_OPERATORS_FOR_FLAGS(ForeignClass::Property::Flags)
87
+
88
+ } // namespace RubyQml
@@ -0,0 +1,345 @@
1
+ #include "foreignmetaobject.h"
2
+ #include "foreignclass.h"
3
+ #include "foreignobject.h"
4
+ #include <QQueue>
5
+ #include <QDebug>
6
+ #include <QQmlProperty>
7
+ #include <private/qmetaobject_p.h>
8
+
9
+ namespace RubyQml {
10
+
11
+ class ForeignMetaObject::StringPool
12
+ {
13
+ public:
14
+ int intern(const QByteArray &str) {
15
+ int size = mStrings.size();
16
+ for (int i = 0; i < size; ++i) {
17
+ if (mStrings[i] == str)
18
+ return i;
19
+ }
20
+ mStrings << str;
21
+ return size;
22
+ }
23
+
24
+ QVector<uint8_t> toMetaStringData()
25
+ {
26
+ int count = mStrings.size();
27
+ int size = sizeof(QByteArrayData) * count;
28
+ for (const auto &str : mStrings) {
29
+ size += str.size() + 1;
30
+ }
31
+ QVector<uint8_t> data(size);
32
+ auto arrayDatas = reinterpret_cast<QArrayData *>(data.data());
33
+ auto stringData = reinterpret_cast<char *>(data.data() + sizeof(QByteArrayData) * count);
34
+
35
+ int stringOffset = 0;
36
+
37
+ for (int i = 0; i < count; ++i) {
38
+ const auto &string = mStrings[i];
39
+ auto size = string.size();
40
+
41
+ // write array data
42
+ auto arrayDataOffset = stringOffset + sizeof(QByteArrayData) * (count - i);
43
+ new(arrayDatas + i) QArrayData { Q_REFCOUNT_INITIALIZE_STATIC, size, 0, 0, qptrdiff(arrayDataOffset) };
44
+
45
+ // write string data
46
+ strcpy(stringData + stringOffset, string.data());
47
+ stringOffset += string.size() + 1;
48
+ }
49
+
50
+ return data;
51
+ }
52
+
53
+ private:
54
+ QList<QByteArray> mStrings;
55
+ };
56
+
57
+ ForeignMetaObject::ForeignMetaObject(const SP<ForeignClass> &klass, const SP<ForeignMetaObject> &superMetaObject) :
58
+ mForeignClass(klass),
59
+ mSuperMetaObject(superMetaObject)
60
+ {
61
+ buildData();
62
+
63
+ d.superdata = mSuperMetaObject ? mSuperMetaObject.get() : &QObject::staticMetaObject;
64
+ d.stringdata = reinterpret_cast<const QByteArrayData *>(mStringData.data());
65
+ d.data = mData.data();
66
+ d.static_metacall = nullptr;
67
+ d.relatedMetaObjects = nullptr;
68
+ d.extradata = nullptr;
69
+ }
70
+
71
+ void ForeignMetaObject::emitSignal(ForeignObject *obj, std::size_t id, const QVariantList &args)
72
+ {
73
+ auto metamethod = method(mSignalIndexHash[id] + methodOffset());
74
+ if (metamethod.parameterCount() != args.size()) {
75
+ qWarning() << "wrong number of signal arguments";
76
+ return;
77
+ }
78
+ QVariantList argsToPass = args;
79
+ while (argsToPass.size() < 10) {
80
+ argsToPass << QVariant();
81
+ }
82
+ metamethod.invoke(obj,
83
+ Q_ARG(QVariant, argsToPass[0]),
84
+ Q_ARG(QVariant, argsToPass[1]),
85
+ Q_ARG(QVariant, argsToPass[2]),
86
+ Q_ARG(QVariant, argsToPass[3]),
87
+ Q_ARG(QVariant, argsToPass[4]),
88
+ Q_ARG(QVariant, argsToPass[5]),
89
+ Q_ARG(QVariant, argsToPass[6]),
90
+ Q_ARG(QVariant, argsToPass[7]),
91
+ Q_ARG(QVariant, argsToPass[8]),
92
+ Q_ARG(QVariant, argsToPass[9]));
93
+ }
94
+
95
+ int ForeignMetaObject::dynamicMetaCall(ForeignObject *obj, QMetaObject::Call call, int index, void **argv)
96
+ {
97
+ if (mSuperMetaObject) {
98
+ index = mSuperMetaObject->dynamicMetaCall(obj, call, index, argv);
99
+ } else {
100
+ index = obj->QObject::qt_metacall(call, index, argv);
101
+ }
102
+
103
+ if (index < 0) {
104
+ return index;
105
+ }
106
+
107
+ switch (call) {
108
+ case QMetaObject::InvokeMetaMethod: {
109
+ if (index < mMethodCount) {
110
+ if (index < mSignalCount) {
111
+ QMetaObject::activate(obj, this, index, argv);
112
+ } else {
113
+ QVariantList args;
114
+ std::transform(argv + 1, argv + 1 + mMethodArities[index], std::back_inserter(args), [](void *arg) {
115
+ return *reinterpret_cast<QVariant *>(arg);
116
+ });
117
+ auto result = mForeignClass->callMethod(obj, mMethodIds[index], args);
118
+ if (argv[0]) {
119
+ *static_cast<QVariant *>(argv[0]) = result;
120
+ }
121
+ }
122
+ }
123
+ index -= mMethodCount;
124
+ break;
125
+ }
126
+ case QMetaObject::ReadProperty: {
127
+ if (index < mPropertyCount) {
128
+ auto result = mForeignClass->getProperty(obj, mPropertyGetterIds[index]);
129
+ *static_cast<QVariant *>(argv[0]) = result;
130
+ }
131
+ index -= mPropertyCount;
132
+ break;
133
+ }
134
+ case QMetaObject::WriteProperty: {
135
+ if (index < mPropertyCount) {
136
+ auto variant = *static_cast<QVariant *>(argv[0]);
137
+ mForeignClass->setProperty(obj, mPropertySetterIds[index], variant);
138
+ }
139
+ index -= mPropertyCount;
140
+ break;
141
+ }
142
+ case QMetaObject::ResetProperty:
143
+ case QMetaObject::QueryPropertyDesignable:
144
+ case QMetaObject::QueryPropertyScriptable:
145
+ case QMetaObject::QueryPropertyStored:
146
+ case QMetaObject::QueryPropertyEditable:
147
+ case QMetaObject::QueryPropertyUser: {
148
+ index -= mPropertyCount;
149
+ break;
150
+ }
151
+ case QMetaObject::RegisterPropertyMetaType: {
152
+ if (index < mPropertyCount) {
153
+ *static_cast<int *>(argv[0]) = -1;
154
+ }
155
+ index -= mPropertyCount;
156
+ break;
157
+ }
158
+ default:
159
+ break;
160
+ }
161
+
162
+ return index;
163
+ }
164
+
165
+ void ForeignMetaObject::buildData()
166
+ {
167
+ auto klass = mForeignClass;
168
+ int index = 0;
169
+ mMethodCount = klass->methods().size();
170
+ for (const auto &signal : klass->signalMethods()) {
171
+ mMethodIds << signal.id;
172
+ mMethodArities << signal.params.size();
173
+ mSignalIndexHash[signal.id] = index++;
174
+ }
175
+ mSignalCount = klass->signalMethods().size();
176
+ for (const auto &method : klass->nonSignalMethods()) {
177
+ mMethodIds << method.id;
178
+ mMethodArities << method.params.size();
179
+ }
180
+ mPropertyCount = klass->properties().size();
181
+ for (const auto &property : klass->properties()) {
182
+ mPropertySetterIds << property.setterId;
183
+ mPropertyGetterIds << property.getterId;
184
+ }
185
+
186
+ StringPool stringPool;
187
+ mData = writeMetaData(stringPool);
188
+ mStringData = stringPool.toMetaStringData();
189
+ }
190
+
191
+ QVector<uint> ForeignMetaObject::writeMetaData(StringPool &stringPool)
192
+ {
193
+ auto klass = mForeignClass;
194
+
195
+ int methodDataSize = 0;
196
+
197
+ for (const auto &method : klass->methods()) {
198
+ methodDataSize += 5 + 1 + method.params.size() * 2;
199
+ }
200
+
201
+ QVector<uint> metaData;
202
+
203
+ auto markIndex = [&]() {
204
+ auto index = metaData.size();
205
+ metaData << 0;
206
+ return index;
207
+ };
208
+
209
+ auto writeCurrentPos = [&](int markedIndex) {
210
+ metaData[markedIndex] = metaData.size();
211
+ };
212
+
213
+ // write header //
214
+
215
+ metaData << 7; // revision
216
+ metaData << stringPool.intern(klass->className()); // classname
217
+ metaData << 0 << 0; // classinfo
218
+
219
+ auto methods = klass->methods();
220
+ auto signalMethods = klass->signalMethods();
221
+ auto nonSignalMethods = klass->nonSignalMethods();
222
+
223
+ // methods
224
+ metaData << (methods.size());
225
+ int methodInfoPosIndex = markIndex();
226
+
227
+ auto properties = klass->properties();
228
+
229
+ // properties
230
+ metaData << properties.size();
231
+ int propertyInfoPosIndex = markIndex();
232
+
233
+ metaData << 0 << 0; // enums
234
+ metaData << 0 << 0; // constructors
235
+ metaData << 0; // flags
236
+ metaData << signalMethods.size(); // signal count
237
+
238
+ // write method info //
239
+
240
+ writeCurrentPos(methodInfoPosIndex);
241
+
242
+ QQueue<int> parameterInfoPosIndexes;
243
+
244
+ auto addMethodInfo = [&](const ForeignClass::Method &method) {
245
+ metaData << stringPool.intern(method.name); // name
246
+ metaData << method.params.size(); // argc
247
+ parameterInfoPosIndexes.enqueue(markIndex()); // parameters
248
+ metaData << 2; // tag
249
+ int flags = 0;
250
+ if (method.type == ForeignClass::Method::Type::Signal) {
251
+ flags |= AccessProtected;
252
+ flags |= MethodSignal;
253
+ } else {
254
+ flags |= AccessPublic;
255
+ }
256
+ metaData << flags; // flags
257
+ };
258
+
259
+ for (const auto &signal : signalMethods) {
260
+ addMethodInfo(signal);
261
+ }
262
+ for (const auto &method : nonSignalMethods) {
263
+ addMethodInfo(method);
264
+ }
265
+
266
+ auto addParametersInfo = [&](const ForeignClass::Method &method) {
267
+ writeCurrentPos(parameterInfoPosIndexes.dequeue());
268
+ metaData << QMetaType::QVariant;
269
+ for (int i = 0; i < method.params.size(); ++i) {
270
+ metaData << QMetaType::QVariant;
271
+ }
272
+ for (const auto &param : method.params) {
273
+ metaData << stringPool.intern(param);
274
+ }
275
+ };
276
+
277
+ for (const auto &signal : signalMethods) {
278
+ addParametersInfo(signal);
279
+ }
280
+ for (const auto &method : nonSignalMethods) {
281
+ addParametersInfo(method);
282
+ }
283
+
284
+ // write property info //
285
+
286
+ writeCurrentPos(propertyInfoPosIndex);
287
+
288
+ for (const auto &property : properties) {
289
+ metaData << stringPool.intern(property.name);
290
+ metaData << QMetaType::QVariant;
291
+ int flags = Notify | ResolveEditable | Stored | Scriptable | Designable;
292
+ if (property.flags & ForeignClass::Property::Flag::Writable) {
293
+ flags |= Writable;
294
+ }
295
+ if (property.flags & ForeignClass::Property::Flag::Readable) {
296
+ flags |= Readable;
297
+ }
298
+ if (property.flags & ForeignClass::Property::Flag::Constant) {
299
+ flags |= Constant;
300
+ }
301
+ metaData << flags;
302
+ }
303
+
304
+ for (const auto &property : properties) {
305
+ int signalIndex;
306
+ if (property.hasNotifySignal) {
307
+ signalIndex = mSignalIndexHash[property.notifySignalId];
308
+ } else {
309
+ signalIndex = -1;
310
+ }
311
+ metaData << signalIndex;
312
+ }
313
+
314
+ // end of data //
315
+
316
+ metaData << 0;
317
+
318
+ return metaData;
319
+ }
320
+
321
+ void ForeignMetaObject::dump()
322
+ {
323
+ qDebug() << "-- dumping ForeignClass::MetaObject" << className();
324
+ qDebug() << " -- methods";
325
+ for (int i = 0; i < methodCount(); ++i) {
326
+ auto m = method(i);
327
+ qDebug() << "name:" << m.name();
328
+ qDebug() << "return type:" << QMetaType::typeName(m.returnType());
329
+ qDebug() << "param types:" << m.parameterTypes();
330
+ qDebug() << "param names" << m.parameterNames();
331
+ qDebug() << "method type" << m.methodType();
332
+ qDebug() << "attributes" << m.attributes();
333
+ }
334
+ qDebug() << " -- properties";
335
+ for (int i = 0; i < propertyCount(); ++i) {
336
+ auto p = property(i);
337
+ qDebug() << "name:" << p.name();
338
+ qDebug() << "notify signal:" << p.notifySignal().name();
339
+ qDebug() << "writable" << p.isWritable();
340
+ qDebug() << "readable" << p.isReadable();
341
+ qDebug() << "constant" << p.isConstant();
342
+ }
343
+ }
344
+
345
+ } // namespace RubyQml