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