summaryrefslogtreecommitdiffstats
path: root/src/Runtime
diff options
context:
space:
mode:
authorMiikka Heikkinen <miikka.heikkinen@qt.io>2019-04-30 14:09:34 +0300
committerMiikka Heikkinen <miikka.heikkinen@qt.io>2019-05-07 08:47:09 +0000
commitee62a1cd82e7f6dc3b16d9935fc148f3c48c8f46 (patch)
treefe117785f310373976c74300e4c440af3a640d49 /src/Runtime
parent988f62c763eef90e4dafe9ecf6bb05629279278e (diff)
Add deleteElement to C++ API
Add possibility to delete elements that have been added with createElement. Task-number: QT3DS-3374 Change-Id: I701e565241d18294171cd63ef934083f627b89aa Reviewed-by: Tomi Korpipää <tomi.korpipaa@qt.io>
Diffstat (limited to 'src/Runtime')
-rw-r--r--src/Runtime/Source/engine/Qt3DSRenderRuntimeBindingImpl.h4
-rw-r--r--src/Runtime/Source/engine/Qt3DSRuntimeView.cpp16
-rw-r--r--src/Runtime/Source/engine/Qt3DSRuntimeView.h1
-rw-r--r--src/Runtime/Source/runtime/Qt3DSIScriptBridge.h2
-rw-r--r--src/Runtime/Source/runtime/Qt3DSQmlEngine.cpp76
-rw-r--r--src/Runtime/Source/runtime/Qt3DSSlideSystem.cpp41
-rw-r--r--src/Runtime/Source/runtime/Qt3DSSlideSystem.h2
-rw-r--r--src/Runtime/Source/viewer/Qt3DSViewerApp.cpp8
-rw-r--r--src/Runtime/Source/viewer/Qt3DSViewerApp.h1
9 files changed, 144 insertions, 7 deletions
diff --git a/src/Runtime/Source/engine/Qt3DSRenderRuntimeBindingImpl.h b/src/Runtime/Source/engine/Qt3DSRenderRuntimeBindingImpl.h
index c174d4a7..92cb8658 100644
--- a/src/Runtime/Source/engine/Qt3DSRenderRuntimeBindingImpl.h
+++ b/src/Runtime/Source/engine/Qt3DSRenderRuntimeBindingImpl.h
@@ -190,8 +190,8 @@ namespace render {
static Qt3DSTranslator *GetTranslatorFromGraphNode(SGraphObject &inObject);
static Qt3DSTranslator *CreateTranslatorForElement(Q3DStudio::TElement &inElement,
- SGraphObject &inGraphObject,
- NVAllocatorCallback &inAlloc);
+ SGraphObject &inGraphObject,
+ NVAllocatorCallback &inAlloc);
static Q3DStudio::IPresentation *
GetPresentationFromPresentation(SPresentation &inPresentation);
static void InitializePointerTags(IStringTable &inTable);
diff --git a/src/Runtime/Source/engine/Qt3DSRuntimeView.cpp b/src/Runtime/Source/engine/Qt3DSRuntimeView.cpp
index abff8f09..9863031d 100644
--- a/src/Runtime/Source/engine/Qt3DSRuntimeView.cpp
+++ b/src/Runtime/Source/engine/Qt3DSRuntimeView.cpp
@@ -217,6 +217,7 @@ public:
void createElement(const QString &parentElementPath, const QString &slideName,
const QHash<QString, QVariant> &properties) override;
+ void deleteElement(const QString &elementPath) override;
void SetAttribute(const char *elementPath, const char *attributeName,
const char *value) override;
bool GetAttribute(const char *elementPath, const char *attributeName, void *value) override;
@@ -615,7 +616,7 @@ float CRuntimeView::dataInputMin(const QString &name) const
}
void CRuntimeView::createElement(const QString &parentElementPath, const QString &slideName,
- const QHash<QString, QVariant> &properties)
+ const QHash<QString, QVariant> &properties)
{
if (m_Application) {
Q3DStudio::CQmlEngine &theBridgeEngine
@@ -625,7 +626,18 @@ void CRuntimeView::createElement(const QString &parentElementPath, const QString
}
}
-void CRuntimeView::SetAttribute(const char *elementPath, const char *attributeName, const char *value)
+void CRuntimeView::deleteElement(const QString &elementPath)
+{
+ if (m_Application) {
+ Q3DStudio::CQmlEngine &theBridgeEngine
+ = static_cast<Q3DStudio::CQmlEngine &>(m_RuntimeFactoryCore->GetScriptEngineQml());
+ theBridgeEngine.deleteElement(elementPath,
+ &m_RuntimeFactory->GetQt3DSRenderContext().GetRenderer());
+ }
+}
+
+void CRuntimeView::SetAttribute(const char *elementPath, const char *attributeName,
+ const char *value)
{
if (m_Application) {
if (!elementPath || !attributeName || !value)
diff --git a/src/Runtime/Source/engine/Qt3DSRuntimeView.h b/src/Runtime/Source/engine/Qt3DSRuntimeView.h
index 3626fd52..776fbea2 100644
--- a/src/Runtime/Source/engine/Qt3DSRuntimeView.h
+++ b/src/Runtime/Source/engine/Qt3DSRuntimeView.h
@@ -191,6 +191,7 @@ public:
virtual float dataInputMin(const QString &name) const = 0;
virtual void createElement(const QString &parentElementPath, const QString &slideName,
const QHash<QString, QVariant> &properties) = 0;
+ virtual void deleteElement(const QString &elementPath) = 0;
virtual void SetAttribute(const char *elementPath, const char *attributeName,
const char *value) = 0;
virtual bool GetAttribute(const char *elementPath, const char *attributeName, void *value) = 0;
diff --git a/src/Runtime/Source/runtime/Qt3DSIScriptBridge.h b/src/Runtime/Source/runtime/Qt3DSIScriptBridge.h
index 3b26abd2..2aa59339 100644
--- a/src/Runtime/Source/runtime/Qt3DSIScriptBridge.h
+++ b/src/Runtime/Source/runtime/Qt3DSIScriptBridge.h
@@ -161,6 +161,8 @@ public: // Elements
virtual void createElement(const QString &parentElementPath, const QString &slideName,
const QHash<QString, QVariant> &properties,
qt3ds::render::IQt3DSRenderer *renderer) = 0;
+ virtual void deleteElement(const QString &elementPath,
+ qt3ds::render::IQt3DSRenderer *renderer) = 0;
public: // Components
virtual void GotoSlide(const char *component, const char *slideName,
diff --git a/src/Runtime/Source/runtime/Qt3DSQmlEngine.cpp b/src/Runtime/Source/runtime/Qt3DSQmlEngine.cpp
index 23a097a7..86f68bdd 100644
--- a/src/Runtime/Source/runtime/Qt3DSQmlEngine.cpp
+++ b/src/Runtime/Source/runtime/Qt3DSQmlEngine.cpp
@@ -420,6 +420,8 @@ public:
void createElement(const QString &parentElementPath, const QString &slideName,
const QHash<QString, QVariant> &properties,
qt3ds::render::IQt3DSRenderer *renderer) override;
+ void deleteElement(const QString &elementPath,
+ qt3ds::render::IQt3DSRenderer *renderer) override;
//void createMaterial() override; // TODO (QT3DS-3377)
//void createMesh() override; // TODO (QT3DS-3378)
@@ -1042,7 +1044,6 @@ void CQmlEngineImpl::createElement(const QString &parentElementPath, const QStri
return;
}
-
// First check if we can resolve the referenced material before creating any graph objects
// Find a match in material container
// If the specified material is not available in original presentation, or was not specified,
@@ -1086,7 +1087,7 @@ void CQmlEngineImpl::createElement(const QString &parentElementPath, const QStri
}
}
- // Create new SGraphObject (SNode)
+ // Create model SGraphObject
NVAllocatorCallback &allocator = presentation->GetScene()->allocator();
qt3ds::render::SModel *newObject = QT3DS_NEW(allocator, qt3ds::render::SModel)();
newObject->m_Id = strTable.RegisterStr((QByteArrayLiteral("_newObject_")
@@ -1124,6 +1125,77 @@ void CQmlEngineImpl::createElement(const QString &parentElementPath, const QStri
renderer->ChildrenUpdated(parentObject);
}
+// Only supports deleting element types that can be added via createElement.
+void CQmlEngineImpl::deleteElement(const QString &elementPath,
+ qt3ds::render::IQt3DSRenderer *renderer)
+{
+ // Resolve element
+ QByteArray thePath = elementPath.toUtf8();
+ TElement *element = getTarget(thePath.constData());
+
+ if (!element) {
+ qWarning() << __FUNCTION__ << "Invalid element:" << elementPath;
+ return;
+ }
+
+ // Remove element recursively from slide system
+ IPresentation *presentation = element->GetBelongedPresentation();
+ TElement &component = element->GetComponentParent();
+ ISlideSystem &slideSystem = presentation->GetSlideSystem();
+ slideSystem.removeElement(component, *element);
+
+ TElement *parentElement = element->GetParent();
+ Q_ASSERT(parentElement);
+
+ NVAllocatorCallback &allocator = presentation->GetScene()->allocator();
+
+ // Recursive deleter for translators and graph objects
+ std::function<void(TElement *)> deleteRenderObjects;
+ deleteRenderObjects = [&](TElement *elem) {
+ TElement *child = elem->m_Child;
+ while (child) {
+ TElement *sibling = child->m_Sibling;
+ deleteRenderObjects(child);
+ child = sibling;
+ }
+
+ auto translator = static_cast<qt3ds::render::Qt3DSTranslator *>(elem->GetAssociation());
+ if (translator) {
+ if (translator->GetUIPType() == qt3ds::render::GraphObjectTypes::Model) {
+ auto model = static_cast<qt3ds::render::SModel *>(&translator->RenderObject());
+ // Delete material
+ if (model->m_FirstMaterial) {
+ auto material = static_cast<qt3ds::render::SReferencedMaterial *>(
+ model->m_FirstMaterial);
+ QT3DS_FREE(allocator, material);
+ }
+ QT3DS_FREE(allocator, model);
+ }
+ QT3DS_FREE(allocator, translator);
+ }
+ };
+
+ qt3ds::render::SNode *node = nullptr;
+ qt3ds::render::SNode *parentNode = nullptr;
+ auto translator = static_cast<qt3ds::render::Qt3DSTranslator *>(element->GetAssociation());
+
+ if (translator) {
+ node = &static_cast<qt3ds::render::SNode &>(translator->RenderObject());
+ auto parentTranslator = static_cast<qt3ds::render::Qt3DSTranslator *>(
+ parentElement->GetAssociation());
+ if (parentTranslator) {
+ parentNode = &static_cast<qt3ds::render::SNode &>(parentTranslator->RenderObject());
+ parentNode->RemoveChild(*node);
+ renderer->ChildrenUpdated(*parentNode);
+ }
+ // Release child element graph objects/translators
+ deleteRenderObjects(element);
+ }
+
+ // Remove element recursively
+ m_Application->GetElementAllocator().ReleaseElement(*element, true);
+}
+
void CQmlEngineImpl::GotoSlide(const char *component, const char *slideName,
const SScriptEngineGotoSlideArgs &inArgs)
{
diff --git a/src/Runtime/Source/runtime/Qt3DSSlideSystem.cpp b/src/Runtime/Source/runtime/Qt3DSSlideSystem.cpp
index 3e2f95c2..33c7544d 100644
--- a/src/Runtime/Source/runtime/Qt3DSSlideSystem.cpp
+++ b/src/Runtime/Source/runtime/Qt3DSSlideSystem.cpp
@@ -255,7 +255,6 @@ struct SSlideSystem : public ISlideSystem
}
}
-
// The parent element must be found from target slide.
// Elements cannot be added to the master slide.
bool addSlideElement(element::SElement &inComponent, int slideIndex,
@@ -314,6 +313,46 @@ struct SSlideSystem : public ISlideSystem
return true;
}
+ void removeElementRecursive(SSlide *slide, element::SElement &inElement)
+ {
+ element::SElement *child = inElement.m_Child;
+ while (child) {
+ removeElementRecursive(slide, *child);
+ child = child->m_Sibling;
+ }
+
+ SSlideElement *slideElement = slide->m_FirstElement;
+ SSlideElement *previousElement = nullptr;
+ while (slideElement) {
+ if (slideElement->m_ElementHandle == inElement.m_Handle) {
+ if (slide->m_FirstElement == slideElement)
+ slide->m_FirstElement = slideElement->m_NextElement;
+ if (slide->m_lastElement == slideElement)
+ slide->m_lastElement = previousElement;
+ if (previousElement)
+ previousElement->m_NextElement = slideElement->m_NextElement;
+ m_SlideElements.deallocate(slideElement);
+ break;
+ }
+ previousElement = slideElement;
+ slideElement = slideElement->m_NextElement;
+ }
+ }
+
+ // Removes element and its children from all slides
+ void removeElement(element::SElement &inComponent, element::SElement &inElement) override
+ {
+ TComponentSlideHash::const_iterator theFindResult = m_Slides.find(&inComponent);
+ if (theFindResult == m_Slides.end()) {
+ qWarning() << __FUNCTION__ << "Could not find slides for component";
+ return;
+ }
+
+ SSlide *slide = theFindResult->second;
+ for (; slide; slide = slide->m_NextSlide)
+ removeElementRecursive(slide, inElement);
+ }
+
void AddSlideAttribute(Q3DStudio::SAttributeKey inKey, Q3DStudio::UVariant inValue) override
{
if (m_CurrentSlideElement) {
diff --git a/src/Runtime/Source/runtime/Qt3DSSlideSystem.h b/src/Runtime/Source/runtime/Qt3DSSlideSystem.h
index 3aa2a011..d3accbd3 100644
--- a/src/Runtime/Source/runtime/Qt3DSSlideSystem.h
+++ b/src/Runtime/Source/runtime/Qt3DSSlideSystem.h
@@ -128,6 +128,8 @@ namespace runtime {
virtual void AddSlideElement(element::SElement &inElement, bool inActive) = 0;
virtual bool addSlideElement(element::SElement &inComponent, int slideIndex,
element::SElement &inElement, bool eyeBall) = 0;
+ virtual void removeElement(element::SElement &inComponent,
+ element::SElement &inElement) = 0;
virtual void AddSlideAttribute(Q3DStudio::SAttributeKey inKey,
Q3DStudio::UVariant inValue) = 0;
virtual SSlideAnimAction *AddSlideAnimAction(bool inAnimation, QT3DSI32 inIndex,
diff --git a/src/Runtime/Source/viewer/Qt3DSViewerApp.cpp b/src/Runtime/Source/viewer/Qt3DSViewerApp.cpp
index 005eedcd..4dd5dbd9 100644
--- a/src/Runtime/Source/viewer/Qt3DSViewerApp.cpp
+++ b/src/Runtime/Source/viewer/Qt3DSViewerApp.cpp
@@ -803,6 +803,14 @@ void Q3DSViewerApp::createElement(const QString &parentElementPath, const QStrin
m_Impl.m_view->createElement(parentElementPath, slideName, properties);
}
+void Q3DSViewerApp::deleteElement(const QString &elementPath)
+{
+ if (!m_Impl.m_view)
+ return;
+
+ m_Impl.m_view->deleteElement(elementPath);
+}
+
Q3DSViewerApp &Q3DSViewerApp::Create(void *glContext, Q3DStudio::IAudioPlayer *inAudioPlayer,
QElapsedTimer *startupTimer)
{
diff --git a/src/Runtime/Source/viewer/Qt3DSViewerApp.h b/src/Runtime/Source/viewer/Qt3DSViewerApp.h
index a4bdc2e3..66a40e76 100644
--- a/src/Runtime/Source/viewer/Qt3DSViewerApp.h
+++ b/src/Runtime/Source/viewer/Qt3DSViewerApp.h
@@ -361,6 +361,7 @@ public:
void createElement(const QString &parentElementPath, const QString &slideName,
const QHash<QString, QVariant> &properties);
+ void deleteElement(const QString &elementPath);
QString error();