qml 0.0.7 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
data/ext/qml/js_array.h
ADDED
@@ -0,0 +1,109 @@
|
|
1
|
+
#include "js_function.h"
|
2
|
+
#include "conversion.h"
|
3
|
+
#include "engine.h"
|
4
|
+
|
5
|
+
VALUE rbqml_cJSFunction;
|
6
|
+
|
7
|
+
typedef enum {
|
8
|
+
CallFunction, CallMethod, CallConstructor
|
9
|
+
} CallType;
|
10
|
+
|
11
|
+
typedef struct {
|
12
|
+
qmlbind_value func;
|
13
|
+
qmlbind_value instance;
|
14
|
+
int argc;
|
15
|
+
qmlbind_value *argv;
|
16
|
+
CallType type;
|
17
|
+
} function_call_data;
|
18
|
+
|
19
|
+
static void *function_call_impl(void *p) {
|
20
|
+
function_call_data *data = p;
|
21
|
+
|
22
|
+
switch (data->type) {
|
23
|
+
case CallFunction:
|
24
|
+
return qmlbind_value_call(data->func, data->argc, data->argv);
|
25
|
+
case CallMethod: {
|
26
|
+
return qmlbind_value_call_with_instance(data->func, data->instance, data->argc, data->argv);
|
27
|
+
}
|
28
|
+
case CallConstructor: {
|
29
|
+
return qmlbind_value_call_constructor(data->func, data->argc, data->argv);
|
30
|
+
}
|
31
|
+
}
|
32
|
+
return NULL;
|
33
|
+
}
|
34
|
+
|
35
|
+
static VALUE function_call(VALUE self, VALUE thisValue, VALUE args, CallType callType) {
|
36
|
+
qmlbind_value func = rbqml_js_object_get(self);
|
37
|
+
|
38
|
+
int argc = RARRAY_LEN(args);
|
39
|
+
qmlbind_value *qmlArgs = malloc(argc * sizeof(qmlbind_value));
|
40
|
+
|
41
|
+
for (int i = 0; i < argc; ++i) {
|
42
|
+
qmlbind_value value = rbqml_to_qml(RARRAY_AREF(args, i));
|
43
|
+
qmlArgs[i] = value;
|
44
|
+
}
|
45
|
+
|
46
|
+
function_call_data data;
|
47
|
+
data.func = func;
|
48
|
+
if (callType == CallMethod) {
|
49
|
+
data.instance = rbqml_js_object_get(thisValue);
|
50
|
+
}
|
51
|
+
data.argc = argc;
|
52
|
+
data.argv = qmlArgs;
|
53
|
+
data.type = callType;
|
54
|
+
|
55
|
+
qmlbind_value result = rb_thread_call_without_gvl(&function_call_impl, &data, RUBY_UBF_IO, NULL);
|
56
|
+
|
57
|
+
bool is_error = qmlbind_value_is_error(result);
|
58
|
+
VALUE resultValue = rbqml_to_ruby(result);
|
59
|
+
qmlbind_value_release(result);
|
60
|
+
qmlbind_value_release(func);
|
61
|
+
|
62
|
+
if (is_error) {
|
63
|
+
rb_exc_raise(rb_funcall(resultValue, rb_intern("to_error"), 0));
|
64
|
+
}
|
65
|
+
return resultValue;
|
66
|
+
}
|
67
|
+
|
68
|
+
static VALUE js_function_call(int argc, VALUE *argv, VALUE self) {
|
69
|
+
VALUE args;
|
70
|
+
VALUE block;
|
71
|
+
rb_scan_args(argc, argv, "*&", &args, &block);
|
72
|
+
if (!NIL_P(block)) {
|
73
|
+
args = rb_ary_concat(args, rb_ary_new_from_args(1, block));
|
74
|
+
}
|
75
|
+
|
76
|
+
return function_call(self, Qnil, args, CallFunction);
|
77
|
+
}
|
78
|
+
|
79
|
+
static VALUE js_function_new(int argc, VALUE *argv, VALUE self) {
|
80
|
+
VALUE args;
|
81
|
+
VALUE block;
|
82
|
+
rb_scan_args(argc, argv, "*&", &args, &block);
|
83
|
+
if (!NIL_P(block)) {
|
84
|
+
args = rb_ary_concat(args, rb_ary_new_from_args(1, block));
|
85
|
+
}
|
86
|
+
|
87
|
+
return function_call(self, Qnil, args, CallConstructor);
|
88
|
+
}
|
89
|
+
|
90
|
+
static VALUE js_function_call_with_instance(int argc, VALUE *argv, VALUE self) {
|
91
|
+
VALUE thisValue;
|
92
|
+
VALUE args;
|
93
|
+
VALUE block;
|
94
|
+
rb_scan_args(argc, argv, "1*&", &thisValue, &args, &block);
|
95
|
+
if (!NIL_P(block)) {
|
96
|
+
args = rb_ary_concat(args, rb_ary_new_from_args(1, block));
|
97
|
+
}
|
98
|
+
|
99
|
+
return function_call(self, thisValue, args, CallMethod);
|
100
|
+
}
|
101
|
+
|
102
|
+
void rbqml_init_js_function(void) {
|
103
|
+
VALUE mQML = rb_define_module("QML");
|
104
|
+
rbqml_cJSFunction = rb_define_class_under(mQML, "JSFunction", rbqml_cJSObject);
|
105
|
+
|
106
|
+
rb_define_method(rbqml_cJSFunction, "call", js_function_call, -1);
|
107
|
+
rb_define_method(rbqml_cJSFunction, "new", js_function_new, -1);
|
108
|
+
rb_define_method(rbqml_cJSFunction, "call_with_instance", js_function_call_with_instance, -1);
|
109
|
+
}
|
data/ext/qml/js_object.c
ADDED
@@ -0,0 +1,284 @@
|
|
1
|
+
#include "js_object.h"
|
2
|
+
#include "engine.h"
|
3
|
+
#include "conversion.h"
|
4
|
+
|
5
|
+
typedef struct {
|
6
|
+
qmlbind_value obj;
|
7
|
+
const char *key;
|
8
|
+
} get_property_data;
|
9
|
+
|
10
|
+
void *get_property_impl(void *p) {
|
11
|
+
get_property_data *data = p;
|
12
|
+
return qmlbind_value_get_property(data->obj, data->key);
|
13
|
+
}
|
14
|
+
|
15
|
+
qmlbind_value rbqml_get_property(qmlbind_value obj, const char *key) {
|
16
|
+
get_property_data data;
|
17
|
+
data.obj = obj;
|
18
|
+
data.key = key;
|
19
|
+
return rb_thread_call_without_gvl(&get_property_impl, &data, RUBY_UBF_IO, NULL);
|
20
|
+
}
|
21
|
+
|
22
|
+
typedef struct {
|
23
|
+
qmlbind_value obj;
|
24
|
+
int index;
|
25
|
+
} get_array_item_data;
|
26
|
+
|
27
|
+
void *get_array_item_impl(void *p) {
|
28
|
+
get_array_item_data *data = p;
|
29
|
+
return qmlbind_value_get_array_item(data->obj, data->index);
|
30
|
+
}
|
31
|
+
|
32
|
+
qmlbind_value rbqml_get_array_item(qmlbind_value obj, int index) {
|
33
|
+
get_array_item_data data;
|
34
|
+
data.obj = obj;
|
35
|
+
data.index = index;
|
36
|
+
return rb_thread_call_without_gvl(&get_array_item_impl, &data, RUBY_UBF_IO, NULL);
|
37
|
+
}
|
38
|
+
|
39
|
+
typedef struct {
|
40
|
+
qmlbind_value obj;
|
41
|
+
const char *key;
|
42
|
+
qmlbind_value value;
|
43
|
+
} set_property_data;
|
44
|
+
|
45
|
+
void *set_property_impl(void *p) {
|
46
|
+
set_property_data *data = p;
|
47
|
+
qmlbind_value_set_property(data->obj, data->key, data->value);
|
48
|
+
return NULL;
|
49
|
+
}
|
50
|
+
|
51
|
+
void rbqml_set_property(qmlbind_value obj, const char *key, qmlbind_value value) {
|
52
|
+
set_property_data data;
|
53
|
+
data.obj = obj;
|
54
|
+
data.key = key;
|
55
|
+
data.value = value;
|
56
|
+
rb_thread_call_without_gvl(&set_property_impl, &data, RUBY_UBF_IO, NULL);
|
57
|
+
}
|
58
|
+
|
59
|
+
typedef struct {
|
60
|
+
qmlbind_value obj;
|
61
|
+
int index;
|
62
|
+
qmlbind_value value;
|
63
|
+
} set_array_item_data;
|
64
|
+
|
65
|
+
void *set_array_item_impl(void *p) {
|
66
|
+
set_array_item_data *data = p;
|
67
|
+
qmlbind_value_set_array_item(data->obj, data->index, data->value);
|
68
|
+
return NULL;
|
69
|
+
}
|
70
|
+
|
71
|
+
void rbqml_set_array_item(qmlbind_value obj, int index, qmlbind_value value) {
|
72
|
+
set_array_item_data data;
|
73
|
+
data.obj = obj;
|
74
|
+
data.index = index;
|
75
|
+
data.value = value;
|
76
|
+
rb_thread_call_without_gvl(&set_array_item_impl, &data, RUBY_UBF_IO, NULL);
|
77
|
+
}
|
78
|
+
|
79
|
+
|
80
|
+
qmlbind_value rbqml_get_iterator_value(qmlbind_iterator iter) {
|
81
|
+
return rb_thread_call_without_gvl((void *(*)(void *))&qmlbind_iterator_get_value, iter, RUBY_UBF_IO, NULL);
|
82
|
+
}
|
83
|
+
|
84
|
+
typedef struct {
|
85
|
+
qmlbind_value value;
|
86
|
+
} js_object_t;
|
87
|
+
|
88
|
+
VALUE rbqml_cJSObject;
|
89
|
+
|
90
|
+
void free_js_object(void *ptr)
|
91
|
+
{
|
92
|
+
js_object_t *obj = ptr;
|
93
|
+
qmlbind_value_release(obj->value);
|
94
|
+
xfree(obj);
|
95
|
+
}
|
96
|
+
|
97
|
+
static const rb_data_type_t data_type = {
|
98
|
+
"QML::JSObject",
|
99
|
+
{ NULL, &free_js_object }
|
100
|
+
};
|
101
|
+
|
102
|
+
static VALUE js_object_alloc(VALUE klass)
|
103
|
+
{
|
104
|
+
return rbqml_js_object_new(klass, qmlbind_value_new_null());
|
105
|
+
}
|
106
|
+
|
107
|
+
VALUE rbqml_js_object_new(VALUE klass, qmlbind_value value)
|
108
|
+
{
|
109
|
+
js_object_t *obj = ALLOC(js_object_t);
|
110
|
+
obj->value = qmlbind_value_clone(value);
|
111
|
+
return TypedData_Wrap_Struct(klass, &data_type, obj);
|
112
|
+
}
|
113
|
+
|
114
|
+
bool rbqml_js_object_p(VALUE value)
|
115
|
+
{
|
116
|
+
return rb_type(value) == T_DATA && RTYPEDDATA_P(value) && RTYPEDDATA_TYPE(value) == &data_type;
|
117
|
+
}
|
118
|
+
|
119
|
+
qmlbind_value rbqml_js_object_get(VALUE jsobject)
|
120
|
+
{
|
121
|
+
js_object_t *obj;
|
122
|
+
TypedData_Get_Struct(jsobject, js_object_t, &data_type, obj);
|
123
|
+
return qmlbind_value_clone(obj->value);
|
124
|
+
}
|
125
|
+
|
126
|
+
static void get_property_key(VALUE key, int *index, const char **keyStr)
|
127
|
+
{
|
128
|
+
switch (rb_type(key)) {
|
129
|
+
case T_FIXNUM:
|
130
|
+
*index = NUM2INT(key);
|
131
|
+
break;
|
132
|
+
case T_STRING:
|
133
|
+
*keyStr = rb_string_value_cstr(&key);
|
134
|
+
break;
|
135
|
+
case T_SYMBOL:
|
136
|
+
*keyStr = rb_id2name(SYM2ID(key));
|
137
|
+
break;
|
138
|
+
default:
|
139
|
+
rb_raise(rb_eTypeError, "expected Fixnum, String or Symbol for index, got %s", rb_class2name(rb_obj_class(key)));
|
140
|
+
break;
|
141
|
+
}
|
142
|
+
}
|
143
|
+
|
144
|
+
static VALUE js_object_aref(VALUE self, VALUE key)
|
145
|
+
{
|
146
|
+
qmlbind_value obj = rbqml_js_object_get(self);
|
147
|
+
|
148
|
+
int index = -1;
|
149
|
+
const char *keyStr;
|
150
|
+
get_property_key(key, &index, &keyStr);
|
151
|
+
|
152
|
+
qmlbind_value value;
|
153
|
+
|
154
|
+
if (index >= 0) {
|
155
|
+
value = rbqml_get_array_item(obj, index);
|
156
|
+
} else {
|
157
|
+
value = rbqml_get_property(obj, keyStr);
|
158
|
+
}
|
159
|
+
|
160
|
+
qmlbind_value_release(obj);
|
161
|
+
|
162
|
+
return rb_ensure(&rbqml_to_ruby, (VALUE)value, (VALUE (*)())&qmlbind_value_release, (VALUE)value);
|
163
|
+
}
|
164
|
+
|
165
|
+
static VALUE js_object_aset(VALUE self, VALUE key, VALUE value)
|
166
|
+
{
|
167
|
+
qmlbind_value obj = rbqml_js_object_get(self);
|
168
|
+
|
169
|
+
qmlbind_value qmlValue = rbqml_to_qml(value);
|
170
|
+
|
171
|
+
int index = -1;
|
172
|
+
const char *keyStr;
|
173
|
+
|
174
|
+
get_property_key(key, &index, &keyStr);
|
175
|
+
|
176
|
+
if (index >= 0) {
|
177
|
+
rbqml_set_array_item(obj, index, qmlValue);
|
178
|
+
} else {
|
179
|
+
rbqml_set_property(obj, keyStr, qmlValue);
|
180
|
+
}
|
181
|
+
|
182
|
+
qmlbind_value_release(obj);
|
183
|
+
|
184
|
+
return value;
|
185
|
+
}
|
186
|
+
|
187
|
+
static VALUE js_object_each_iterator(VALUE data)
|
188
|
+
{
|
189
|
+
qmlbind_iterator it = (qmlbind_iterator)data;
|
190
|
+
while (qmlbind_iterator_has_next(it)) {
|
191
|
+
qmlbind_iterator_next(it);
|
192
|
+
|
193
|
+
qmlbind_value value = rbqml_get_iterator_value(it);
|
194
|
+
VALUE rubyValue = rb_ensure(&rbqml_to_ruby, (VALUE)value, (VALUE (*)())&qmlbind_value_release, (VALUE)value);
|
195
|
+
|
196
|
+
qmlbind_string str = qmlbind_iterator_get_key(it);
|
197
|
+
VALUE rubyKey = rb_enc_str_new(qmlbind_string_get_chars(str), qmlbind_string_get_length(str), rb_utf8_encoding());
|
198
|
+
qmlbind_string_release(str);
|
199
|
+
|
200
|
+
VALUE pair[] = { rubyKey, rubyValue };
|
201
|
+
|
202
|
+
rb_yield(rb_ary_new_from_values(2, pair));
|
203
|
+
}
|
204
|
+
return Qnil;
|
205
|
+
}
|
206
|
+
|
207
|
+
static VALUE js_object_each_pair(VALUE self)
|
208
|
+
{
|
209
|
+
RETURN_ENUMERATOR(self, 0, 0);
|
210
|
+
|
211
|
+
qmlbind_value obj = rbqml_js_object_get(self);
|
212
|
+
|
213
|
+
qmlbind_iterator it = qmlbind_iterator_new(obj);
|
214
|
+
rb_ensure(&js_object_each_iterator, (VALUE)it, (VALUE (*)())&qmlbind_iterator_release, (VALUE)it);
|
215
|
+
|
216
|
+
qmlbind_value_release(obj);
|
217
|
+
|
218
|
+
return self;
|
219
|
+
}
|
220
|
+
|
221
|
+
static VALUE js_object_has_key_p(VALUE self, VALUE key)
|
222
|
+
{
|
223
|
+
qmlbind_value obj = rbqml_js_object_get(self);
|
224
|
+
|
225
|
+
int index = -1;
|
226
|
+
const char *keyStr;
|
227
|
+
|
228
|
+
get_property_key(key, &index, &keyStr);
|
229
|
+
|
230
|
+
int ret;
|
231
|
+
|
232
|
+
if (index >= 0) {
|
233
|
+
ret = qmlbind_value_has_index(obj, index);
|
234
|
+
} else {
|
235
|
+
ret = qmlbind_value_has_property(obj, keyStr);
|
236
|
+
}
|
237
|
+
|
238
|
+
qmlbind_value_release(obj);
|
239
|
+
|
240
|
+
if (ret) {
|
241
|
+
return Qtrue;
|
242
|
+
} else {
|
243
|
+
return Qfalse;
|
244
|
+
}
|
245
|
+
}
|
246
|
+
|
247
|
+
static VALUE js_object_error_p(VALUE self)
|
248
|
+
{
|
249
|
+
qmlbind_value obj = rbqml_js_object_get(self);
|
250
|
+
if (qmlbind_value_is_error(obj)) {
|
251
|
+
return Qtrue;
|
252
|
+
} else {
|
253
|
+
return Qfalse;
|
254
|
+
}
|
255
|
+
}
|
256
|
+
|
257
|
+
/*
|
258
|
+
* Compares two JS objects by JavaScript identity (===).
|
259
|
+
* @return [Boolean]
|
260
|
+
*/
|
261
|
+
static VALUE js_object_equal_p(VALUE self, VALUE other)
|
262
|
+
{
|
263
|
+
qmlbind_value obj = rbqml_js_object_get(self);
|
264
|
+
qmlbind_value otherObj = rbqml_js_object_get(other);
|
265
|
+
|
266
|
+
if (qmlbind_value_is_identical(obj, otherObj)) {
|
267
|
+
return Qtrue;
|
268
|
+
} else {
|
269
|
+
return Qfalse;
|
270
|
+
}
|
271
|
+
}
|
272
|
+
|
273
|
+
void rbqml_init_js_object(void)
|
274
|
+
{
|
275
|
+
VALUE mQML = rb_define_module("QML");
|
276
|
+
rbqml_cJSObject = rb_define_class_under(mQML, "JSObject", rb_cObject);
|
277
|
+
|
278
|
+
rb_define_method(rbqml_cJSObject, "[]", js_object_aref, 1);
|
279
|
+
rb_define_method(rbqml_cJSObject, "[]=", js_object_aset, 2);
|
280
|
+
rb_define_method(rbqml_cJSObject, "each_pair", js_object_each_pair, 0);
|
281
|
+
rb_define_method(rbqml_cJSObject, "has_key?", js_object_has_key_p, 1);
|
282
|
+
rb_define_method(rbqml_cJSObject, "error?", js_object_error_p, 0);
|
283
|
+
rb_define_method(rbqml_cJSObject, "==", js_object_equal_p, 1);
|
284
|
+
}
|
data/ext/qml/js_object.h
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
#pragma once
|
2
|
+
|
3
|
+
#include "qml.h"
|
4
|
+
#include <stdbool.h>
|
5
|
+
|
6
|
+
qmlbind_value rbqml_get_property(qmlbind_value obj, const char *key);
|
7
|
+
qmlbind_value rbqml_get_array_item(qmlbind_value obj, int index);
|
8
|
+
void rbqml_set_property(qmlbind_value obj, const char *key, qmlbind_value value);
|
9
|
+
void rbqml_set_array_item(qmlbind_value obj, int index, qmlbind_value value);
|
10
|
+
qmlbind_value rbqml_get_iterator_value(qmlbind_iterator iter);
|
11
|
+
|
12
|
+
VALUE rbqml_js_object_new(VALUE klass, qmlbind_value value);
|
13
|
+
|
14
|
+
bool rbqml_js_object_p(VALUE value);
|
15
|
+
qmlbind_value rbqml_js_object_get(VALUE jsobject);
|
16
|
+
|
17
|
+
extern VALUE rbqml_cJSObject;
|
18
|
+
|
19
|
+
void rbqml_init_js_object(void);
|
@@ -0,0 +1,19 @@
|
|
1
|
+
#include "js_wrapper.h"
|
2
|
+
|
3
|
+
VALUE rbqml_cJSWrapper;
|
4
|
+
|
5
|
+
/*
|
6
|
+
* @return [QML::Access]
|
7
|
+
*/
|
8
|
+
static VALUE js_wrapper_unwrap(VALUE self) {
|
9
|
+
qmlbind_value wrapper = rbqml_js_object_get(self);
|
10
|
+
VALUE unwrapped = (VALUE)qmlbind_value_get_backref(wrapper);
|
11
|
+
qmlbind_value_release(wrapper);
|
12
|
+
return unwrapped;
|
13
|
+
}
|
14
|
+
|
15
|
+
void rbqml_init_js_wrapper(void) {
|
16
|
+
VALUE mQML = rb_define_module("QML");
|
17
|
+
rbqml_cJSWrapper = rb_define_class_under(mQML, "JSWrapper", rbqml_cJSObject);
|
18
|
+
rb_define_method(rbqml_cJSWrapper, "unwrap", js_wrapper_unwrap, 0);
|
19
|
+
}
|