diff options
author | Sean Harmer <sean.harmer@kdab.com> | 2017-02-22 15:23:33 +0000 |
---|---|---|
committer | Sean Harmer <sean.harmer@kdab.com> | 2017-02-24 20:41:44 +0000 |
commit | 3624ddb7beeff87196cf1ccc6684dd05457945e1 (patch) | |
tree | 5b3e53c861528fa07bc8122b7a6a954821952a7e | |
parent | 28938073a228a38c2a5beccdb3357b5a8c172def (diff) |
Add startClip and endClip properties to QLerpClipBlend
Task-number: QTBUG-58904
Change-Id: I67a28b5f311d0065e8ca81df692de33ef1aeefcf
Reviewed-by: Kevin Ottens <kevin.ottens@kdab.com>
-rw-r--r-- | src/animation/backend/lerpclipblend.cpp | 8 | ||||
-rw-r--r-- | src/animation/backend/lerpclipblend_p.h | 8 | ||||
-rw-r--r-- | src/animation/frontend/qlerpclipblend.cpp | 83 | ||||
-rw-r--r-- | src/animation/frontend/qlerpclipblend.h | 8 | ||||
-rw-r--r-- | src/animation/frontend/qlerpclipblend_p.h | 4 | ||||
-rw-r--r-- | tests/auto/animation/qlerpclipblend/tst_qlerpclipblend.cpp | 197 |
6 files changed, 298 insertions, 10 deletions
diff --git a/src/animation/backend/lerpclipblend.cpp b/src/animation/backend/lerpclipblend.cpp index 1121f0324..7e10a5174 100644 --- a/src/animation/backend/lerpclipblend.cpp +++ b/src/animation/backend/lerpclipblend.cpp @@ -47,6 +47,8 @@ namespace Animation { LerpClipBlend::LerpClipBlend() : ClipBlendNode(ClipBlendNode::LerpBlendType) + , m_startClipId() + , m_endClipId() , m_blendFactor(0.0f) { } @@ -61,6 +63,10 @@ void LerpClipBlend::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) Qt3DCore::QPropertyUpdatedChangePtr change = qSharedPointerCast<Qt3DCore::QPropertyUpdatedChange>(e); if (change->propertyName() == QByteArrayLiteral("blendFactor")) m_blendFactor = change->value().toFloat(); + else if (change->propertyName() == QByteArrayLiteral("startClip")) + m_startClipId = change->value().value<Qt3DCore::QNodeId>(); + else if (change->propertyName() == QByteArrayLiteral("endClip")) + m_endClipId = change->value().value<Qt3DCore::QNodeId>(); } } @@ -74,6 +80,8 @@ void LerpClipBlend::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr ClipBlendNode::initializeFromPeer(change); const auto creationChangeData = qSharedPointerCast<Qt3DAnimation::QClipBlendNodeCreatedChange<Qt3DAnimation::QLerpClipBlendData>>(change); const Qt3DAnimation::QLerpClipBlendData cloneData = creationChangeData->data; + m_startClipId = cloneData.startClipId; + m_endClipId = cloneData.endClipId; m_blendFactor = cloneData.blendFactor; } diff --git a/src/animation/backend/lerpclipblend_p.h b/src/animation/backend/lerpclipblend_p.h index 8b925b5b6..8d2a9839b 100644 --- a/src/animation/backend/lerpclipblend_p.h +++ b/src/animation/backend/lerpclipblend_p.h @@ -65,12 +65,20 @@ public: inline float blendFactor() const { return m_blendFactor; } void setBlendFactor(float blendFactor) { m_blendFactor = blendFactor; } // For unit tests + inline Qt3DCore::QNodeId startClipId() const { return m_startClipId; } + void setStartClipId(Qt3DCore::QNodeId startClipId) { m_startClipId = startClipId; } // For unit tests + + inline Qt3DCore::QNodeId endClipId() const { return m_endClipId; } + void setEndClipId(Qt3DCore::QNodeId endClipId) { m_endClipId = endClipId; } // For unit tests + void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) Q_DECL_FINAL; float blend(float value1, float value2) const Q_DECL_FINAL; private: void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) Q_DECL_FINAL; + Qt3DCore::QNodeId m_startClipId; + Qt3DCore::QNodeId m_endClipId; float m_blendFactor; }; diff --git a/src/animation/frontend/qlerpclipblend.cpp b/src/animation/frontend/qlerpclipblend.cpp index cb6df6235..3b26adbaa 100644 --- a/src/animation/frontend/qlerpclipblend.cpp +++ b/src/animation/frontend/qlerpclipblend.cpp @@ -86,6 +86,8 @@ namespace Qt3DAnimation { QLerpClipBlendPrivate::QLerpClipBlendPrivate() : QAbstractClipBlendNodePrivate() + , m_startClip(nullptr) + , m_endClip(nullptr) , m_blendFactor(0.0f) { } @@ -109,6 +111,8 @@ Qt3DCore::QNodeCreatedChangeBasePtr QLerpClipBlend::createNodeCreationChange() c Q_D(const QLerpClipBlend); auto creationChange = QClipBlendNodeCreatedChangePtr<QLerpClipBlendData>::create(this); QLerpClipBlendData &data = creationChange->data; + data.startClipId = Qt3DCore::qIdForNode(d->m_startClip); + data.endClipId = Qt3DCore::qIdForNode(d->m_endClip); data.blendFactor = d->m_blendFactor; return creationChange; } @@ -131,9 +135,50 @@ float QLerpClipBlend::blendFactor() const return d->m_blendFactor; } +/*! + \qmlproperty AbstractClipBlendNode LerpClipBlend::startClip + + Holds the sub-tree that should be used as the start clip for this + lerp blend node. That is, the clip returned by this blend node when + the blendFactor is set to a value of 0. +*/ +/*! + \property QLerpClipBlend::startClip + + Holds the sub-tree that should be used as the start clip for this + lerp blend node. That is, the clip returned by this blend node when + the blendFactor is set to a value of 0. +*/ +Qt3DAnimation::QAbstractClipBlendNode *QLerpClipBlend::startClip() const +{ + Q_D(const QLerpClipBlend); + return d->m_startClip; +} + +/*! + \qmlproperty AbstractClipBlendNode LerpClipBlend::endClip + + Holds the sub-tree that should be used as the end clip for this + lerp blend node. That is, the clip returned by this blend node when + the blendFactor is set to a value of 1. +*/ +/*! + \property QLerpClipBlend::endClip + + Holds the sub-tree that should be used as the start clip for this + lerp blend node. That is, the clip returned by this blend node when + the blendFactor is set to a value of 1. +*/ +Qt3DAnimation::QAbstractClipBlendNode *QLerpClipBlend::endClip() const +{ + Q_D(const QLerpClipBlend); + return d->m_endClip; +} + void QLerpClipBlend::setBlendFactor(float blendFactor) { Q_D(QLerpClipBlend); + if (d->m_blendFactor == blendFactor) return; @@ -141,6 +186,44 @@ void QLerpClipBlend::setBlendFactor(float blendFactor) emit blendFactorChanged(blendFactor); } +void QLerpClipBlend::setStartClip(Qt3DAnimation::QAbstractClipBlendNode *startClip) +{ + Q_D(QLerpClipBlend); + if (d->m_startClip == startClip) + return; + + if (d->m_startClip) + d->unregisterDestructionHelper(d->m_startClip); + + if (startClip && !startClip->parent()) + startClip->setParent(this); + d->m_startClip = startClip; + + // Ensures proper bookkeeping + if (d->m_startClip) + d->registerDestructionHelper(d->m_startClip, &QLerpClipBlend::setStartClip, d->m_startClip); + emit startClipChanged(startClip); +} + +void QLerpClipBlend::setEndClip(Qt3DAnimation::QAbstractClipBlendNode *endClip) +{ + Q_D(QLerpClipBlend); + if (d->m_endClip == endClip) + return; + + if (d->m_endClip) + d->unregisterDestructionHelper(d->m_endClip); + + if (endClip && !endClip->parent()) + endClip->setParent(this); + d->m_endClip = endClip; + + // Ensures proper bookkeeping + if (d->m_endClip) + d->registerDestructionHelper(d->m_endClip, &QLerpClipBlend::setEndClip, d->m_endClip); + emit endClipChanged(endClip); +} + /*! \qmlproperty list<AnimationClip> LerpBlend::clips diff --git a/src/animation/frontend/qlerpclipblend.h b/src/animation/frontend/qlerpclipblend.h index 83d1201cb..f6707a5a5 100644 --- a/src/animation/frontend/qlerpclipblend.h +++ b/src/animation/frontend/qlerpclipblend.h @@ -48,6 +48,8 @@ class QLerpClipBlendPrivate; class QT3DANIMATIONSHARED_EXPORT QLerpClipBlend : public QAbstractClipBlendNode { Q_OBJECT + Q_PROPERTY(Qt3DAnimation::QAbstractClipBlendNode *startClip READ startClip WRITE setStartClip NOTIFY startClipChanged) + Q_PROPERTY(Qt3DAnimation::QAbstractClipBlendNode *endClip READ endClip WRITE setEndClip NOTIFY endClipChanged) Q_PROPERTY(float blendFactor READ blendFactor WRITE setBlendFactor NOTIFY blendFactorChanged) public: @@ -55,12 +57,18 @@ public: ~QLerpClipBlend(); float blendFactor() const; + Qt3DAnimation::QAbstractClipBlendNode *startClip() const; + Qt3DAnimation::QAbstractClipBlendNode *endClip() const; public Q_SLOTS: void setBlendFactor(float blendFactor); + void setStartClip(Qt3DAnimation::QAbstractClipBlendNode * startClip); + void setEndClip(Qt3DAnimation::QAbstractClipBlendNode * endClip); Q_SIGNALS: void blendFactorChanged(float blendFactor); + void startClipChanged(Qt3DAnimation::QAbstractClipBlendNode * startClip); + void endClipChanged(Qt3DAnimation::QAbstractClipBlendNode * endClip); protected: explicit QLerpClipBlend(QLerpClipBlendPrivate &dd, Qt3DCore::QNode *parent = nullptr); diff --git a/src/animation/frontend/qlerpclipblend_p.h b/src/animation/frontend/qlerpclipblend_p.h index eeae948bf..eee597059 100644 --- a/src/animation/frontend/qlerpclipblend_p.h +++ b/src/animation/frontend/qlerpclipblend_p.h @@ -64,11 +64,15 @@ public: QLerpClipBlendPrivate(); Q_DECLARE_PUBLIC(QLerpClipBlend) + QAbstractClipBlendNode *m_startClip; + QAbstractClipBlendNode *m_endClip; float m_blendFactor; }; struct QLerpClipBlendData { + Qt3DCore::QNodeId startClipId; + Qt3DCore::QNodeId endClipId; float blendFactor; }; diff --git a/tests/auto/animation/qlerpclipblend/tst_qlerpclipblend.cpp b/tests/auto/animation/qlerpclipblend/tst_qlerpclipblend.cpp index 5f3bdeccf..d6b449fdb 100644 --- a/tests/auto/animation/qlerpclipblend/tst_qlerpclipblend.cpp +++ b/tests/auto/animation/qlerpclipblend/tst_qlerpclipblend.cpp @@ -44,6 +44,10 @@ class tst_QLerpClipBlend : public QObject Q_OBJECT private Q_SLOTS: + void initTestCase() + { + qRegisterMetaType<Qt3DAnimation::QAbstractClipBlendNode*>(); + } void checkDefaultConstruction() { @@ -52,6 +56,8 @@ private Q_SLOTS: // THEN QCOMPARE(lerpBlend.blendFactor(), 0.0f); + QCOMPARE(lerpBlend.startClip(), static_cast<Qt3DAnimation::QAbstractClipBlendNode *>(nullptr)); + QCOMPARE(lerpBlend.endClip(), static_cast<Qt3DAnimation::QAbstractClipBlendNode *>(nullptr)); } void checkPropertyChanges() @@ -78,17 +84,57 @@ private Q_SLOTS: QCOMPARE(lerpBlend.blendFactor(), newValue); QCOMPARE(spy.count(), 0); } + + { + // WHEN + QSignalSpy spy(&lerpBlend, SIGNAL(startClipChanged(Qt3DAnimation::QAbstractClipBlendNode*))); + auto newValue = new Qt3DAnimation::QLerpClipBlend(); + lerpBlend.setStartClip(newValue); + + // THEN + QVERIFY(spy.isValid()); + QCOMPARE(lerpBlend.startClip(), newValue); + QCOMPARE(spy.count(), 1); + + // WHEN + spy.clear(); + lerpBlend.setStartClip(newValue); + + // THEN + QCOMPARE(lerpBlend.startClip(), newValue); + QCOMPARE(spy.count(), 0); + } + + { + // WHEN + QSignalSpy spy(&lerpBlend, SIGNAL(endClipChanged(Qt3DAnimation::QAbstractClipBlendNode*))); + auto newValue = new Qt3DAnimation::QLerpClipBlend(); + lerpBlend.setEndClip(newValue); + + // THEN + QVERIFY(spy.isValid()); + QCOMPARE(lerpBlend.endClip(), newValue); + QCOMPARE(spy.count(), 1); + + // WHEN + spy.clear(); + lerpBlend.setEndClip(newValue); + + // THEN + QCOMPARE(lerpBlend.endClip(), newValue); + QCOMPARE(spy.count(), 0); + } } void checkCreationData() { // GIVEN Qt3DAnimation::QLerpClipBlend lerpBlend; - Qt3DAnimation::QAnimationClipLoader clip1; - Qt3DAnimation::QAnimationClipLoader clip2; + Qt3DAnimation::QLerpClipBlend startClip; + Qt3DAnimation::QLerpClipBlend endClip; - lerpBlend.addClip(&clip1); - lerpBlend.addClip(&clip2); + lerpBlend.setStartClip(&startClip); + lerpBlend.setEndClip(&endClip); lerpBlend.setBlendFactor(0.8f); @@ -112,9 +158,8 @@ private Q_SLOTS: QCOMPARE(lerpBlend.isEnabled(), true); QCOMPARE(lerpBlend.isEnabled(), creationChangeData->isNodeEnabled()); QCOMPARE(lerpBlend.metaObject(), creationChangeData->metaObject()); - QCOMPARE(creationChangeData->clips().size(), 2); - QCOMPARE(creationChangeData->clips().first(), clip1.id()); - QCOMPARE(creationChangeData->clips().last(), clip2.id()); + QCOMPARE(cloneData.startClipId, startClip.id()); + QCOMPARE(cloneData.endClipId, endClip.id()); QCOMPARE(creationChangeData->parentClipBlendNodeId(), Qt3DCore::QNodeId()); } @@ -138,9 +183,8 @@ private Q_SLOTS: QCOMPARE(lerpBlend.isEnabled(), false); QCOMPARE(lerpBlend.isEnabled(), creationChangeData->isNodeEnabled()); QCOMPARE(lerpBlend.metaObject(), creationChangeData->metaObject()); - QCOMPARE(creationChangeData->clips().size(), 2); - QCOMPARE(creationChangeData->clips().first(), clip1.id()); - QCOMPARE(creationChangeData->clips().last(), clip2.id()); + QCOMPARE(cloneData.startClipId, startClip.id()); + QCOMPARE(cloneData.endClipId, endClip.id()); QCOMPARE(creationChangeData->parentClipBlendNodeId(), Qt3DCore::QNodeId()); } } @@ -178,6 +222,139 @@ private Q_SLOTS: } + void checkStartClipUpdate() + { + // GIVEN + TestArbiter arbiter; + Qt3DAnimation::QLerpClipBlend lerpBlend; + arbiter.setArbiterOnNode(&lerpBlend); + auto startClip = new Qt3DAnimation::QLerpClipBlend(); + + { + // WHEN + lerpBlend.setStartClip(startClip); + QCoreApplication::processEvents(); + + // THEN + QCOMPARE(arbiter.events.size(), 1); + auto change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>(); + QCOMPARE(change->propertyName(), "startClip"); + QCOMPARE(change->value().value<Qt3DCore::QNodeId>(), lerpBlend.startClip()->id()); + QCOMPARE(change->type(), Qt3DCore::PropertyUpdated); + + arbiter.events.clear(); + } + + { + // WHEN + lerpBlend.setStartClip(startClip); + QCoreApplication::processEvents(); + + // THEN + QCOMPARE(arbiter.events.size(), 0); + } + } + + void checkEndClipUpdate() + { + // GIVEN + TestArbiter arbiter; + Qt3DAnimation::QLerpClipBlend lerpBlend; + arbiter.setArbiterOnNode(&lerpBlend); + auto endClip = new Qt3DAnimation::QLerpClipBlend(); + + { + // WHEN + lerpBlend.setEndClip(endClip); + QCoreApplication::processEvents(); + + // THEN + QCOMPARE(arbiter.events.size(), 1); + auto change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>(); + QCOMPARE(change->propertyName(), "endClip"); + QCOMPARE(change->value().value<Qt3DCore::QNodeId>(), lerpBlend.endClip()->id()); + QCOMPARE(change->type(), Qt3DCore::PropertyUpdated); + + arbiter.events.clear(); + } + + { + // WHEN + lerpBlend.setEndClip(endClip); + QCoreApplication::processEvents(); + + // THEN + QCOMPARE(arbiter.events.size(), 0); + } + } + + void checkStartClipBookkeeping() + { + // GIVEN + QScopedPointer<Qt3DAnimation::QLerpClipBlend> lerpBlend(new Qt3DAnimation::QLerpClipBlend); + { + // WHEN + Qt3DAnimation::QLerpClipBlend clip; + lerpBlend->setStartClip(&clip); + + // THEN + QCOMPARE(clip.parent(), lerpBlend.data()); + QCOMPARE(lerpBlend->startClip(), &clip); + } + // THEN (Should not crash and clip be unset) + QVERIFY(lerpBlend->startClip() == nullptr); + + { + // WHEN + Qt3DAnimation::QLerpClipBlend someOtherLerpBlend; + QScopedPointer<Qt3DAnimation::QLerpClipBlend> clip(new Qt3DAnimation::QLerpClipBlend(&someOtherLerpBlend)); + lerpBlend->setStartClip(clip.data()); + + // THEN + QCOMPARE(clip->parent(), &someOtherLerpBlend); + QCOMPARE(lerpBlend->startClip(), clip.data()); + + // WHEN + lerpBlend.reset(); + clip.reset(); + + // THEN Should not crash when the effect is destroyed (tests for failed removal of destruction helper) + } + } + + void checkEndClipBookkeeping() + { + // GIVEN + QScopedPointer<Qt3DAnimation::QLerpClipBlend> lerpBlend(new Qt3DAnimation::QLerpClipBlend); + { + // WHEN + Qt3DAnimation::QLerpClipBlend clip; + lerpBlend->setEndClip(&clip); + + // THEN + QCOMPARE(clip.parent(), lerpBlend.data()); + QCOMPARE(lerpBlend->endClip(), &clip); + } + // THEN (Should not crash and clip be unset) + QVERIFY(lerpBlend->endClip() == nullptr); + + { + // WHEN + Qt3DAnimation::QLerpClipBlend someOtherLerpBlend; + QScopedPointer<Qt3DAnimation::QLerpClipBlend> clip(new Qt3DAnimation::QLerpClipBlend(&someOtherLerpBlend)); + lerpBlend->setEndClip(clip.data()); + + // THEN + QCOMPARE(clip->parent(), &someOtherLerpBlend); + QCOMPARE(lerpBlend->endClip(), clip.data()); + + // WHEN + lerpBlend.reset(); + clip.reset(); + + // THEN Should not crash when the effect is destroyed (tests for failed removal of destruction helper) + } + } }; QTEST_MAIN(tst_QLerpClipBlend) |