Commit 23467a77 authored by Marco Bubke's avatar Marco Bubke
Browse files

QmlDesigner.NodeInstance: Improve process restarting

parent d7709a02
......@@ -107,8 +107,8 @@ public:
NodeInstance instanceForNode(const ModelNode &node) const ;
bool hasInstanceForNode(const ModelNode &node) const;
NodeInstance instanceForId(qint32 id) const;
bool hasInstanceForId(qint32 id) const;
NodeInstance instanceForId(qint32 id);
bool hasInstanceForId(qint32 id);
QRectF sceneRect() const;
......@@ -131,8 +131,6 @@ private: // functions
NodeInstance loadNode(const ModelNode &node);
void loadNodes(const QList<ModelNode> &nodeList);
void removeAllInstanceNodeRelationships();
void removeRecursiveChildRelationship(const ModelNode &removedNode);
......@@ -147,7 +145,7 @@ private: // functions
NodeInstanceServerInterface *nodeInstanceServer() const;
CreateSceneCommand createCreateSceneCommand() const;
CreateSceneCommand createCreateSceneCommand();
ClearSceneCommand createClearSceneCommand() const;
CreateInstancesCommand createCreateInstancesCommand(const QList<NodeInstance> &instanceList) const;
CompleteComponentCommand createComponentCompleteCommand(const QList<NodeInstance> &instanceList) const;
......@@ -174,7 +172,6 @@ private: //variables
NodeInstance m_activeStateInstance;
QHash<ModelNode, NodeInstance> m_nodeInstanceHash;
QHash<qint32, NodeInstance> m_idInstanceHash; // This is purely internal. Might contain dangling pointers!
uint m_blockUpdates;
QWeakPointer<NodeInstanceServerInterface> m_nodeInstanceServer;
......
......@@ -6,13 +6,72 @@ CreateSceneCommand::CreateSceneCommand()
{
}
QDataStream &operator<<(QDataStream &out, const CreateSceneCommand &/*command*/)
CreateSceneCommand::CreateSceneCommand(const QVector<InstanceContainer> &instanceContainer,
const QVector<ReparentContainer> &reparentContainer,
const QVector<IdContainer> &idVector,
const QVector<PropertyValueContainer> &valueChangeVector,
const QVector<PropertyBindingContainer> &bindingChangeVector,
const QUrl &fileUrl)
: m_instanceVector(instanceContainer),
m_reparentInstanceVector(reparentContainer),
m_idVector(idVector),
m_valueChangeVector(valueChangeVector),
m_bindingChangeVector(bindingChangeVector),
m_fileUrl(fileUrl)
{
}
QVector<InstanceContainer> CreateSceneCommand::instances() const
{
return m_instanceVector;
}
QVector<ReparentContainer> CreateSceneCommand::reparentInstances() const
{
return m_reparentInstanceVector;
}
QVector<IdContainer> CreateSceneCommand::ids() const
{
return m_idVector;
}
QVector<PropertyValueContainer> CreateSceneCommand::valueChanges() const
{
return m_valueChangeVector;
}
QVector<PropertyBindingContainer> CreateSceneCommand::bindingChanges() const
{
return m_bindingChangeVector;
}
QUrl CreateSceneCommand::fileUrl() const
{
return m_fileUrl;
}
QDataStream &operator<<(QDataStream &out, const CreateSceneCommand &command)
{
out << command.instances();
out << command.reparentInstances();
out << command.ids();
out << command.valueChanges();
out << command.bindingChanges();
out << command.fileUrl();
return out;
}
QDataStream &operator>>(QDataStream &in, CreateSceneCommand &/*command*/)
QDataStream &operator>>(QDataStream &in, CreateSceneCommand &command)
{
in >> command.m_instanceVector;
in >> command.m_reparentInstanceVector;
in >> command.m_idVector;
in >> command.m_valueChangeVector;
in >> command.m_bindingChangeVector;
in >> command.m_fileUrl;
return in;
}
......
......@@ -2,6 +2,15 @@
#define CREATESCENECOMMAND_H
#include <qmetatype.h>
#include <QUrl>
#include <QVector>
#include "instancecontainer.h"
#include "reparentcontainer.h"
#include "idcontainer.h"
#include "propertyvaluecontainer.h"
#include "propertybindingcontainer.h"
namespace QmlDesigner {
......@@ -11,6 +20,27 @@ class CreateSceneCommand
public:
CreateSceneCommand();
CreateSceneCommand(const QVector<InstanceContainer> &instanceContainer,
const QVector<ReparentContainer> &reparentContainer,
const QVector<IdContainer> &idVector,
const QVector<PropertyValueContainer> &valueChangeVector,
const QVector<PropertyBindingContainer> &bindingChangeVector,
const QUrl &fileUrl);
QVector<InstanceContainer> instances() const;
QVector<ReparentContainer> reparentInstances() const;
QVector<IdContainer> ids() const;
QVector<PropertyValueContainer> valueChanges() const;
QVector<PropertyBindingContainer> bindingChanges() const;
QUrl fileUrl() const;
private:
QVector<InstanceContainer> m_instanceVector;
QVector<ReparentContainer> m_reparentInstanceVector;
QVector<IdContainer> m_idVector;
QVector<PropertyValueContainer> m_valueChangeVector;
QVector<PropertyBindingContainer> m_bindingChangeVector;
QUrl m_fileUrl;
};
QDataStream &operator<<(QDataStream &out, const CreateSceneCommand &command);
......
......@@ -38,6 +38,7 @@
#include "childrenchangedcommand.h"
#include "completecomponentcommand.h"
#include "componentcompletedcommand.h"
#include "createscenecommand.h"
#include <iostream>
#include <stdio.h>
......@@ -53,6 +54,11 @@ NodeInstanceServer::NodeInstanceServer(NodeInstanceClientInterface *nodeInstance
m_slowRenderTimer(false)
{
connect(m_childrenChangeEventFilter.data(), SIGNAL(childrenChanged(QObject*)), this, SLOT(emitParentChanged(QObject*)));
m_declarativeView = new QDeclarativeView;
m_declarativeView->setAttribute(Qt::WA_DontShowOnScreen, true);
m_declarativeView->setViewportUpdateMode(QGraphicsView::NoViewportUpdate);
m_declarativeView->show();
}
NodeInstanceServer::~NodeInstanceServer()
......@@ -60,11 +66,11 @@ NodeInstanceServer::~NodeInstanceServer()
delete m_declarativeView.data();
}
void NodeInstanceServer::createInstances(const CreateInstancesCommand &command)
QList<ServerNodeInstance> NodeInstanceServer::createInstances(const QVector<InstanceContainer> &containerVector)
{
Q_ASSERT(m_declarativeView);
QList<ServerNodeInstance> instanceList;
foreach(const InstanceContainer &instanceContainer, command.instances()) {
foreach(const InstanceContainer &instanceContainer, containerVector) {
ServerNodeInstance instance = ServerNodeInstance::create(this, instanceContainer);
insertInstanceRelationship(instance);
instanceList.append(instance);
......@@ -80,6 +86,13 @@ void NodeInstanceServer::createInstances(const CreateInstancesCommand &command)
}
}
return instanceList;
}
void NodeInstanceServer::createInstances(const CreateInstancesCommand &command)
{
createInstances(command.instances());
startRenderTimer();
}
......@@ -144,19 +157,36 @@ void NodeInstanceServer::stopRenderTimer()
}
}
void NodeInstanceServer::createScene(const CreateSceneCommand &/*command*/)
void NodeInstanceServer::createScene(const CreateSceneCommand &command)
{
Q_ASSERT(!m_declarativeView);
m_declarativeView = new QDeclarativeView;
m_declarativeView->setAttribute(Qt::WA_DontShowOnScreen, true);
m_declarativeView->setViewportUpdateMode(QGraphicsView::NoViewportUpdate);
m_declarativeView->show();
if (!m_fileUrl.isEmpty())
engine()->setBaseUrl(m_fileUrl);
if (!command.fileUrl().isEmpty())
engine()->setBaseUrl(command.fileUrl());
static_cast<QGraphicsScenePrivate*>(QObjectPrivate::get(m_declarativeView->scene()))->processDirtyItemsEmitted = true;
QList<ServerNodeInstance> instanceList = createInstances(command.instances());
reparentInstances(command.reparentInstances());
foreach(const IdContainer &container, command.ids()) {
if (hasInstanceForId(container.instanceId()))
instanceForId(container.instanceId()).setId(container.id());
}
foreach(const PropertyValueContainer &container, command.valueChanges())
setInstancePropertyVariant(container);
foreach(const PropertyBindingContainer &container, command.bindingChanges())
setInstancePropertyBinding(container);
foreach(ServerNodeInstance instance, instanceList)
instance.doComponentComplete();
nodeInstanceClient()->valuesChanged(createValuesChangedCommand(instanceList));
nodeInstanceClient()->informationChanged(createAllInformationChangedCommand(instanceList, true));
sendChildrenChangedCommand(instanceList);
nodeInstanceClient()->pixmapChanged(createPixmapChangedCommand(instanceList));
nodeInstanceClient()->componentCompleted(createComponentCompletedCommand(instanceList));
startRenderTimer();
}
......@@ -190,14 +220,19 @@ void NodeInstanceServer::removeProperties(const RemovePropertiesCommand &command
startRenderTimer();
}
void NodeInstanceServer::reparentInstances(const ReparentInstancesCommand &command)
void NodeInstanceServer::reparentInstances(const QVector<ReparentContainer> &containerVector)
{
foreach(const ReparentContainer &container, command.reparentInstances()) {
foreach(const ReparentContainer &container, containerVector) {
ServerNodeInstance instance = instanceForId(container.instanceId());
if (instance.isValid()) {
instance.reparent(instanceForId(container.oldParentInstanceId()), container.oldParentProperty(), instanceForId(container.newParentInstanceId()), container.newParentProperty());
}
}
}
void NodeInstanceServer::reparentInstances(const ReparentInstancesCommand &command)
{
reparentInstances(command.reparentInstances());
startRenderTimer();
}
......@@ -226,14 +261,13 @@ void NodeInstanceServer::completeComponent(const CompleteComponentCommand &comma
ServerNodeInstance instance = instanceForId(instanceId);
instance.doComponentComplete();
instanceList.append(instance);
m_componentCompletedVector.append(instanceId);
}
}
nodeInstanceClient()->valuesChanged(createValuesChangedCommand(instanceList));
nodeInstanceClient()->informationChanged(createAllInformationChangedCommand(instanceList, true));
nodeInstanceClient()->pixmapChanged(createPixmapChangedCommand(instanceList));
nodeInstanceClient()->componentCompleted(createComponentCompletedCommand(instanceList));
}
void NodeInstanceServer::addImport(const AddImportCommand &command)
......@@ -261,8 +295,6 @@ void NodeInstanceServer::addImport(const AddImportCommand &command)
engine()->addPluginPath(importPath);
}
qDebug() << __FUNCTION__ << fileUrl().resolved(QUrl("content/samegame.js")) << componentString;
importComponent.setData(componentString.toUtf8(), QUrl());
if (!importComponent.errorString().isEmpty())
......@@ -649,6 +681,17 @@ ValuesChangedCommand NodeInstanceServer::createValuesChangedCommand(const QList<
return ValuesChangedCommand(valueVector);
}
ComponentCompletedCommand NodeInstanceServer::createComponentCompletedCommand(const QList<ServerNodeInstance> &instanceList)
{
QVector<qint32> idVector;
foreach (const ServerNodeInstance &instance, instanceList) {
if (instance.instanceId() >= 0)
idVector.append(instance.instanceId());
}
return ComponentCompletedCommand(idVector);
}
ValuesChangedCommand NodeInstanceServer::createValuesChangedCommand(const QVector<InstancePropertyPair> &propertyList) const
{
QVector<PropertyValueContainer> valueVector;
......@@ -804,10 +847,6 @@ void NodeInstanceServer::findItemChangesAndSendChangeCommands()
if (!parentChangedSet.isEmpty())
sendChildrenChangedCommand(parentChangedSet.toList());
if (!m_componentCompletedVector.isEmpty())
nodeInstanceClient()->componentCompleted(ComponentCompletedCommand(m_componentCompletedVector));
m_componentCompletedVector.clear();
if (!m_dirtyInstanceSet.isEmpty() && nodeInstanceClient()->bytesToWrite() < 100000) {
nodeInstanceClient()->pixmapChanged(createPixmapChangedCommand(m_dirtyInstanceSet.toList()));
m_dirtyInstanceSet.clear();
......
......@@ -23,6 +23,8 @@ class ValuesChangedCommand;
class PixmapChangedCommand;
class InformationChangedCommand;
class ChildrenChangedCommand;
class ReparentContainer;
class ComponentCompletedCommand;
namespace Internal {
class ChildrenChangeEventFilter;
......@@ -84,6 +86,9 @@ public slots:
void emitParentChanged(QObject *child);
protected:
QList<ServerNodeInstance> createInstances(const QVector<InstanceContainer> &container);
void reparentInstances(const QVector<ReparentContainer> &container);
Internal::ChildrenChangeEventFilter *childrenChangeEventFilter();
void resetInstanceProperty(const PropertyAbstractContainer &propertyContainer);
void setInstancePropertyBinding(const PropertyBindingContainer &bindingContainer);
......@@ -106,7 +111,7 @@ protected:
PixmapChangedCommand createPixmapChangedCommand(const QList<ServerNodeInstance> &instanceList) const;
InformationChangedCommand createAllInformationChangedCommand(const QList<ServerNodeInstance> &instanceList, bool initial = false) const;
ChildrenChangedCommand createChildrenChangedCommand(const ServerNodeInstance &parentInstance, const QList<ServerNodeInstance> &instanceList) const;
ComponentCompletedCommand createComponentCompletedCommand(const QList<ServerNodeInstance> &instanceList);
void sendChildrenChangedCommand(const QList<ServerNodeInstance> childList);
void addChangedProperty(const InstancePropertyPair &property);
......@@ -129,7 +134,6 @@ private:
int m_timer;
bool m_slowRenderTimer;
QVector<InstancePropertyPair> m_changedPropertyList;
QVector<qint32> m_componentCompletedVector;
QStringList m_importList;
QSet<ServerNodeInstance> m_dirtyInstanceSet;
};
......
......@@ -143,13 +143,11 @@ void NodeInstanceView::modelAttached(Model *model)
connect(m_nodeInstanceServer.data(), SIGNAL(processCrashed()), this, SLOT(restartProcess()));
setBlockUpdates(true);
nodeInstanceServer()->createScene(createCreateSceneCommand());
nodeInstanceServer()->changeFileUrl(createChangeFileUrlCommand(model->fileUrl()));
foreach(const Import &import, model->imports())
nodeInstanceServer()->addImport(createImportCommand(import));
loadNodes(allModelNodes());
nodeInstanceServer()->createScene(createCreateSceneCommand());
setBlockUpdates(false);
}
......@@ -166,11 +164,21 @@ void NodeInstanceView::modelAboutToBeDetached(Model * model)
void NodeInstanceView::restartProcess()
{
setBlockUpdates(true);
Model *oldModel = model();
if (oldModel) {
oldModel->detachView(this);
oldModel->attachView(this);
if (model()) {
delete nodeInstanceServer();
m_nodeInstanceServer = new NodeInstanceServerProxy(this);
connect(m_nodeInstanceServer.data(), SIGNAL(processCrashed()), this, SLOT(restartProcess()));
setBlockUpdates(true);
foreach(const Import &import, model()->imports())
nodeInstanceServer()->addImport(createImportCommand(import));
nodeInstanceServer()->createScene(createCreateSceneCommand());
}
setBlockUpdates(false);
}
......@@ -314,12 +322,7 @@ void NodeInstanceView::rootNodeTypeChanged(const QString &/*type*/, int /*majorV
nodeInstanceServer()->clearScene(createClearSceneCommand());
removeAllInstanceNodeRelationships();
QList<ModelNode> nodeList;
nodeList.append(allModelNodes());
nodeInstanceServer()->createScene(createCreateSceneCommand());
loadNodes(nodeList);
}
void NodeInstanceView::bindingPropertiesChanged(const QList<BindingProperty>& propertyList, PropertyChangeFlags /*propertyChange*/)
......@@ -452,54 +455,9 @@ void NodeInstanceView::importRemoved(const Import &/*import*/)
//\}
void NodeInstanceView::loadNodes(const QList<ModelNode> &nodeList)
{
QList<NodeInstance> instanceList;
foreach (const ModelNode &node, nodeList)
instanceList.append(loadNode(node));
QList<VariantProperty> variantPropertyList;
QList<BindingProperty> bindingPropertyList;
foreach (const ModelNode &node, nodeList) {
variantPropertyList.append(node.variantProperties());
bindingPropertyList.append(node.bindingProperties());
}
nodeInstanceServer()->createInstances(createCreateInstancesCommand(instanceList));
nodeInstanceServer()->reparentInstances(createReparentInstancesCommand(instanceList));
nodeInstanceServer()->changeIds(createChangeIdsCommand(instanceList));
nodeInstanceServer()->changePropertyValues(createChangeValueCommand(variantPropertyList));
nodeInstanceServer()->changePropertyBindings(createChangeBindingCommand(bindingPropertyList));
nodeInstanceServer()->completeComponent(createComponentCompleteCommand(instanceList));
}
void NodeInstanceView::removeAllInstanceNodeRelationships()
{
// prevent destroyed() signals calling back
// foreach (NodeInstance instance, m_objectInstanceHash.values()) {
// if (instance.isValid())
// instance.setId(QString());
// }
// //first the root object
// if (rootNodeInstance().internalObject())
// rootNodeInstance().internalObject()->disconnect();
// rootNodeInstance().makeInvalid();
foreach (NodeInstance instance, m_idInstanceHash.values()) {
// if (instance.internalObject())
// instance.internalObject()->disconnect();
instance.makeInvalid();
}
m_nodeInstanceHash.clear();
m_idInstanceHash.clear();
}
/*! \brief Returns a List of all NodeInstances
......@@ -533,20 +491,20 @@ bool NodeInstanceView::hasInstanceForNode(const ModelNode &node) const
return m_nodeInstanceHash.contains(node);
}
NodeInstance NodeInstanceView::instanceForId(qint32 id) const
NodeInstance NodeInstanceView::instanceForId(qint32 id)
{
if (id < 0)
if (id < 0 || !hasModelNodeForInternalId(id))
return NodeInstance();
return m_idInstanceHash.value(id);
return m_nodeInstanceHash.value(modelNodeForInternalId(id));
}
bool NodeInstanceView::hasInstanceForId(qint32 id) const
bool NodeInstanceView::hasInstanceForId(qint32 id)
{
if (id < 0)
if (id < 0 || !hasModelNodeForInternalId(id))
return false;
return m_idInstanceHash.contains(id);
return m_nodeInstanceHash.contains(modelNodeForInternalId(id));
}
......@@ -592,19 +550,16 @@ NodeInstance NodeInstanceView::rootNodeInstance() const
void NodeInstanceView::insertInstanceRelationships(const NodeInstance &instance)
{
Q_ASSERT(instance.instanceId() >=0);
Q_ASSERT(!m_nodeInstanceHash.contains(instance.modelNode()));
Q_ASSERT(!m_idInstanceHash.contains(instance.instanceId()));
if(m_nodeInstanceHash.contains(instance.modelNode()))
return;
m_nodeInstanceHash.insert(instance.modelNode(), instance);
m_idInstanceHash.insert(instance.instanceId(), instance);
}
void NodeInstanceView::removeInstanceNodeRelationship(const ModelNode &node)
{
Q_ASSERT(m_nodeInstanceHash.contains(node));
NodeInstance instance = instanceForNode(node);
// if (instance.isValid())
// instance.setId(QString());
m_idInstanceHash.remove(instanceForNode(node).instanceId());
m_nodeInstanceHash.remove(node);
instance.makeInvalid();
}
......@@ -690,10 +645,75 @@ QRectF NodeInstanceView::sceneRect() const
return QRectF();
}
CreateSceneCommand NodeInstanceView::createCreateSceneCommand() const
CreateSceneCommand NodeInstanceView::createCreateSceneCommand()
{
return CreateSceneCommand();
QList<ModelNode> nodeList = allModelNodes();
QList<NodeInstance> instanceList;
foreach (const ModelNode &node, nodeList)
instanceList.append(loadNode(node));
QList<VariantProperty> variantPropertyList;
QList<BindingProperty> bindingPropertyList;
foreach (const ModelNode &node, nodeList) {
variantPropertyList.append(node.variantProperties());
bindingPropertyList.append(node.bindingProperties());
}
QVector<InstanceContainer> instanceContainerList;
foreach(const NodeInstance &instance, instanceList) {
InstanceContainer container(instance.instanceId(), instance.modelNode().type(), instance.modelNode().majorVersion(), instance.modelNode().minorVersion(), instance.modelNode().metaInfo().componentFileName());
instanceContainerList.append(container);
}
QVector<ReparentContainer> reparentContainerList;
foreach(const NodeInstance &instance, instanceList) {
if (instance.modelNode().hasParentProperty()) {
NodeAbstractProperty parentProperty = instance.modelNode().parentProperty();
ReparentContainer container(instance.instanceId(), -1, QString(), instanceForNode(parentProperty.parentModelNode()).instanceId(), parentProperty.name());
reparentContainerList.append(container);
}
}
QVector<IdContainer> idContainerList;
foreach(const NodeInstance &instance, instanceList) {
QString id = instance.modelNode().id();
if (!id.isEmpty()) {
IdContainer container(instance.instanceId(), id);
idContainerList.append(container);
}
}
QVector<PropertyValueContainer> valueContainerList;
foreach(const VariantProperty &property, variantPropertyList) {
ModelNode node = property.parentModelNode();
if (node.isValid() && hasInstanceForNode(node)) {
NodeInstance instance = instanceForNode(node);
PropertyValueContainer container(instance.instanceId(), property.name(), property.value(), property.dynamicTypeName());
valueContainerList.append(container);
}
}
QVector<PropertyBindingContainer> bindingContainerList;
foreach(const BindingProperty &property, bindingPropertyList) {
ModelNode node = property.parentModelNode();
if (node.isValid() && hasInstanceForNode(node)) {
NodeInstance instance = instanceForNode(node);
PropertyBindingContainer container(instance.instanceId(), property.name(), property.expression(), property.dynamicTypeName());
bindingContainerList.append(container);
}
}
return CreateSceneCommand(instanceContainerList,
reparentContainerList,
idContainerList,