diff options
author | George Kiagiadakis <george.kiagiadakis@collabora.co.uk> | 2010-12-16 12:53:36 +0200 |
---|---|---|
committer | George Kiagiadakis <george.kiagiadakis@collabora.co.uk> | 2010-12-16 12:53:36 +0200 |
commit | b68c2396d8bc009cace13a07bd4d7e024af2df35 (patch) | |
tree | 47b37cd5aa56b19a6f3adb0b2ef48880c33bddfc | |
parent | d5eeec5feb460f20338cb112eee4447d8e53cfee (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.cpp | 19 | ||||
-rw-r--r-- | tests/auto/valuetest.cpp | 15 |
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; |