summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSean Harmer <sean.harmer@kdab.com>2017-02-22 15:23:33 +0000
committerSean Harmer <sean.harmer@kdab.com>2017-02-24 20:41:44 +0000
commit3624ddb7beeff87196cf1ccc6684dd05457945e1 (patch)
tree5b3e53c861528fa07bc8122b7a6a954821952a7e
parent28938073a228a38c2a5beccdb3357b5a8c172def (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.cpp8
-rw-r--r--src/animation/backend/lerpclipblend_p.h8
-rw-r--r--src/animation/frontend/qlerpclipblend.cpp83
-rw-r--r--src/animation/frontend/qlerpclipblend.h8
-rw-r--r--src/animation/frontend/qlerpclipblend_p.h4
-rw-r--r--tests/auto/animation/qlerpclipblend/tst_qlerpclipblend.cpp197
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)