summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorge Kiagiadakis <george.kiagiadakis@collabora.co.uk>2010-12-16 12:53:36 +0200
committerGeorge Kiagiadakis <george.kiagiadakis@collabora.co.uk>2010-12-16 12:53:36 +0200
commitb68c2396d8bc009cace13a07bd4d7e024af2df35 (patch)
tree47b37cd5aa56b19a6f3adb0b2ef48880c33bddfc
parentd5eeec5feb460f20338cb112eee4447d8e53cfee (diff)
Handle interfaces properly in Value.
All interfaces that can be assigned to a GValue have an instantiatable prerequisite which is the actual type stored inside the GValue. Here, we make use of this invariant to find the proper vtable that can be used to set/get the interface pointer to/from the GValue.
-rw-r--r--src/QGlib/value.cpp19
-rw-r--r--tests/auto/valuetest.cpp15
2 files changed, 34 insertions, 0 deletions
diff --git a/src/QGlib/value.cpp b/src/QGlib/value.cpp
index e4145c3..0ee7dd7 100644
--- a/src/QGlib/value.cpp
+++ b/src/QGlib/value.cpp
@@ -82,6 +82,25 @@ Dispatcher::Dispatcher()
ValueVTable Dispatcher::getVTable(Type t) const
{
+ //if the type is an interface, try to find its
+ //instantiatable prerequisite and get the vtable
+ //of this instantiatable type instead.
+ if (t.isInterface()) {
+ QList<Type> prerequisites = t.interfacePrerequisites();
+ Q_FOREACH(Type prereq, prerequisites) {
+ if (prereq.isInstantiatable()) {
+ t = prereq;
+ }
+ }
+
+ //Check if the prerequisite was found and
+ //bail out if not, since such interfaces
+ //are not compatible with GValue.
+ if (!t.isInstantiatable()) {
+ return ValueVTable();
+ }
+ }
+
QReadLocker l(&lock);
if (dispatchTable.contains(t)) {
diff --git a/tests/auto/valuetest.cpp b/tests/auto/valuetest.cpp
index 4161d3e..47ff9a4 100644
--- a/tests/auto/valuetest.cpp
+++ b/tests/auto/valuetest.cpp
@@ -36,6 +36,7 @@ private Q_SLOTS:
void miniObjectTest();
void capsTest();
void valueTest();
+ void interfaceTest();
void conversionsTest();
void copyTest();
void castTest();
@@ -144,6 +145,20 @@ void ValueTest::valueTest()
QCOMPARE(v2.toByteArray(), QByteArray("foobar"));
}
+void ValueTest::interfaceTest()
+{
+ QGlib::Value v;
+ v.init<QGst::ChildProxy>();
+ QCOMPARE(v.type(), QGlib::GetType<QGst::ChildProxy>());
+
+ QGst::ChildProxyPtr childProxy = QGst::Bin::create();
+ v.set(childProxy);
+
+ QGst::ChildProxyPtr cp2 = v.get<QGst::ChildProxyPtr>();
+ QVERIFY(!cp2.isNull());
+ QCOMPARE(static_cast<GstChildProxy*>(childProxy), static_cast<GstChildProxy*>(cp2));
+}
+
void ValueTest::conversionsTest()
{
QGlib::Value v;