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.
- checksums.yaml +4 -4
- data/.gitmodules +3 -0
- data/.travis.yml +5 -9
- data/LICENSE.txt +1 -1
- data/README.md +84 -114
- data/changes.md +5 -0
- data/examples/fizzbuzz/fizzbuzz.rb +3 -4
- data/examples/todo_array/todo_array.rb +4 -4
- data/examples/todo_sequel/todo_sequel.rb +7 -7
- data/examples/twitter/twitter.rb +5 -3
- data/ext/qml/application.c +88 -0
- data/ext/qml/application.h +9 -0
- data/ext/qml/component.c +89 -0
- data/ext/qml/component.h +10 -0
- data/ext/qml/conversion.c +60 -0
- data/ext/qml/conversion.h +8 -0
- data/ext/qml/dispatcher.c +31 -0
- data/ext/qml/dispatcher.h +7 -0
- data/ext/qml/engine.c +135 -0
- data/ext/qml/engine.h +10 -0
- data/ext/qml/exporter.c +93 -0
- data/ext/qml/exporter.h +7 -0
- data/ext/qml/extconf.rb +38 -97
- data/ext/qml/interface.c +156 -0
- data/ext/qml/interface.h +11 -0
- data/ext/qml/js_array.c +47 -0
- data/ext/qml/js_array.h +7 -0
- data/ext/qml/js_function.c +109 -0
- data/ext/qml/js_function.h +7 -0
- data/ext/qml/js_object.c +284 -0
- data/ext/qml/js_object.h +19 -0
- data/ext/qml/js_wrapper.c +19 -0
- data/ext/qml/js_wrapper.h +7 -0
- data/ext/qml/lib/libqmlbind/.gitignore +38 -0
- data/ext/qml/lib/libqmlbind/.gitmodules +3 -0
- data/ext/qml/lib/libqmlbind/.travis.yml +14 -0
- data/ext/qml/lib/libqmlbind/LICENSE.txt +22 -0
- data/ext/qml/lib/libqmlbind/libqmlbind.pro +3 -0
- data/ext/qml/lib/libqmlbind/qmlbind/include/qmlbind.h +14 -0
- data/ext/qml/lib/libqmlbind/qmlbind/include/qmlbind/application.h +18 -0
- data/ext/qml/lib/libqmlbind/qmlbind/include/qmlbind/component.h +21 -0
- data/ext/qml/lib/libqmlbind/qmlbind/include/qmlbind/engine.h +34 -0
- data/ext/qml/lib/libqmlbind/qmlbind/include/qmlbind/exporter.h +37 -0
- data/ext/qml/lib/libqmlbind/qmlbind/include/qmlbind/interface.h +16 -0
- data/ext/qml/lib/libqmlbind/qmlbind/include/qmlbind/iterator.h +19 -0
- data/ext/qml/lib/libqmlbind/qmlbind/include/qmlbind/metaobject.h +13 -0
- data/ext/qml/lib/libqmlbind/qmlbind/include/qmlbind/plugin.h +17 -0
- data/ext/qml/lib/libqmlbind/qmlbind/include/qmlbind/qmlbind_global.h +78 -0
- data/ext/qml/lib/libqmlbind/qmlbind/include/qmlbind/register.h +17 -0
- data/ext/qml/lib/libqmlbind/qmlbind/include/qmlbind/signal_emitter.h +15 -0
- data/ext/qml/lib/libqmlbind/qmlbind/include/qmlbind/string.h +15 -0
- data/ext/qml/lib/libqmlbind/qmlbind/include/qmlbind/value.h +100 -0
- data/ext/qml/lib/libqmlbind/qmlbind/qmlbind.pro +62 -0
- data/ext/qml/lib/libqmlbind/qmlbind/src/api_application.cpp +103 -0
- data/ext/qml/lib/libqmlbind/qmlbind/src/api_component.cpp +54 -0
- data/ext/qml/lib/libqmlbind/qmlbind/src/api_engine.cpp +65 -0
- data/ext/qml/lib/libqmlbind/qmlbind/src/api_exporter.cpp +52 -0
- data/ext/qml/lib/libqmlbind/qmlbind/src/api_interface.cpp +19 -0
- data/ext/qml/lib/libqmlbind/qmlbind/src/api_iterator.cpp +32 -0
- data/ext/qml/lib/libqmlbind/qmlbind/src/api_metaobject.cpp +19 -0
- data/ext/qml/lib/libqmlbind/qmlbind/src/api_plugin.cpp +27 -0
- data/ext/qml/lib/libqmlbind/qmlbind/src/api_register.cpp +17 -0
- data/ext/qml/lib/libqmlbind/qmlbind/src/api_signal_emitter.cpp +27 -0
- data/ext/qml/lib/libqmlbind/qmlbind/src/api_string.cpp +22 -0
- data/ext/qml/lib/libqmlbind/qmlbind/src/api_value.cpp +215 -0
- data/ext/qml/lib/libqmlbind/qmlbind/src/backref.cpp +54 -0
- data/ext/qml/lib/libqmlbind/qmlbind/src/backref.h +29 -0
- data/ext/qml/lib/libqmlbind/qmlbind/src/engine.cpp +32 -0
- data/ext/qml/lib/libqmlbind/qmlbind/src/engine.h +27 -0
- data/ext/qml/lib/libqmlbind/qmlbind/src/exporter.cpp +73 -0
- data/ext/qml/lib/libqmlbind/qmlbind/src/exporter.h +46 -0
- data/ext/qml/lib/libqmlbind/qmlbind/src/interface.cpp +75 -0
- data/ext/qml/lib/libqmlbind/qmlbind/src/interface.h +37 -0
- data/ext/qml/lib/libqmlbind/qmlbind/src/metaobject.cpp +101 -0
- data/ext/qml/lib/libqmlbind/qmlbind/src/metaobject.h +29 -0
- data/ext/qml/lib/libqmlbind/qmlbind/src/signalemitter.cpp +33 -0
- data/ext/qml/lib/libqmlbind/qmlbind/src/signalemitter.h +25 -0
- data/ext/qml/lib/libqmlbind/qmlbind/src/ticktimer.cpp +15 -0
- data/ext/qml/lib/libqmlbind/qmlbind/src/ticktimer.h +19 -0
- data/ext/qml/lib/libqmlbind/qmlbind/src/typeregisterer.cpp +112 -0
- data/ext/qml/lib/libqmlbind/qmlbind/src/typeregisterer.h +28 -0
- data/ext/qml/lib/libqmlbind/qmlbind/src/util.h +13 -0
- data/ext/qml/lib/libqmlbind/qmlbind/src/wrapper.cpp +23 -0
- data/ext/qml/lib/libqmlbind/qmlbind/src/wrapper.h +29 -0
- data/ext/qml/lib/libqmlbind/readme.md +14 -0
- data/ext/qml/lib/libqmlbind/test/api.c +1 -0
- data/ext/qml/lib/libqmlbind/test/application_test.cpp +16 -0
- data/ext/qml/lib/libqmlbind/test/component_test.cpp +57 -0
- data/ext/qml/lib/libqmlbind/test/engine_test.cpp +94 -0
- data/ext/qml/lib/libqmlbind/test/exporter_test.cpp +312 -0
- data/ext/qml/lib/libqmlbind/test/fixtures/emptyhandlers.cpp +36 -0
- data/ext/qml/lib/libqmlbind/test/fixtures/emptyhandlers.h +6 -0
- data/ext/qml/lib/libqmlbind/test/fixtures/test.qml +5 -0
- data/ext/qml/lib/libqmlbind/test/fixtures/testmodule/qmldir +2 -0
- data/ext/qml/lib/libqmlbind/test/fixtures/testmodule/test.qml +5 -0
- data/ext/qml/lib/libqmlbind/test/iterator_test.cpp +37 -0
- data/ext/qml/lib/libqmlbind/test/main.cpp +11 -0
- data/ext/qml/lib/libqmlbind/test/plugin_test.cpp +41 -0
- data/ext/qml/lib/libqmlbind/test/test.pro +26 -0
- data/ext/qml/lib/libqmlbind/test/test_helper.h +20 -0
- data/ext/qml/lib/libqmlbind/test/value_test.cpp +252 -0
- data/ext/qml/lib/libqmlbind/testplugin/testplugin.cpp +11 -0
- data/ext/qml/lib/libqmlbind/testplugin/testplugin.h +21 -0
- data/ext/qml/lib/libqmlbind/testplugin/testplugin.json +3 -0
- data/ext/qml/lib/libqmlbind/testplugin/testplugin.pro +21 -0
- data/ext/qml/meta_object.c +81 -0
- data/ext/qml/meta_object.h +8 -0
- data/ext/qml/plugin_loader.c +71 -0
- data/ext/qml/plugin_loader.h +7 -0
- data/ext/qml/qml.c +95 -0
- data/ext/qml/qml.h +10 -0
- data/ext/qml/rubyqml-plugin/listmodel.cpp +102 -0
- data/ext/qml/rubyqml-plugin/listmodel.h +37 -0
- data/ext/qml/rubyqml-plugin/rubyqml-plugin.pro +19 -0
- data/ext/qml/rubyqml-plugin/rubyqmlplugin.cpp +25 -0
- data/ext/qml/rubyqml-plugin/rubyqmlplugin.h +19 -0
- data/ext/qml/signal_emitter.c +71 -0
- data/ext/qml/signal_emitter.h +9 -0
- data/lib/qml.rb +11 -10
- data/lib/qml/access.rb +64 -86
- data/lib/qml/application.rb +20 -71
- data/lib/qml/component.rb +41 -33
- data/lib/qml/core_ext.rb +1 -0
- data/lib/qml/core_ext/to_qml.rb +70 -0
- data/lib/qml/data.rb +1 -0
- data/lib/qml/data/array_model.rb +99 -101
- data/lib/qml/data/list_model.rb +107 -131
- data/lib/qml/data/list_model_access.rb +44 -0
- data/lib/qml/data/query_model.rb +45 -47
- data/lib/qml/dispatcher.rb +5 -13
- data/lib/qml/engine.rb +9 -58
- data/lib/qml/errors.rb +0 -21
- data/lib/qml/interface.rb +21 -0
- data/lib/qml/js_array.rb +8 -0
- data/lib/qml/js_object.rb +69 -0
- data/lib/qml/js_util.rb +18 -0
- data/lib/qml/plugin_loader.rb +1 -13
- data/lib/qml/plugins.rb +3 -17
- data/lib/qml/proc_access.rb +28 -0
- data/lib/qml/qt.rb +21 -3
- data/lib/qml/reactive.rb +147 -8
- data/lib/qml/signal.rb +67 -0
- data/lib/qml/version.rb +1 -1
- data/qml.gemspec +8 -2
- data/spec/qml/access_spec.rb +33 -120
- data/spec/qml/application_spec.rb +11 -24
- data/spec/qml/component_spec.rb +4 -4
- data/spec/qml/data/array_model_spec.rb +2 -2
- data/spec/qml/data/list_model_spec.rb +2 -2
- data/spec/qml/data/query_model_spec.rb +4 -4
- data/spec/qml/engine_spec.rb +23 -21
- data/spec/qml/interface_spec.rb +20 -0
- data/spec/qml/js_array_spec.rb +29 -0
- data/spec/qml/js_function_spec.rb +32 -0
- data/spec/qml/js_object_spec.rb +113 -0
- data/spec/qml/plugin_loader_spec.rb +9 -11
- data/spec/qml/qt_spec.rb +9 -0
- data/spec/qml/reactive_spec.rb +37 -0
- data/spec/qml/signal_connect_spec.rb +27 -0
- data/spec/qml/signal_spec.rb +73 -0
- data/spec/qml/to_qml_spec.rb +76 -0
- data/spec/shared/qml/access_example.rb +21 -0
- data/spec/shared/qml/data/list_model.rb +12 -13
- data/spec/spec_helper.rb +2 -3
- metadata +141 -166
- data/examples/imageprovider/imageprovider.rb +0 -57
- data/examples/imageprovider/main.qml +0 -51
- data/ext/qml/accessclass.cpp +0 -65
- data/ext/qml/accessclass.h +0 -19
- data/ext/qml/accessobject.cpp +0 -30
- data/ext/qml/accessobject.h +0 -22
- data/ext/qml/common.h +0 -18
- data/ext/qml/conversionerror.h +0 -14
- data/ext/qml/ext_accesswrapperfactory.cpp +0 -75
- data/ext/qml/ext_accesswrapperfactory.h +0 -39
- data/ext/qml/ext_anywrapper.cpp +0 -34
- data/ext/qml/ext_anywrapper.h +0 -23
- data/ext/qml/ext_kernel.cpp +0 -81
- data/ext/qml/ext_kernel.h +0 -9
- data/ext/qml/ext_metaobject.cpp +0 -399
- data/ext/qml/ext_metaobject.h +0 -60
- data/ext/qml/ext_pluginloader.cpp +0 -53
- data/ext/qml/ext_pluginloader.h +0 -30
- data/ext/qml/ext_pointer.cpp +0 -132
- data/ext/qml/ext_pointer.h +0 -41
- data/ext/qml/ext_testutil.cpp +0 -40
- data/ext/qml/ext_testutil.h +0 -9
- data/ext/qml/foreignclass.cpp +0 -72
- data/ext/qml/foreignclass.h +0 -88
- data/ext/qml/foreignmetaobject.cpp +0 -345
- data/ext/qml/foreignmetaobject.h +0 -46
- data/ext/qml/foreignobject.cpp +0 -22
- data/ext/qml/foreignobject.h +0 -21
- data/ext/qml/functioninfo.h +0 -16
- data/ext/qml/init.cpp +0 -67
- data/ext/qml/kernel.cpp +0 -39
- data/ext/qml/kernel.h +0 -32
- data/ext/qml/listmodel.cpp +0 -137
- data/ext/qml/listmodel.h +0 -45
- data/ext/qml/markable.h +0 -12
- data/ext/qml/objectdata.cpp +0 -26
- data/ext/qml/objectdata.h +0 -20
- data/ext/qml/objectgc.cpp +0 -69
- data/ext/qml/objectgc.h +0 -28
- data/ext/qml/plugins/core/applicationextension.cpp +0 -29
- data/ext/qml/plugins/core/applicationextension.h +0 -25
- data/ext/qml/plugins/core/componentextension.cpp +0 -41
- data/ext/qml/plugins/core/componentextension.h +0 -28
- data/ext/qml/plugins/core/contextextension.cpp +0 -39
- data/ext/qml/plugins/core/contextextension.h +0 -29
- data/ext/qml/plugins/core/core.pro +0 -29
- data/ext/qml/plugins/core/coreplugin.cpp +0 -87
- data/ext/qml/plugins/core/coreplugin.h +0 -49
- data/ext/qml/plugins/core/engineextension.cpp +0 -43
- data/ext/qml/plugins/core/engineextension.h +0 -31
- data/ext/qml/plugins/core/imageprovider.cpp +0 -38
- data/ext/qml/plugins/core/imageprovider.h +0 -18
- data/ext/qml/plugins/core/imagerequestpromise.cpp +0 -19
- data/ext/qml/plugins/core/imagerequestpromise.h +0 -21
- data/ext/qml/plugins/core/qmlexception.cpp +0 -11
- data/ext/qml/plugins/core/qmlexception.h +0 -17
- data/ext/qml/plugins/testutil/imageprovidertest.cpp +0 -40
- data/ext/qml/plugins/testutil/imageprovidertest.h +0 -17
- data/ext/qml/plugins/testutil/objectlifechecker.cpp +0 -17
- data/ext/qml/plugins/testutil/objectlifechecker.h +0 -24
- data/ext/qml/plugins/testutil/ownershiptest.cpp +0 -26
- data/ext/qml/plugins/testutil/ownershiptest.h +0 -30
- data/ext/qml/plugins/testutil/testobject.cpp +0 -6
- data/ext/qml/plugins/testutil/testobject.h +0 -108
- data/ext/qml/plugins/testutil/testobjectsubclass.cpp +0 -10
- data/ext/qml/plugins/testutil/testobjectsubclass.h +0 -19
- data/ext/qml/plugins/testutil/testutil.pro +0 -22
- data/ext/qml/plugins/testutil/testutilplugin.cpp +0 -55
- data/ext/qml/plugins/testutil/testutilplugin.h +0 -36
- data/ext/qml/qmltyperegisterer.cpp +0 -74
- data/ext/qml/qmltyperegisterer.h +0 -30
- data/ext/qml/rubyclass.cpp +0 -82
- data/ext/qml/rubyclass.h +0 -230
- data/ext/qml/rubyvalue.cpp +0 -656
- data/ext/qml/rubyvalue.h +0 -224
- data/ext/qml/signalforwarder.cpp +0 -64
- data/ext/qml/signalforwarder.h +0 -29
- data/ext/qml/util.cpp +0 -112
- data/ext/qml/util.h +0 -82
- data/ext/qml/valuereference.cpp +0 -50
- data/ext/qml/valuereference.h +0 -22
- data/ext/qml/weakvaluereference.cpp +0 -51
- data/ext/qml/weakvaluereference.h +0 -21
- data/lib/qml/context.rb +0 -71
- data/lib/qml/data/error.rb +0 -5
- data/lib/qml/dispatchable.rb +0 -34
- data/lib/qml/error_converter.rb +0 -16
- data/lib/qml/geometry.rb +0 -3
- data/lib/qml/geometry/point.rb +0 -5
- data/lib/qml/geometry/rectangle.rb +0 -5
- data/lib/qml/geometry/size.rb +0 -5
- data/lib/qml/image_provider.rb +0 -87
- data/lib/qml/init.rb +0 -29
- data/lib/qml/meta_object.rb +0 -20
- data/lib/qml/models.rb +0 -1
- data/lib/qml/qt_classes.rb +0 -9
- data/lib/qml/qt_object_base.rb +0 -233
- data/lib/qml/reactive/bindable.rb +0 -79
- data/lib/qml/reactive/chained_signal.rb +0 -25
- data/lib/qml/reactive/error.rb +0 -5
- data/lib/qml/reactive/object.rb +0 -293
- data/lib/qml/reactive/property.rb +0 -19
- data/lib/qml/reactive/signal.rb +0 -115
- data/lib/qml/reactive/signal_spy.rb +0 -27
- data/lib/qml/reactive/signals/map_signal.rb +0 -21
- data/lib/qml/reactive/signals/merge_signal.rb +0 -21
- data/lib/qml/reactive/signals/select_signal.rb +0 -21
- data/lib/qml/reactive/simple_property.rb +0 -17
- data/lib/qml/reactive/unbound_property.rb +0 -42
- data/lib/qml/reactive/unbound_signal.rb +0 -51
- data/lib/qml/test_util.rb +0 -1
- data/lib/qml/test_util/object_life_checker.rb +0 -17
- data/lib/qml/wrappable.rb +0 -9
- data/spec/qml/context_spec.rb +0 -43
- data/spec/qml/conversion_spec.rb +0 -60
- data/spec/qml/dispatchable_spec.rb +0 -26
- data/spec/qml/dispatcher_spec.rb +0 -71
- data/spec/qml/geometry/point_spec.rb +0 -4
- data/spec/qml/geometry/rectangle_spec.rb +0 -4
- data/spec/qml/geometry/size_spec.rb +0 -4
- data/spec/qml/image_provider_spec.rb +0 -33
- data/spec/qml/qt_object_base_spec.rb +0 -119
- data/spec/qml/reactive/object_spec.rb +0 -249
- data/spec/qml/reactive/property_spec.rb +0 -70
- data/spec/qml/reactive/signal_spec.rb +0 -191
- data/spec/qml/reactive/signal_spy_spec.rb +0 -26
- data/spec/qml/reactive/unbound_property_spec.rb +0 -40
- data/spec/qml/reactive/unbound_signal_spec.rb +0 -70
- data/spec/qml/test_object_spec.rb +0 -186
- data/spec/qml/wrappable_spec.rb +0 -10
- 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
|