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
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
|
+
}
|