qml 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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