示例#1
0
    void checkSceneChangeEvents()
    {
        // GIVEN
        Qt3DRender::Render::MemoryBarrier backendMemoryBarrier;
        TestRenderer renderer;
        backendMemoryBarrier.setRenderer(&renderer);

        {
             // WHEN
             const bool newValue = false;
             const auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId());
             change->setPropertyName("enabled");
             change->setValue(newValue);
             backendMemoryBarrier.sceneChangeEvent(change);

             // THEN
            QCOMPARE(backendMemoryBarrier.isEnabled(), newValue);
        }
        {
             // WHEN
             const Qt3DRender::QMemoryBarrier::Operations newValue(Qt3DRender::QMemoryBarrier::AtomicCounter|Qt3DRender::QMemoryBarrier::ElementArray);
             const auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId());
             change->setPropertyName("waitOperations");
             change->setValue(QVariant::fromValue(newValue));
             backendMemoryBarrier.sceneChangeEvent(change);

             // THEN
            QCOMPARE(backendMemoryBarrier.waitOperations(), newValue);
        }
    }
示例#2
0
    void checkSceneChangeEvents()
    {
        // GIVEN
        Qt3DInput::Input::LogicalDevice backendLogicalDevice;

        {
            // WHEN
            const bool newValue = false;
            const auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId());
            change->setPropertyName("enabled");
            change->setValue(newValue);
            backendLogicalDevice.sceneChangeEvent(change);

            // THEN
            QCOMPARE(backendLogicalDevice.isEnabled(), newValue);
        }
        {
            // WHEN
            Qt3DInput::QAxis newValue;
            const auto change = Qt3DCore::QPropertyNodeAddedChangePtr::create(Qt3DCore::QNodeId(), &newValue);
            change->setPropertyName("axis");
            backendLogicalDevice.sceneChangeEvent(change);

            // THEN
            QCOMPARE(backendLogicalDevice.axes().size(), 1);
            QCOMPARE(backendLogicalDevice.axes().first(), newValue.id());

            // WHEN
            const auto change2 = Qt3DCore::QPropertyNodeRemovedChangePtr::create(Qt3DCore::QNodeId(), &newValue);
            change2->setPropertyName("axis");
            backendLogicalDevice.sceneChangeEvent(change2);

            // THEN
            QCOMPARE(backendLogicalDevice.axes().size(), 0);
        }
        {
            // WHEN
            Qt3DInput::QAction newValue;
            const auto change = Qt3DCore::QPropertyNodeAddedChangePtr::create(Qt3DCore::QNodeId(), &newValue);
            change->setPropertyName("action");
            backendLogicalDevice.sceneChangeEvent(change);

            // THEN
            QCOMPARE(backendLogicalDevice.actions().size(), 1);
            QCOMPARE(backendLogicalDevice.actions().first(), newValue.id());

            // WHEN
            const auto change2 = Qt3DCore::QPropertyNodeRemovedChangePtr::create(Qt3DCore::QNodeId(), &newValue);
            change2->setPropertyName("action");
            backendLogicalDevice.sceneChangeEvent(change2);

            // THEN
            QCOMPARE(backendLogicalDevice.actions().size(), 0);
        }
    }
bool DlgSetRDRPropertyByExpressionEditor::loadWidget(QSettings *settings, const QString &prefix)
{
    setExpression(settings->value(prefix+"expression").toString());
    setType(settings->value(prefix+"type").toInt());
    setPropertyName(settings->value(prefix+"property").toString());
    return true;
}
示例#4
0
文件: texture.cpp 项目: RSATom/Qt
void Texture::notifyStatus(QAbstractTexture::Status status)
{
    auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(peerId());
    change->setDeliveryFlags(Qt3DCore::QSceneChange::Nodes);
    change->setPropertyName("status");
    change->setValue(status);
    notifyObservers(change);
}
示例#5
0
文件: qnode.cpp 项目: RSATom/Qt
void QNodePrivate::notifyDynamicPropertyChange(const QByteArray &name, const QVariant &value)
{
    // Bail out early if we can to avoid operator new
    if (m_blockNotifications)
        return;

    auto e = QDynamicPropertyUpdatedChangePtr::create(m_id);
    e->setPropertyName(name);
    e->setValue(value);
    notifyObservers(e);
}
HidingStateChanger::HidingStateChanger(QObject* target, const QByteArray property, QObject* parent)
    : ItemVisibilityController(parent)
{
    connect(this, SIGNAL(propertiesAssigned(bool)),
            this, SLOT(slotPropertiesAssigned(bool)));

    setTargetObject(target);
    setPropertyName(property);

    // here, we assume to start with a visible item
    setVisible(true);
}
示例#7
0
void BoundingVolumeDebug::setRadius(float radius)
{
    if (m_radius != radius) {
        m_radius = radius;
        auto e = Qt3DCore::QPropertyUpdatedChangePtr::create(peerdId());
        e->setDeliveryFlags(Qt3DCore::QSceneChange::DeliverToAll);
        e->setPropertyName("radius");
        e->setTargetNode(peerId());
        e->setValue(QVariant(radius));
        notifyObservers(e);
    }
}
示例#8
0
void BoundingVolumeDebug::setCenter(const QVector3D &center)
{
    if (m_center != center) {
        m_center = center;
        auto e = Qt3DCore::QPropertyUpdatedChangePtr::create(peerdId());
        e->setDeliveryFlags(Qt3DCore::QSceneChange::DeliverToAll);
        e->setPropertyName("center");
        e->setTargetNode(peerId());
        e->setValue(QVariant::fromValue(center));
        notifyObservers(e);
    }
}
示例#9
0
文件: qeffect.cpp 项目: RSATom/Qt
/*!
 * Removes a technique \a t from the effect.
 */
void QEffect::removeTechnique(QTechnique *t)
{
    Q_D(QEffect);
    if (t && d->m_changeArbiter != nullptr) {
        const auto change = QPropertyNodeRemovedChangePtr::create(id(), t);
        change->setPropertyName("technique");
        d->notifyObservers(change);
    }
    d->m_techniques.removeOne(t);
    // Remove bookkeeping connection
    d->unregisterDestructionHelper(t);
}
示例#10
0
文件: qeffect.cpp 项目: RSATom/Qt
/*!
 * Removes a parameter \a parameter from the effect.
 */
void QEffect::removeParameter(QParameter *parameter)
{
    Q_D(QEffect);

    if (parameter && d->m_changeArbiter != nullptr) {
        const auto change = QPropertyNodeRemovedChangePtr::create(id(), parameter);
        change->setPropertyName("parameter");
        d->notifyObservers(change);
    }
    d->m_parameters.removeOne(parameter);
    // Remove bookkeeping connection
    d->unregisterDestructionHelper(parameter);
}
示例#11
0
/*!
    Removes a chosen output via \a output.
 */
void QRenderTarget::removeOutput(QRenderTargetOutput *output)
{
    Q_D(QRenderTarget);

    if (output && d->m_changeArbiter != nullptr) {
        const auto change = QPropertyNodeRemovedChangePtr::create(id(), output);
        change->setPropertyName("output");
        d->notifyObservers(change);
    }
    d->m_outputs.removeOne(output);
    // Remove bookkeeping connection
    d->unregisterDestructionHelper(output);
}
示例#12
0
/*!
    Sets the geometry \a factory.
 */
void QGeometryRenderer::setGeometryFactory(const QGeometryFactoryPtr &factory)
{
    Q_D(QGeometryRenderer);
    if (factory && d->m_geometryFactory && *factory == *d->m_geometryFactory)
        return;
    d->m_geometryFactory = factory;
    if (d->m_changeArbiter != nullptr) {
        auto change = QPropertyUpdatedChangePtr::create(d->m_id);
        change->setPropertyName("geometryFactory");
        change->setValue(QVariant::fromValue(d->m_geometryFactory));
        d->notifyObservers(change);
    }
}
示例#13
0
文件: qnode.cpp 项目: RSATom/Qt
/*!
 * \internal
 *
 * Called by _q_setParentHelper on the main thread.
 */
void QNodePrivate::_q_removeChild(QNode *childNode)
{
    Q_ASSERT(childNode);
    Q_ASSERT_X(childNode->parent() == q_func(), Q_FUNC_INFO, "not a child of this node");

    QNodePrivate::get(childNode)->m_parentId = QNodeId();

    // We notify the backend that we lost a child
    if (m_changeArbiter != nullptr) {
        const auto change = QPropertyNodeRemovedChangePtr::create(m_id, childNode);
        change->setPropertyName("children");
        notifyObservers(change);
    }
}
示例#14
0
void AnimationClip::setDuration(float duration)
{
    if (qFuzzyCompare(duration, m_duration))
        return;

    m_duration = duration;

    // Send a change to the frontend
    auto e = Qt3DCore::QPropertyUpdatedChangePtr::create(peerId());
    e->setDeliveryFlags(Qt3DCore::QSceneChange::DeliverToAll);
    e->setPropertyName("duration");
    e->setValue(m_duration);
    notifyObservers(e);
}
示例#15
0
文件: texture.cpp 项目: RSATom/Qt
void Texture::updateFromData(QTextureDataPtr data)
{
    if (data->width() != m_properties.width) {
        m_properties.width = data->width();
        auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(peerId());
        change->setDeliveryFlags(Qt3DCore::QSceneChange::Nodes);
        change->setPropertyName("width");
        change->setValue(data->width());
        notifyObservers(change);
    }

    if (data->height() != m_properties.height) {
        m_properties.height = data->height();
        auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(peerId());
        change->setDeliveryFlags(Qt3DCore::QSceneChange::Nodes);
        change->setPropertyName("height");
        change->setValue(data->height());
        notifyObservers(change);
    }

    if (data->depth() != m_properties.depth) {
        m_properties.depth = data->depth();
        auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(peerId());
        change->setDeliveryFlags(Qt3DCore::QSceneChange::Nodes);
        change->setPropertyName("depth");
        change->setValue(data->depth());
        notifyObservers(change);
    }

    if (data->layers() != m_properties.layers) {
        m_properties.layers = data->layers();
        auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(peerId());
        change->setDeliveryFlags(Qt3DCore::QSceneChange::Nodes);
        change->setPropertyName("layers");
        change->setValue(data->layers());
        notifyObservers(change);
    }

    if (data->format() != m_properties.format) {
        m_properties.format = data->format();
        auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(peerId());
        change->setDeliveryFlags(Qt3DCore::QSceneChange::Nodes);
        change->setPropertyName("format");
        change->setValue(data->format());
        notifyObservers(change);
    }

    if (data->target() != m_properties.target) {
        // TODO frontend property is actually constant
        m_properties.target = data->target();
        auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(peerId());
        change->setDeliveryFlags(Qt3DCore::QSceneChange::Nodes);
        change->setPropertyName("target");
        change->setValue(data->target());
        notifyObservers(change);
    }
}
示例#16
0
void PhysicalDeviceProxy::setDevice(QAbstractPhysicalDevice *device)
{
    m_physicalDeviceId = Qt3DCore::QNodeId();
    // Move the device to the main thread
    if (device != nullptr) {
        m_physicalDeviceId = device->id();
        device->moveToThread(QCoreApplication::instance()->thread());
    }

    auto e = Qt3DCore::QPropertyUpdatedChangePtr::create(peerId());
    e->setDeliveryFlags(Qt3DCore::QSceneChange::DeliverToAll);
    e->setPropertyName("device");
    e->setValue(QVariant::fromValue(device));
    notifyObservers(e);
}
示例#17
0
PHISlideAnimation::PHISlideAnimation(PHIBaseItem *item, qreal orgHeight, bool upDir )
    : QPropertyAnimation( item ), _item( item ), _orgHeight( orgHeight ), _upDir( upDir )
{
    setTargetObject( item );
    setPropertyName( "_height" );
    connect( this, &QPropertyAnimation::finished, this, &PHISlideAnimation::slotFinished );
    connect( this, &QPropertyAnimation::stateChanged, this, &PHISlideAnimation::slotStateChanged );
    if ( _upDir ) {
        setStartValue( _orgHeight );
        setEndValue( 0 );
    } else {
        setStartValue( 0 );
        setEndValue( _orgHeight );
    }
}
示例#18
0
文件: qinputchord.cpp 项目: RSATom/Qt
/*!
    Remove the QAbstractActionInput \a input from this QInputChord's chord vector.

    \sa addChord
 */
void QInputChord::removeChord(QAbstractActionInput *input)
{
    Q_D(QInputChord);
    if (d->m_chords.contains(input)) {

        if (d->m_changeArbiter != nullptr) {
            const auto change = Qt3DCore::QPropertyNodeRemovedChangePtr::create(id(), input);
            change->setPropertyName("chord");
            d->notifyObservers(change);
        }

        d->m_chords.removeOne(input);

        // Remove bookkeeping connection
        d->unregisterDestructionHelper(input);
    }
}
int QPropertyAnimation::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
    _id = QVariantAnimation::qt_metacall(_c, _id, _a);
    if (_id < 0)
        return _id;

#ifndef QT_NO_PROPERTIES
    if (_c == QMetaObject::ReadProperty) {
        void *_v = _a[0];
        switch (_id) {
        case 0:
            *reinterpret_cast< QByteArray*>(_v) = propertyName();
            break;
        case 1:
            *reinterpret_cast< QObject**>(_v) = targetObject();
            break;
        }
        _id -= 2;
    } else if (_c == QMetaObject::WriteProperty) {
        void *_v = _a[0];
        switch (_id) {
        case 0:
            setPropertyName(*reinterpret_cast< QByteArray*>(_v));
            break;
        case 1:
            setTargetObject(*reinterpret_cast< QObject**>(_v));
            break;
        }
        _id -= 2;
    } else if (_c == QMetaObject::ResetProperty) {
        _id -= 2;
    } else if (_c == QMetaObject::QueryPropertyDesignable) {
        _id -= 2;
    } else if (_c == QMetaObject::QueryPropertyScriptable) {
        _id -= 2;
    } else if (_c == QMetaObject::QueryPropertyStored) {
        _id -= 2;
    } else if (_c == QMetaObject::QueryPropertyEditable) {
        _id -= 2;
    } else if (_c == QMetaObject::QueryPropertyUser) {
        _id -= 2;
    }
#endif // QT_NO_PROPERTIES
    return _id;
}
示例#20
0
/*!
    Adds a chosen output via \a output.
 */
void QRenderTarget::addOutput(QRenderTargetOutput *output)
{
    Q_D(QRenderTarget);
    if (output && !d->m_outputs.contains(output)) {
        d->m_outputs.append(output);

        // Ensures proper bookkeeping
        d->registerDestructionHelper(output, &QRenderTarget::removeOutput, d->m_outputs);

        if (!output->parent())
            output->setParent(this);

        if (d->m_changeArbiter != nullptr) {
            const auto change = QPropertyNodeAddedChangePtr::create(id(), output);
            change->setPropertyName("output");
            d->notifyObservers(change);
        }
    }
}
示例#21
0
文件: qinputchord.cpp 项目: RSATom/Qt
/*!
    Append the QAbstractActionInput \a input to the end of this QInputChord's chord vector.

    \sa removeChord
 */
void QInputChord::addChord(QAbstractActionInput *input)
{
    Q_D(QInputChord);
    if (!d->m_chords.contains(input)) {
        d->m_chords.push_back(input);

        // Ensures proper bookkeeping
        d->registerDestructionHelper(input, &QInputChord::removeChord, d->m_chords);

        if (!input->parent())
            input->setParent(this);

        if (d->m_changeArbiter != nullptr) {
            const auto change = Qt3DCore::QPropertyNodeAddedChangePtr::create(id(), input);
            change->setPropertyName("chord");
            d->notifyObservers(change);
        }
    }
}
示例#22
0
文件: qnode.cpp 项目: RSATom/Qt
/*!
 * \internal
 *
 * Called by _q_setParentHelper() or _q_postConstructorInit()
 * on the main thread.
 */
void QNodePrivate::_q_addChild(QNode *childNode)
{
    Q_ASSERT(childNode);
    Q_ASSERT_X(childNode->parent() == q_func(), Q_FUNC_INFO,  "not a child of this node");

    // Have we already notified the parent about its new child? If so, bail out
    // early so that we do not send more than one new child event to the backend
    QNodePrivate *childD = QNodePrivate::get(childNode);
    if (childD->m_notifiedParent == true)
        return;

    // Store our id as the parentId in the child so that even if the child gets
    // removed from the scene as part of the destruction of the parent, when the
    // parent's children are deleted in the QObject dtor, we still have access to
    // the parentId. If we didn't store this, we wouldn't have access at that time
    // because the parent would then only be a QObject, the QNode part would have
    // been destroyed already.
    childD->m_parentId = m_id;

    if (!m_scene)
        return;

    // We need to send a QPropertyNodeAddedChange to the backend
    // to notify the backend that we have a new child
    if (m_changeArbiter != nullptr) {
        // Flag that we have notified the parent. We do this immediately before
        // creating the change because that recurses back into this function and
        // we need to catch that to avoid sending more than one new child event
        // to the backend.
        childD->m_notifiedParent = true;
        const auto change = QPropertyNodeAddedChangePtr::create(m_id, childNode);
        change->setPropertyName("children");
        notifyObservers(change);
    }

    // Update the scene
    // TODO: Fold this into the QNodeCreatedChangeGenerator so we don't have to
    // traverse the sub tree three times!
    QNodeVisitor visitor;
    visitor.traverse(childNode, this, &QNodePrivate::addEntityComponentToScene);
}
示例#23
0
文件: qnode.cpp 项目: RSATom/Qt
/*!
 * \internal
 *
 * Notify the backend that the parent lost this node as a child and
 * that this node is being destroyed. We only send the node removed
 * change for the parent's children property iff we have an id for
 * a parent node. This is set/unset in the _q_addChild()/_q_removeChild()
 * functions (and initialized in init() if there is a parent at
 * construction time).
 *
 * Likewise, we only send the node destroyed change, iff we have
 * previously sent a node created change. This is tracked via the
 * m_hasBackendNode member.
 */
void QNodePrivate::notifyDestructionChangesAndRemoveFromScene()
{
    Q_Q(QNode);

    // We notify the backend that the parent lost us as a child
    if (m_changeArbiter != nullptr && !m_parentId.isNull()) {
        const auto change = QPropertyNodeRemovedChangePtr::create(m_parentId, q);
        change->setPropertyName("children");
        notifyObservers(change);
    }

    // Tell the backend we are about to be destroyed
    if (m_hasBackendNode) {
        const QDestructionIdAndTypeCollector collector(q);
        const auto destroyedChange = QNodeDestroyedChangePtr::create(q, collector.subtreeIdsAndTypes());
        notifyObservers(destroyedChange);
    }

    // We unset the scene from the node as its backend node was/is about to be destroyed
    QNodeVisitor visitor;
    visitor.traverse(q, this, &QNodePrivate::unsetSceneHelper);
}
示例#24
0
文件: qeffect.cpp 项目: RSATom/Qt
/*!
 * Adds \a parameter to the effect. It sends a QPropertyNodeAddedChange to the backend.
 * The \a parameter will be used to set a corresponding uniform value in the shader used
 * by this effect.
 */
void QEffect::addParameter(QParameter *parameter)
{
    Q_D(QEffect);
    if (parameter && !d->m_parameters.contains(parameter)) {
        d->m_parameters.append(parameter);

        // Ensures proper bookkeeping
        d->registerDestructionHelper(parameter, &QEffect::removeParameter, d->m_parameters);

        // We need to add it as a child of the current node if it has been declared inline
        // Or not previously added as a child of the current node so that
        // 1) The backend gets notified about it's creation
        // 2) When the current node is destroyed, it gets destroyed as well
        if (!parameter->parent())
            parameter->setParent(this);

        if (d->m_changeArbiter != nullptr) {
            const auto change = QPropertyNodeAddedChangePtr::create(id(), parameter);
            change->setPropertyName("parameter");
            d->notifyObservers(change);
        }
    }
}
示例#25
0
文件: qeffect.cpp 项目: RSATom/Qt
/*!
 * Adds a new technique \a t to the effect. It sends a QPropertyNodeAddedChange to the backend.
 */
void QEffect::addTechnique(QTechnique *t)
{
    Q_ASSERT(t);
    Q_D(QEffect);
    if (t && !d->m_techniques.contains(t)) {
        d->m_techniques.append(t);

        // Ensures proper bookkeeping
        d->registerDestructionHelper(t, &QEffect::removeTechnique, d->m_techniques);

        // We need to add it as a child of the current node if it has been declared inline
        // Or not previously added as a child of the current node so that
        // 1) The backend gets notified about it's creation
        // 2) When the current node is destroyed, tit gets destroyed as well
        if (!t->parent())
            t->setParent(this);

        if (d->m_changeArbiter != nullptr) {
            const auto change = QPropertyNodeAddedChangePtr::create(id(), t);
            change->setPropertyName("technique");
            d->notifyObservers(change);
        }
    }
}
/*!
    Construct a QtPropertyAnimation object. \a parent is passed to QObject's
    constructor. The animation changes the property \a propertyName on \a
    target. The default duration is 250ms.

    \sa targetObject, propertyName
*/
QtPropertyAnimation::QtPropertyAnimation(QObject *target, const QByteArray &propertyName, QObject *parent)
    : QtVariantAnimation(*new QtPropertyAnimationPrivate, parent)
{
    setTargetObject(target);
    setPropertyName(propertyName);
}
示例#27
0
    void checkPropertyChanges()
    {
        // GIVEN
        Qt3DAnimation::Animation::Handler handler;
        Qt3DAnimation::Animation::ChannelMapper backendMapper;
        backendMapper.setHandler(&handler);
        Qt3DCore::QPropertyUpdatedChangePtr updateChange;

        // WHEN
        updateChange = QSharedPointer<Qt3DCore::QPropertyUpdatedChange>::create(Qt3DCore::QNodeId());
        updateChange->setPropertyName("enabled");
        updateChange->setValue(true);
        backendMapper.sceneChangeEvent(updateChange);

        // THEN
        QCOMPARE(backendMapper.isEnabled(), true);

        // WHEN
        Qt3DAnimation::QChannelMapping mapping;
        const Qt3DCore::QNodeId mappingId = mapping.id();
        Qt3DAnimation::Animation::ChannelMapping *backendMapping
                = handler.channelMappingManager()->getOrCreateResource(mappingId);
        backendMapping->setHandler(&handler);
        simulateInitialization(&mapping, backendMapping);

        auto nodeAddedChange = Qt3DCore::QPropertyNodeAddedChangePtr::create(Qt3DCore::QNodeId(), &mapping);
        nodeAddedChange->setPropertyName("mappings");
        backendMapper.sceneChangeEvent(nodeAddedChange);

        // THEN
        QCOMPARE(backendMapper.mappingIds().size(), 1);
        QCOMPARE(backendMapper.mappingIds().first(), mappingId);
        QCOMPARE(backendMapper.mappings().size(), 1);
        QCOMPARE(backendMapper.mappings().first(), backendMapping);

        // WHEN
        Qt3DAnimation::QChannelMapping mapping2;
        const Qt3DCore::QNodeId mappingId2 = mapping2.id();
        Qt3DAnimation::Animation::ChannelMapping *backendMapping2
                = handler.channelMappingManager()->getOrCreateResource(mappingId2);
        backendMapping2->setHandler(&handler);
        simulateInitialization(&mapping2, backendMapping2);

        nodeAddedChange = Qt3DCore::QPropertyNodeAddedChangePtr::create(Qt3DCore::QNodeId(), &mapping2);
        nodeAddedChange->setPropertyName("mappings");
        backendMapper.sceneChangeEvent(nodeAddedChange);

        // THEN
        QCOMPARE(backendMapper.mappingIds().size(), 2);
        QCOMPARE(backendMapper.mappingIds().first(), mappingId);
        QCOMPARE(backendMapper.mappingIds().last(), mappingId2);
        QCOMPARE(backendMapper.mappings().size(), 2);
        QCOMPARE(backendMapper.mappings().first(), backendMapping);
        QCOMPARE(backendMapper.mappings().last(), backendMapping2);

        // WHEN
        const auto nodeRemovedChange = Qt3DCore::QPropertyNodeRemovedChangePtr::create(Qt3DCore::QNodeId(), &mapping);
        nodeRemovedChange->setPropertyName("mappings");
        backendMapper.sceneChangeEvent(nodeRemovedChange);

        // THEN
        QCOMPARE(backendMapper.mappingIds().size(), 1);
        QCOMPARE(backendMapper.mappingIds().first(), mappingId2);
        QCOMPARE(backendMapper.mappings().size(), 1);
        QCOMPARE(backendMapper.mappings().first(), backendMapping2);
    }