summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@qt.io>2018-07-09 15:43:40 +0200
committerLaszlo Agocs <laszlo.agocs@qt.io>2018-07-10 08:03:39 +0000
commitdc04968027163c9698b872498f7856a0e56088cc (patch)
tree6d02cead24ec47764092a37654a86b15ebdab39f
parent280abea92d6174f8082e6825d06abd982f12b9cc (diff)
Do not leak attached objects when removing and readding
The attached object should go away when an object gets disconnected from a scene (or master slide). It is recreated when the object gets added into a scene (or master slide) hierarchy again. To exercise this, the console's setparent() now works as expected, supporting both unparenting (with a 'null' parent) and reparenting. Change-Id: I70d69300d7fbab6a48b33d7082b2fb9fa9fe1e7e Reviewed-by: Andy Nichols <andy.nichols@qt.io>
-rw-r--r--src/runtime/q3dsconsolecommands.cpp19
-rw-r--r--src/runtime/q3dsscenemanager.cpp15
2 files changed, 27 insertions, 7 deletions
diff --git a/src/runtime/q3dsconsolecommands.cpp b/src/runtime/q3dsconsolecommands.cpp
index 2da5a8a..bfe9e1b 100644
--- a/src/runtime/q3dsconsolecommands.cpp
+++ b/src/runtime/q3dsconsolecommands.cpp
@@ -148,7 +148,7 @@ void Q3DSConsoleCommands::setupConsole(Q3DSConsole *console)
"\n"
"object(id, name, type, parentObj, slide) - Creates a new object. (type == Model, DefaultMaterial, ...; parent and slide may be null) [R]\n"
"primitive(id, name, source, parentObj, slide) - Shortcut to add a model with a default material. (source == #Cube, #Cone, etc.) [R]\n"
- "setparent(obj, parentObj) - Sets the parent (only valid when object()/primitive() was called with parentObj == null) [R]\n"
+ "setparent(obj, parentObj) - Sets the parent (may be null). [R]\n"
"kill(obj) - Removes a node from the scene graph (and from the slides' object list). [R]\n"
"objslideadd(obj, slide) - Associates the object with the given slide. [R]\n"
"objslideremove(obj, slide) - Removes the object from the slide's objject list. [R]\n"
@@ -438,9 +438,20 @@ void Q3DSConsoleCommands::setupConsole(Q3DSConsole *console)
if (splitArgs.count() >= 2) {
Q3DSGraphObject *obj = resolveObj(splitArgs[0]);
Q3DSGraphObject *parent = resolveObj(splitArgs[1]);
- if (obj && parent) {
- parent->appendChildNode(obj);
- m_console->addMessageFmt(responseColor, "Appended as child node");
+ if (obj) {
+ if (parent) {
+ if (obj->parent() != parent) {
+ if (obj->parent())
+ obj->parent()->removeChildNode(obj);
+ parent->appendChildNode(obj);
+ m_console->addMessageFmt(responseColor, "Reparented");
+ }
+ } else {
+ if (obj->parent()) {
+ obj->parent()->removeChildNode(obj);
+ m_console->addMessageFmt(responseColor, "Unparented");
+ }
+ }
}
}
}, Q3DSConsole::CmdRecordable));
diff --git a/src/runtime/q3dsscenemanager.cpp b/src/runtime/q3dsscenemanager.cpp
index b89f254..b4cb002 100644
--- a/src/runtime/q3dsscenemanager.cpp
+++ b/src/runtime/q3dsscenemanager.cpp
@@ -8081,11 +8081,13 @@ void Q3DSSceneManager::handleSceneChange(Q3DSScene *, Q3DSGraphObject::DirtyFlag
qCDebug(lcScene) << "Dyn.removing" << obj->attached()->entity;
Q3DSUipPresentation::forAllObjectsInSubTree(obj, [this](Q3DSGraphObject *objOrChild) {
+ Q3DSGraphObjectAttached *data = objOrChild->attached();
+ if (!data)
+ return;
Q3DSSlidePlayer *slidePlayer = m_slidePlayer;
- if (objOrChild->attached()->component)
- slidePlayer = objOrChild->attached()->component->masterSlide()->attached<Q3DSSlideAttached>()->slidePlayer;
+ if (data->component)
+ slidePlayer = data->component->masterSlide()->attached<Q3DSSlideAttached>()->slidePlayer;
slidePlayer->objectAboutToBeRemovedFromScene(objOrChild);
- Q3DSGraphObjectAttached *data = objOrChild->attached();
if (data->propertyChangeObserverIndex >= 0) {
objOrChild->removePropertyChangeObserver(data->propertyChangeObserverIndex);
data->propertyChangeObserverIndex = -1;
@@ -8102,6 +8104,11 @@ void Q3DSSceneManager::handleSceneChange(Q3DSScene *, Q3DSGraphObject::DirtyFlag
removeLayerContent(obj, layer3DS);
}
}
+ // bye bye attached; it will get recreated in case obj gets added back later on
+ if (obj->attached()) {
+ delete obj->attached();
+ obj->setAttached(nullptr);
+ }
}
}
@@ -8189,6 +8196,8 @@ void Q3DSSceneManager::handleSlideGraphChange(Q3DSSlide *master, Q3DSGraphObject
slide->removeSlideObjectChangeObserver(data->slideObjectChangeObserverIndex);
data->slideObjectChangeObserverIndex = -1;
}
+ delete data;
+ slide->setAttached(nullptr);
}
}