qml 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +46 -0
- data/.rspec +2 -0
- data/.travis.yml +15 -0
- data/.yardopts +4 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +351 -0
- data/Rakefile +6 -0
- data/examples/assets/fonts/fontawesome-webfont.ttf +0 -0
- data/examples/fizzbuzz/fizzbuzz.rb +43 -0
- data/examples/fizzbuzz/main.qml +38 -0
- data/examples/imageprovider/imageprovider.rb +57 -0
- data/examples/imageprovider/main.qml +51 -0
- data/examples/todo/main.qml +70 -0
- data/examples/todo/todo.rb +36 -0
- data/examples/twitter/main.qml +36 -0
- data/examples/twitter/twitter.rb +55 -0
- data/ext/qml/accessclass.cpp +71 -0
- data/ext/qml/accessclass.h +19 -0
- data/ext/qml/accessobject.cpp +30 -0
- data/ext/qml/accessobject.h +22 -0
- data/ext/qml/application.cpp +54 -0
- data/ext/qml/application.h +17 -0
- data/ext/qml/common.h +18 -0
- data/ext/qml/ext_accesssupport.cpp +77 -0
- data/ext/qml/ext_accesssupport.h +42 -0
- data/ext/qml/ext_gcmarker.cpp +39 -0
- data/ext/qml/ext_gcmarker.h +27 -0
- data/ext/qml/ext_kernel.cpp +62 -0
- data/ext/qml/ext_kernel.h +11 -0
- data/ext/qml/ext_metaobject.cpp +410 -0
- data/ext/qml/ext_metaobject.h +62 -0
- data/ext/qml/ext_pluginloader.cpp +55 -0
- data/ext/qml/ext_pluginloader.h +32 -0
- data/ext/qml/ext_pointer.cpp +134 -0
- data/ext/qml/ext_pointer.h +43 -0
- data/ext/qml/ext_testutil.cpp +42 -0
- data/ext/qml/ext_testutil.h +11 -0
- data/ext/qml/extconf.rb +84 -0
- data/ext/qml/foreignclass.cpp +72 -0
- data/ext/qml/foreignclass.h +88 -0
- data/ext/qml/foreignmetaobject.cpp +345 -0
- data/ext/qml/foreignmetaobject.h +46 -0
- data/ext/qml/foreignobject.cpp +22 -0
- data/ext/qml/foreignobject.h +21 -0
- data/ext/qml/functioninfo.h +16 -0
- data/ext/qml/init.cpp +69 -0
- data/ext/qml/listmodel.cpp +112 -0
- data/ext/qml/listmodel.h +43 -0
- data/ext/qml/markable.h +12 -0
- data/ext/qml/objectdata.cpp +26 -0
- data/ext/qml/objectdata.h +20 -0
- data/ext/qml/objectgc.cpp +69 -0
- data/ext/qml/objectgc.h +28 -0
- data/ext/qml/plugins/core/applicationextension.cpp +34 -0
- data/ext/qml/plugins/core/applicationextension.h +28 -0
- data/ext/qml/plugins/core/componentextension.cpp +41 -0
- data/ext/qml/plugins/core/componentextension.h +28 -0
- data/ext/qml/plugins/core/contextextension.cpp +39 -0
- data/ext/qml/plugins/core/contextextension.h +29 -0
- data/ext/qml/plugins/core/core.pro +29 -0
- data/ext/qml/plugins/core/coreplugin.cpp +87 -0
- data/ext/qml/plugins/core/coreplugin.h +49 -0
- data/ext/qml/plugins/core/engineextension.cpp +27 -0
- data/ext/qml/plugins/core/engineextension.h +28 -0
- data/ext/qml/plugins/core/imageprovider.cpp +38 -0
- data/ext/qml/plugins/core/imageprovider.h +18 -0
- data/ext/qml/plugins/core/imagerequestpromise.cpp +19 -0
- data/ext/qml/plugins/core/imagerequestpromise.h +21 -0
- data/ext/qml/plugins/core/qmlexception.cpp +11 -0
- data/ext/qml/plugins/core/qmlexception.h +17 -0
- data/ext/qml/plugins/testutil/objectlifechecker.cpp +17 -0
- data/ext/qml/plugins/testutil/objectlifechecker.h +24 -0
- data/ext/qml/plugins/testutil/ownershiptest.cpp +26 -0
- data/ext/qml/plugins/testutil/ownershiptest.h +30 -0
- data/ext/qml/plugins/testutil/testobject.cpp +6 -0
- data/ext/qml/plugins/testutil/testobject.h +108 -0
- data/ext/qml/plugins/testutil/testobjectsubclass.cpp +10 -0
- data/ext/qml/plugins/testutil/testobjectsubclass.h +19 -0
- data/ext/qml/plugins/testutil/testutil.pro +20 -0
- data/ext/qml/plugins/testutil/testutilplugin.cpp +47 -0
- data/ext/qml/plugins/testutil/testutilplugin.h +32 -0
- data/ext/qml/qmltyperegisterer.cpp +74 -0
- data/ext/qml/qmltyperegisterer.h +30 -0
- data/ext/qml/rubyclass.cpp +94 -0
- data/ext/qml/rubyclass.h +234 -0
- data/ext/qml/rubyvalue.cpp +690 -0
- data/ext/qml/rubyvalue.h +256 -0
- data/ext/qml/signalforwarder.cpp +66 -0
- data/ext/qml/signalforwarder.h +29 -0
- data/ext/qml/util.cpp +120 -0
- data/ext/qml/util.h +101 -0
- data/ext/qml/valuereference.cpp +50 -0
- data/ext/qml/valuereference.h +22 -0
- data/ext/qml/weakvaluereference.cpp +27 -0
- data/ext/qml/weakvaluereference.h +19 -0
- data/lib/qml.rb +41 -0
- data/lib/qml/access.rb +137 -0
- data/lib/qml/application.rb +139 -0
- data/lib/qml/class_builder.rb +126 -0
- data/lib/qml/component.rb +53 -0
- data/lib/qml/context.rb +71 -0
- data/lib/qml/data.rb +2 -0
- data/lib/qml/data/array_model.rb +103 -0
- data/lib/qml/data/error.rb +5 -0
- data/lib/qml/data/list_model.rb +146 -0
- data/lib/qml/dispatchable.rb +34 -0
- data/lib/qml/dispatcher.rb +61 -0
- data/lib/qml/engine.rb +54 -0
- data/lib/qml/error_converter.rb +15 -0
- data/lib/qml/errors.rb +26 -0
- data/lib/qml/geometry.rb +3 -0
- data/lib/qml/geometry/point.rb +5 -0
- data/lib/qml/geometry/rectangle.rb +5 -0
- data/lib/qml/geometry/size.rb +5 -0
- data/lib/qml/image_provider.rb +87 -0
- data/lib/qml/meta_object.rb +20 -0
- data/lib/qml/models.rb +1 -0
- data/lib/qml/name_helper.rb +12 -0
- data/lib/qml/platform.rb +15 -0
- data/lib/qml/plugin_loader.rb +46 -0
- data/lib/qml/plugins.rb +26 -0
- data/lib/qml/qml.rb +1 -0
- data/lib/qml/qt.rb +6 -0
- data/lib/qml/qt_classes.rb +9 -0
- data/lib/qml/qt_object_base.rb +108 -0
- data/lib/qml/reactive.rb +8 -0
- data/lib/qml/reactive/bindable.rb +79 -0
- data/lib/qml/reactive/chained_signal.rb +25 -0
- data/lib/qml/reactive/error.rb +5 -0
- data/lib/qml/reactive/object.rb +278 -0
- data/lib/qml/reactive/property.rb +19 -0
- data/lib/qml/reactive/signal.rb +116 -0
- data/lib/qml/reactive/signal_spy.rb +27 -0
- data/lib/qml/reactive/signals/map_signal.rb +21 -0
- data/lib/qml/reactive/signals/merge_signal.rb +21 -0
- data/lib/qml/reactive/signals/select_signal.rb +21 -0
- data/lib/qml/reactive/simple_property.rb +17 -0
- data/lib/qml/reactive/unbound_property.rb +42 -0
- data/lib/qml/reactive/unbound_signal.rb +51 -0
- data/lib/qml/root_path.rb +3 -0
- data/lib/qml/test_util.rb +1 -0
- data/lib/qml/test_util/object_life_checker.rb +17 -0
- data/lib/qml/version.rb +3 -0
- data/lib/qml/wrappable.rb +9 -0
- data/qml.gemspec +28 -0
- data/spec/assets/testobj.qml +5 -0
- data/spec/qml/.access_spec.rb.swp +0 -0
- data/spec/qml/access_spec.rb +162 -0
- data/spec/qml/application_spec.rb +43 -0
- data/spec/qml/component_spec.rb +44 -0
- data/spec/qml/context_spec.rb +43 -0
- data/spec/qml/conversion_spec.rb +59 -0
- data/spec/qml/data/array_model_spec.rb +215 -0
- data/spec/qml/dispatchable_spec.rb +26 -0
- data/spec/qml/dispatcher_spec.rb +48 -0
- data/spec/qml/geometry/point_spec.rb +4 -0
- data/spec/qml/geometry/rectangle_spec.rb +4 -0
- data/spec/qml/geometry/size_spec.rb +4 -0
- data/spec/qml/plugin_loader_spec.rb +33 -0
- data/spec/qml/qt_object_base_spec.rb +119 -0
- data/spec/qml/reactive/object_spec.rb +273 -0
- data/spec/qml/reactive/property_spec.rb +70 -0
- data/spec/qml/reactive/signal_spec.rb +191 -0
- data/spec/qml/reactive/signal_spy_spec.rb +26 -0
- data/spec/qml/test_object_spec.rb +186 -0
- data/spec/qml_spec.rb +7 -0
- data/spec/spec_helper.rb +5 -0
- metadata +321 -0
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include "rubyvalue.h"
|
|
4
|
+
#include <QtCore/QMetaObject>
|
|
5
|
+
#include <QtCore/QVector>
|
|
6
|
+
#include <QtCore/QHash>
|
|
7
|
+
#include <QtCore/QObject>
|
|
8
|
+
|
|
9
|
+
namespace RubyQml {
|
|
10
|
+
namespace Ext {
|
|
11
|
+
|
|
12
|
+
class MetaObject
|
|
13
|
+
{
|
|
14
|
+
public:
|
|
15
|
+
MetaObject(RubyValue self);
|
|
16
|
+
|
|
17
|
+
RubyValue className() const;
|
|
18
|
+
|
|
19
|
+
RubyValue methodNames() const;
|
|
20
|
+
RubyValue isPublic(RubyValue name) const;
|
|
21
|
+
RubyValue isProtected(RubyValue name) const;
|
|
22
|
+
RubyValue isPrivate(RubyValue name) const;
|
|
23
|
+
RubyValue isSignal(RubyValue name) const;
|
|
24
|
+
|
|
25
|
+
RubyValue invokeMethod(RubyValue object, RubyValue methodName, RubyValue args) const;
|
|
26
|
+
RubyValue connectSignal(RubyValue object, RubyValue signalName, RubyValue proc) const;
|
|
27
|
+
|
|
28
|
+
RubyValue propertyNames() const;
|
|
29
|
+
RubyValue getProperty(RubyValue object, RubyValue name) const;
|
|
30
|
+
RubyValue setProperty(RubyValue object, RubyValue name, RubyValue newValue) const;
|
|
31
|
+
RubyValue notifySignal(RubyValue name) const;
|
|
32
|
+
|
|
33
|
+
RubyValue enumerators() const;
|
|
34
|
+
|
|
35
|
+
RubyValue superClass() const;
|
|
36
|
+
|
|
37
|
+
RubyValue isEqual(RubyValue other) const;
|
|
38
|
+
RubyValue hash() const;
|
|
39
|
+
|
|
40
|
+
void setMetaObject(const QMetaObject *metaObject);
|
|
41
|
+
const QMetaObject *metaObject() const { return mMetaObject; }
|
|
42
|
+
|
|
43
|
+
void gc_mark() {}
|
|
44
|
+
|
|
45
|
+
static RubyValue fromMetaObject(const QMetaObject *metaObject);
|
|
46
|
+
static void defineClass();
|
|
47
|
+
|
|
48
|
+
private:
|
|
49
|
+
void checkThread() const;
|
|
50
|
+
|
|
51
|
+
QList<int> findMethods(RubyValue name) const;
|
|
52
|
+
int findProperty(RubyValue name) const;
|
|
53
|
+
|
|
54
|
+
const RubyValue self;
|
|
55
|
+
|
|
56
|
+
const QMetaObject *mMetaObject = nullptr;
|
|
57
|
+
QMultiHash<ID, int> mMethodHash;
|
|
58
|
+
QHash<ID, int> mPropertyHash;
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
} // namespace Ext
|
|
62
|
+
} // namespace RubyQml
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
#include "ext_pluginloader.h"
|
|
2
|
+
#include "ext_pointer.h"
|
|
3
|
+
#include "rubyclass.h"
|
|
4
|
+
#include <QtCore/QPluginLoader>
|
|
5
|
+
#include <QtCore/QSet>
|
|
6
|
+
|
|
7
|
+
namespace RubyQml {
|
|
8
|
+
namespace Ext {
|
|
9
|
+
|
|
10
|
+
PluginLoader::PluginLoader(RubyValue self) :
|
|
11
|
+
self(self),
|
|
12
|
+
mPluginLoader(new QPluginLoader())
|
|
13
|
+
{
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
PluginLoader::~PluginLoader()
|
|
17
|
+
{
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
RubyValue PluginLoader::initialize(RubyValue path)
|
|
21
|
+
{
|
|
22
|
+
mPluginLoader->setFileName(path.to<QString>());
|
|
23
|
+
return self;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
RubyValue PluginLoader::load()
|
|
27
|
+
{
|
|
28
|
+
auto ok = mPluginLoader->load();
|
|
29
|
+
if (!ok) {
|
|
30
|
+
fail("QML::PluginError", mPluginLoader->errorString());
|
|
31
|
+
}
|
|
32
|
+
return self;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
RubyValue PluginLoader::instance()
|
|
36
|
+
{
|
|
37
|
+
self.send("load");
|
|
38
|
+
auto instance = mPluginLoader->instance();
|
|
39
|
+
if (instance) {
|
|
40
|
+
return RubyValue::from(instance);
|
|
41
|
+
} else {
|
|
42
|
+
return Qnil;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
void PluginLoader::defineClass()
|
|
47
|
+
{
|
|
48
|
+
WrapperRubyClass<PluginLoader> klass(RubyModule::fromPath("QML"), "PluginLoader");
|
|
49
|
+
klass.defineMethod(MethodAccess::Private, "initialize", RUBYQML_MEMBER_FUNCTION_INFO(&PluginLoader::initialize));
|
|
50
|
+
klass.defineMethod(MethodAccess::Public, "load", RUBYQML_MEMBER_FUNCTION_INFO(&PluginLoader::load));
|
|
51
|
+
klass.defineMethod(MethodAccess::Public, "instance", RUBYQML_MEMBER_FUNCTION_INFO(&PluginLoader::instance));
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
} // namespace Ext
|
|
55
|
+
} // namespace RubyQml
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include "rubyvalue.h"
|
|
4
|
+
#include <memory>
|
|
5
|
+
|
|
6
|
+
class QPluginLoader;
|
|
7
|
+
|
|
8
|
+
namespace RubyQml {
|
|
9
|
+
namespace Ext {
|
|
10
|
+
|
|
11
|
+
class PluginLoader
|
|
12
|
+
{
|
|
13
|
+
public:
|
|
14
|
+
PluginLoader(RubyValue self);
|
|
15
|
+
~PluginLoader();
|
|
16
|
+
|
|
17
|
+
RubyValue initialize(RubyValue path);
|
|
18
|
+
RubyValue load();
|
|
19
|
+
RubyValue instance();
|
|
20
|
+
|
|
21
|
+
void gc_mark() {}
|
|
22
|
+
|
|
23
|
+
static void defineClass();
|
|
24
|
+
|
|
25
|
+
private:
|
|
26
|
+
const RubyValue self;
|
|
27
|
+
std::unique_ptr<QPluginLoader> mPluginLoader;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
} // namespace Ext
|
|
31
|
+
} // namespace RubyQml
|
|
32
|
+
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
#include "ext_pointer.h"
|
|
2
|
+
#include "markable.h"
|
|
3
|
+
#include "objectdata.h"
|
|
4
|
+
#include "objectgc.h"
|
|
5
|
+
#include "application.h"
|
|
6
|
+
#include <QObject>
|
|
7
|
+
#include <QHash>
|
|
8
|
+
#include <QQmlEngine>
|
|
9
|
+
#include <QQmlContext>
|
|
10
|
+
#include <QDebug>
|
|
11
|
+
#include <QCoreApplication>
|
|
12
|
+
|
|
13
|
+
namespace RubyQml {
|
|
14
|
+
namespace Ext {
|
|
15
|
+
|
|
16
|
+
Pointer::Pointer(RubyValue self) :
|
|
17
|
+
self(self)
|
|
18
|
+
{
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
Pointer::~Pointer()
|
|
22
|
+
{
|
|
23
|
+
ObjectGC::instance()->debug() << "\u267B\uFE0F releasing object:" << mObject << "managed:" << mIsManaged;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
RubyValue Pointer::fromQObject(QObject *obj, bool owned)
|
|
27
|
+
{
|
|
28
|
+
auto klass = wrapperRubyClass<Pointer>();
|
|
29
|
+
auto ptr = klass.newInstance();
|
|
30
|
+
klass.unwrap(ptr)->setQObject(obj, owned);
|
|
31
|
+
return ptr;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
QObject *Pointer::fetchQObject()
|
|
35
|
+
{
|
|
36
|
+
if (!mObject) {
|
|
37
|
+
fail("QML::QtObjectError", "referencing already deleted Qt Object");
|
|
38
|
+
}
|
|
39
|
+
return mObject;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
void Pointer::setQObject(QObject *obj, bool managed)
|
|
43
|
+
{
|
|
44
|
+
if (!obj) {
|
|
45
|
+
throw std::logic_error("null object");
|
|
46
|
+
}
|
|
47
|
+
mObject = obj;
|
|
48
|
+
ObjectGC::instance()->addObject(obj);
|
|
49
|
+
|
|
50
|
+
preferManaged(managed);
|
|
51
|
+
ObjectGC::instance()->debug() << "\u2728 acquiring object:" << mObject;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
void Pointer::setManaged(bool managed)
|
|
55
|
+
{
|
|
56
|
+
if (mObject) {
|
|
57
|
+
if (managed) {
|
|
58
|
+
QQmlEngine::setObjectOwnership(mObject, QQmlEngine::JavaScriptOwnership);
|
|
59
|
+
mJSValue = Application::engine()->newQObject(mObject);
|
|
60
|
+
} else {
|
|
61
|
+
QQmlEngine::setObjectOwnership(mObject, QQmlEngine::CppOwnership);
|
|
62
|
+
mJSValue = QJSValue();
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
ObjectData::getOrCreate(mObject)->owned = managed;
|
|
66
|
+
mIsManaged = managed;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
void Pointer::preferManaged(bool managed)
|
|
71
|
+
{
|
|
72
|
+
auto ownership = QQmlEngine::objectOwnership(mObject);
|
|
73
|
+
|
|
74
|
+
if (ownership == QQmlEngine::JavaScriptOwnership) {
|
|
75
|
+
managed = true;
|
|
76
|
+
} else {
|
|
77
|
+
// owned by parent
|
|
78
|
+
if (mObject->parent()) {
|
|
79
|
+
managed = false;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
setManaged(managed);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
RubyValue Pointer::ext_isManaged() const
|
|
87
|
+
{
|
|
88
|
+
return RubyValue::from(mIsManaged);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
RubyValue Pointer::ext_setManaged(RubyValue managed)
|
|
92
|
+
{
|
|
93
|
+
setManaged(managed.to<bool>());
|
|
94
|
+
return ext_isManaged();
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
RubyValue Pointer::ext_preferManaged(RubyValue managed)
|
|
98
|
+
{
|
|
99
|
+
preferManaged(managed.to<bool>());
|
|
100
|
+
return ext_isManaged();
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
RubyValue Pointer::ext_isNull() const
|
|
104
|
+
{
|
|
105
|
+
return RubyValue::from(!mObject);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
RubyValue Pointer::ext_toString() const
|
|
109
|
+
{
|
|
110
|
+
QString name;
|
|
111
|
+
QDebug(&name) << mObject.data();
|
|
112
|
+
return RubyValue::from(name);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
void Pointer::gc_mark()
|
|
116
|
+
{
|
|
117
|
+
if (mIsManaged) {
|
|
118
|
+
ObjectGC::instance()->markOwnedObject(mObject);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
void Pointer::defineClass()
|
|
123
|
+
{
|
|
124
|
+
WrapperRubyClass<Pointer> klass(RubyModule::fromPath("QML"), "Pointer");
|
|
125
|
+
klass.defineMethod("managed?", RUBYQML_MEMBER_FUNCTION_INFO(&Pointer::ext_isManaged));
|
|
126
|
+
klass.defineMethod("managed=", RUBYQML_MEMBER_FUNCTION_INFO(&Pointer::ext_setManaged));
|
|
127
|
+
klass.defineMethod("prefer_managed", RUBYQML_MEMBER_FUNCTION_INFO(&Pointer::ext_preferManaged));
|
|
128
|
+
klass.defineMethod("null?", RUBYQML_MEMBER_FUNCTION_INFO(&Pointer::ext_isNull));
|
|
129
|
+
klass.defineMethod("to_s", RUBYQML_MEMBER_FUNCTION_INFO(&Pointer::ext_toString));
|
|
130
|
+
klass.aliasMethod("inspect", "to_s");
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
} // namespace Ext
|
|
134
|
+
} // namespace RubyQml
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
#include "rubyclass.h"
|
|
3
|
+
#include <QPointer>
|
|
4
|
+
#include <QJSValue>
|
|
5
|
+
|
|
6
|
+
namespace RubyQml {
|
|
7
|
+
namespace Ext {
|
|
8
|
+
|
|
9
|
+
class Pointer
|
|
10
|
+
{
|
|
11
|
+
public:
|
|
12
|
+
Pointer(RubyValue self);
|
|
13
|
+
~Pointer();
|
|
14
|
+
|
|
15
|
+
static RubyValue fromQObject(QObject *obj, bool owned);
|
|
16
|
+
|
|
17
|
+
QObject *qObject() { return mObject; }
|
|
18
|
+
QObject *fetchQObject();
|
|
19
|
+
void setQObject(QObject *obj, bool managed);
|
|
20
|
+
bool isManaged() const { return mIsManaged; }
|
|
21
|
+
void setManaged(bool managed);
|
|
22
|
+
void preferManaged(bool managed);
|
|
23
|
+
|
|
24
|
+
RubyValue ext_isManaged() const;
|
|
25
|
+
RubyValue ext_setManaged(RubyValue managed);
|
|
26
|
+
RubyValue ext_preferManaged(RubyValue managed);
|
|
27
|
+
RubyValue ext_isNull() const;
|
|
28
|
+
RubyValue ext_toString() const;
|
|
29
|
+
|
|
30
|
+
void gc_mark();
|
|
31
|
+
|
|
32
|
+
static void defineClass();
|
|
33
|
+
|
|
34
|
+
private:
|
|
35
|
+
const RubyValue self;
|
|
36
|
+
|
|
37
|
+
bool mIsManaged = false;
|
|
38
|
+
QPointer<QObject> mObject;
|
|
39
|
+
QJSValue mJSValue;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
} // namespace Ext
|
|
43
|
+
} // namespace RubyQml
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
#include "ext_testutil.h"
|
|
2
|
+
#include "rubyclass.h"
|
|
3
|
+
#include "objectgc.h"
|
|
4
|
+
|
|
5
|
+
namespace RubyQml {
|
|
6
|
+
namespace Ext {
|
|
7
|
+
namespace TestUtil {
|
|
8
|
+
|
|
9
|
+
namespace {
|
|
10
|
+
|
|
11
|
+
RubyValue echoConversion(RubyValue self, RubyValue value)
|
|
12
|
+
{
|
|
13
|
+
Q_UNUSED(self);
|
|
14
|
+
auto variant = RubyValue(value).to<QVariant>();
|
|
15
|
+
return RubyValue::from(variant);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
RubyValue gcDebugMessageEnabled(RubyValue self)
|
|
19
|
+
{
|
|
20
|
+
Q_UNUSED(self);
|
|
21
|
+
return RubyValue::from(ObjectGC::instance()->debugMessageEnabled());
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
RubyValue setGCDebugMessageEnabled(RubyValue self, RubyValue enabled)
|
|
25
|
+
{
|
|
26
|
+
ObjectGC::instance()->setDebugMessageEnabled(enabled.to<bool>());
|
|
27
|
+
return gcDebugMessageEnabled(self);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
void defineModule()
|
|
33
|
+
{
|
|
34
|
+
RubyModule testUtil(RubyModule::fromPath("QML"), "TestUtil");
|
|
35
|
+
testUtil.defineModuleFunction("echo_conversion", RUBYQML_FUNCTION_INFO(&echoConversion));
|
|
36
|
+
testUtil.defineModuleFunction("gc_debug_message_enabled?", RUBYQML_FUNCTION_INFO(&gcDebugMessageEnabled));
|
|
37
|
+
testUtil.defineModuleFunction("gc_debug_message_enabled=", RUBYQML_FUNCTION_INFO(&setGCDebugMessageEnabled));
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
} // namespace TestUtil
|
|
41
|
+
} // namespace Ext
|
|
42
|
+
} // namespace RubyQml
|
data/ext/qml/extconf.rb
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
require 'mkmf'
|
|
2
|
+
require 'pathname'
|
|
3
|
+
|
|
4
|
+
class Configurator
|
|
5
|
+
|
|
6
|
+
PKGS = %w{Qt5Core Qt5Gui Qt5Widgets Qt5Qml Qt5Quick libffi}
|
|
7
|
+
HEADERS = %w{QObject QVariant QApplication QQmlEngine QQmlComponent QQmlContext ffi.h}
|
|
8
|
+
CLASSES = %w{listmodel}
|
|
9
|
+
|
|
10
|
+
def initialize
|
|
11
|
+
find_dependencies
|
|
12
|
+
@cppflags = []
|
|
13
|
+
@ldflags = []
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def find_dependencies
|
|
17
|
+
@pkgconfig = with_config('pkg-config') || find_executable('pkg-config')
|
|
18
|
+
abort 'pkg-config executable not found' unless @pkgconfig
|
|
19
|
+
|
|
20
|
+
@qt_path = with_config('qt-dir')
|
|
21
|
+
@qt_path &&= Pathname(@qt_path).realpath
|
|
22
|
+
|
|
23
|
+
@ffi_path = with_config('libffi-dir')
|
|
24
|
+
@ffi_path &&= Pathname(@ffi_path).realpath
|
|
25
|
+
|
|
26
|
+
[@qt_path, @ffi_path].compact.each do |path|
|
|
27
|
+
ENV['PKG_CONFIG_PATH'] = "#{path + 'lib/pkgconfig'}:#{ENV['PKG_CONFIG_PATH']}"
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
@qmake = @qt_path ? @qt_path + 'bin/qmake' : find_executable('qmake')
|
|
31
|
+
@moc = @qt_path ? @qt_path + 'bin/moc' : find_executable('moc')
|
|
32
|
+
abort 'qmake executable not found' unless @qmake
|
|
33
|
+
abort 'moc executable not found' unless @moc
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def build_plugins
|
|
37
|
+
puts "building plugins..."
|
|
38
|
+
Pathname(__FILE__).+("../plugins").children.select(&:directory?).each do |dir|
|
|
39
|
+
Dir.chdir(dir) do
|
|
40
|
+
system("#{@qmake}") && system('make') or abort "failed to build plugin: #{dir.basename}"
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def configure_extension
|
|
46
|
+
RbConfig::CONFIG['CPP'].gsub!(RbConfig::CONFIG['CC'], RbConfig::CONFIG['CXX'])
|
|
47
|
+
|
|
48
|
+
PKGS.each do |mod|
|
|
49
|
+
@cppflags << `#{@pkgconfig} --cflags #{mod}`.chomp
|
|
50
|
+
@ldflags << `#{@pkgconfig} --libs #{mod}`.chomp
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
qtversion = `#{@pkgconfig} --modversion Qt5Core`.chomp
|
|
54
|
+
`#{@pkgconfig} --cflags-only-I Qt5Core`.split.map { |i| Pathname(i.gsub("-I", "")) }.each do |dir|
|
|
55
|
+
private_dir = dir + "#{qtversion}/QtCore"
|
|
56
|
+
@cppflags << "-I#{private_dir}" if private_dir.exist?
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
$CPPFLAGS += " #{@cppflags.join(" ")}"
|
|
60
|
+
$LDFLAGS += " #{@ldflags.join(" ")}"
|
|
61
|
+
$CPPFLAGS += " -fPIC"
|
|
62
|
+
|
|
63
|
+
HEADERS.each do |h|
|
|
64
|
+
abort "header not found: #{h}" unless have_header(h)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
$CPPFLAGS += " -std=c++11 -Wall -Wextra -pipe"
|
|
68
|
+
if enable_config('debug')
|
|
69
|
+
$CPPFLAGS += " -O0 -ggdb3"
|
|
70
|
+
else
|
|
71
|
+
$CPPFLAGS += " -O3"
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
CLASSES.each do |header|
|
|
75
|
+
File.write("moc_#{header}.cpp", `#{@moc} #{header}.h`)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
create_makefile 'qml/qml'
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
configurator = Configurator.new
|
|
83
|
+
configurator.build_plugins
|
|
84
|
+
configurator.configure_extension
|