nodeinstanceserverproxy.cpp 21.5 KB
Newer Older
hjk's avatar
hjk committed
1
/****************************************************************************
2
**
3
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
hjk's avatar
hjk committed
4
** Contact: http://www.qt-project.org/legal
5
**
hjk's avatar
hjk committed
6
** This file is part of Qt Creator.
7
**
hjk's avatar
hjk committed
8 9 10 11 12 13 14
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.  For licensing terms and
** conditions see http://qt.digia.com/licensing.  For further information
** use the contact form at http://qt.digia.com/contact-us.
15 16
**
** GNU Lesser General Public License Usage
hjk's avatar
hjk committed
17 18 19 20 21 22 23 24 25
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights.  These rights are described in the Digia Qt LGPL Exception
26 27
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
hjk's avatar
hjk committed
28
****************************************************************************/
29

30 31 32 33 34 35 36
#include "nodeinstanceserverproxy.h"

#include <QLocalServer>
#include <QLocalSocket>
#include <QProcess>
#include <QCoreApplication>
#include <QUuid>
37
#include <QFileInfo>
38
#include <QDir>
39
#include <QTimer>
40
#include <QTextStream>
41
#include <QMessageBox>
42 43 44 45 46

#include "createinstancescommand.h"
#include "createscenecommand.h"
#include "changevaluescommand.h"
#include "changebindingscommand.h"
47
#include "changeauxiliarycommand.h"
48 49 50 51 52 53 54
#include "changefileurlcommand.h"
#include "removeinstancescommand.h"
#include "clearscenecommand.h"
#include "removepropertiescommand.h"
#include "reparentinstancescommand.h"
#include "changeidscommand.h"
#include "changestatecommand.h"
55
#include "completecomponentcommand.h"
56
#include "changenodesourcecommand.h"
57 58 59 60

#include "informationchangedcommand.h"
#include "pixmapchangedcommand.h"
#include "valueschangedcommand.h"
61
#include "childrenchangedcommand.h"
62
#include "statepreviewimagechangedcommand.h"
63
#include "componentcompletedcommand.h"
64
#include "tokencommand.h"
65
#include "removesharedmemorycommand.h"
66
#include "endpuppetcommand.h"
67
#include "synchronizecommand.h"
Marco Bubke's avatar
Marco Bubke committed
68
#include "debugoutputcommand.h"
69

70
#include "nodeinstanceview.h"
71 72

#include "import.h"
73

74 75
#include "qmldesignerplugin.h"

76
#include "puppetcreator.h"
Marco Bubke's avatar
Marco Bubke committed
77
#include <qmldesignerwarning.h>
78

79
#include <coreplugin/icore.h>
80
#include <utils/hostosinfo.h>
81 82 83 84
#include <projectexplorer/kit.h>
#include <qtsupport/qtkitinformation.h>
#include <qtsupport/baseqtversion.h>
#include <qtsupport/qtsupportconstants.h>
85

86 87 88

namespace QmlDesigner {

89 90 91 92 93 94 95 96 97 98 99 100
static bool hasQtQuick1(NodeInstanceView *nodeInstanceView)
{
    if (nodeInstanceView && nodeInstanceView->model()) {
        foreach (const Import &import ,nodeInstanceView->model()->imports()) {
            if (import.url() ==  "QtQuick" && import.version().toDouble() < 2.0)
                return true;
        }
    }

    return false;
}

101
NodeInstanceServerProxy::NodeInstanceServerProxy(NodeInstanceView *nodeInstanceView, RunModus runModus, ProjectExplorer::Kit *kit)
102 103 104
    : NodeInstanceServerInterface(nodeInstanceView),
      m_localServer(new QLocalServer(this)),
      m_nodeInstanceView(nodeInstanceView),
105
      m_firstBlockSize(0),
106
      m_secondBlockSize(0),
107
      m_thirdBlockSize(0),
108 109 110 111
      m_writeCommandCounter(0),
      m_firstLastReadCommandCounter(0),
      m_secondLastReadCommandCounter(0),
      m_thirdLastReadCommandCounter(0),
112 113
      m_runModus(runModus),
      m_synchronizeId(-1)
114
{
115 116 117 118 119 120 121 122
   PuppetCreator puppetCreator(kit, QString());

   QString socketToken(QUuid::createUuid().toString());
   m_localServer->listen(socketToken);
   m_localServer->setMaxPendingConnections(3);

   PuppetCreator::QmlPuppetVersion puppetVersion = hasQtQuick1(nodeInstanceView) ? PuppetCreator::Qml1Puppet : PuppetCreator::Qml2Puppet;

123 124
   puppetCreator.createPuppetExecutableIfMissing(puppetVersion);

125 126 127 128
   m_qmlPuppetEditorProcess = puppetCreator.createPuppetProcess(puppetVersion,
                                                                "editormode",
                                                              socketToken,
                                                              this,
129
                                                              SLOT(printEditorProcessOutput()),
130 131 132 133 134 135 136
                                                              SLOT(processFinished(int,QProcess::ExitStatus)));

   if (runModus == NormalModus) {
       m_qmlPuppetRenderProcess = puppetCreator.createPuppetProcess(puppetVersion,
                                                                    "rendermode",
                                                                    socketToken,
                                                                    this,
137
                                                                    SLOT(printRenderProcessOutput()),
138 139 140 141 142 143 144 145
                                                                    SLOT(processFinished(int,QProcess::ExitStatus)));
       m_qmlPuppetPreviewProcess = puppetCreator.createPuppetProcess(puppetVersion,
                                                                     "previewmode",
                                                                     socketToken,
                                                                     this,
                                                                     SLOT(printPreviewProcessOutput()),
                                                                     SLOT(processFinished(int,QProcess::ExitStatus)));
   }
146

147 148
   if (m_qmlPuppetEditorProcess->waitForStarted(10000)) {
       connect(m_qmlPuppetEditorProcess.data(), SIGNAL(finished(int)), m_qmlPuppetEditorProcess.data(),SLOT(deleteLater()));
149

150 151 152
       if (runModus == NormalModus) {
           m_qmlPuppetPreviewProcess->waitForStarted();
           connect(m_qmlPuppetPreviewProcess.data(), SIGNAL(finished(int)), m_qmlPuppetPreviewProcess.data(),SLOT(deleteLater()));
153

154 155
           m_qmlPuppetRenderProcess->waitForStarted();
           connect(m_qmlPuppetRenderProcess.data(), SIGNAL(finished(int)), m_qmlPuppetRenderProcess.data(),SLOT(deleteLater()));
156
       }
157

158 159
       if (!m_localServer->hasPendingConnections())
           m_localServer->waitForNewConnection(10000);
160

161 162 163 164 165 166 167 168 169 170 171 172 173 174 175
       m_firstSocket = m_localServer->nextPendingConnection();
       connect(m_firstSocket.data(), SIGNAL(readyRead()), this, SLOT(readFirstDataStream()));

       if (runModus == NormalModus) {
           if (!m_localServer->hasPendingConnections())
               m_localServer->waitForNewConnection(10000);

           m_secondSocket = m_localServer->nextPendingConnection();
           connect(m_secondSocket.data(), SIGNAL(readyRead()), this, SLOT(readSecondDataStream()));

           if (!m_localServer->hasPendingConnections())
               m_localServer->waitForNewConnection(10000);

           m_thirdSocket = m_localServer->nextPendingConnection();
           connect(m_thirdSocket.data(), SIGNAL(readyRead()), this, SLOT(readThirdDataStream()));
176
       }
177

178
   } else {
Marco Bubke's avatar
Marco Bubke committed
179
       QmlDesignerWarning::show(tr("Cannot Start QML Puppet Executable"),
180
                            tr("The executable of the QML Puppet process cannot be started or is hanging."));
181

182
       QmlDesignerPlugin::instance()->switchToTextModeDeferred();
183
   }
184

185 186 187
   m_localServer->close();


188 189 190 191 192 193
   int indexOfCapturePuppetStream = QCoreApplication::arguments().indexOf("-capture-puppet-stream");
   if (indexOfCapturePuppetStream > 0) {
       m_captureFileForTest.setFileName(QCoreApplication::arguments().at(indexOfCapturePuppetStream + 1));
       bool isOpen = m_captureFileForTest.open(QIODevice::WriteOnly);
       qDebug() << "file is open: " << isOpen;
   }
194 195 196 197 198

   m_firstTimer.setInterval(3000);
   m_secondTimer.setInterval(3000);
   m_thirdTimer.setInterval(3000);

199 200 201 202 203
   if (qgetenv("DEBUG_QML_PUPPET").isEmpty()) {
       connect(&m_firstTimer, SIGNAL(timeout()), this, SLOT(processFinished()));
       connect(&m_secondTimer, SIGNAL(timeout()), this, SLOT(processFinished()));
       connect(&m_thirdTimer, SIGNAL(timeout()), this, SLOT(processFinished()));
   }
204 205 206 207
}

NodeInstanceServerProxy::~NodeInstanceServerProxy()
{
208 209
    disconnect(this, SLOT(processFinished(int,QProcess::ExitStatus)));

210 211
    writeCommand(QVariant::fromValue(EndPuppetCommand()));

212 213
    if (m_firstSocket) {
        m_firstSocket->waitForBytesWritten(1000);
214
        m_firstSocket->abort();
215
    }
216

217 218
    if (m_secondSocket) {
        m_secondSocket->waitForBytesWritten(1000);
219
        m_secondSocket->abort();
220
    }
221

222 223
    if (m_thirdSocket) {
        m_thirdSocket->waitForBytesWritten(1000);
224
        m_thirdSocket->abort();
225
    }
226

227
    if (m_qmlPuppetEditorProcess) {
228
        QTimer::singleShot(3000, m_qmlPuppetEditorProcess.data(), SLOT(terminate()));
229 230
        QTimer::singleShot(6000, m_qmlPuppetEditorProcess.data(), SLOT(kill()));
    }
231

232
    if (m_qmlPuppetPreviewProcess) {
233
        QTimer::singleShot(3000, m_qmlPuppetPreviewProcess.data(), SLOT(terminate()));
234 235
        QTimer::singleShot(6000, m_qmlPuppetPreviewProcess.data(), SLOT(kill()));
    }
236

237
    if (m_qmlPuppetRenderProcess) {
238
         QTimer::singleShot(3000, m_qmlPuppetRenderProcess.data(), SLOT(terminate()));
239 240
         QTimer::singleShot(6000, m_qmlPuppetRenderProcess.data(), SLOT(kill()));
    }
241 242
}

243
void NodeInstanceServerProxy::dispatchCommand(const QVariant &command, PuppetStreamType puppetStreamType)
244 245 246 247
{
    static const int informationChangedCommandType = QMetaType::type("InformationChangedCommand");
    static const int valuesChangedCommandType = QMetaType::type("ValuesChangedCommand");
    static const int pixmapChangedCommandType = QMetaType::type("PixmapChangedCommand");
248
    static const int childrenChangedCommandType = QMetaType::type("ChildrenChangedCommand");
249
    static const int statePreviewImageChangedCommandType = QMetaType::type("StatePreviewImageChangedCommand");
250
    static const int componentCompletedCommandType = QMetaType::type("ComponentCompletedCommand");
251
    static const int synchronizeCommandType = QMetaType::type("SynchronizeCommand");
252
    static const int tokenCommandType = QMetaType::type("TokenCommand");
Marco Bubke's avatar
Marco Bubke committed
253
    static const int debugOutputCommandType = QMetaType::type("DebugOutputCommand");
254
    static const int puppetAliveCommandType = QMetaType::type("PuppetAliveCommand");
255

256
    if (command.userType() ==  informationChangedCommandType) {
257
        nodeInstanceClient()->informationChanged(command.value<InformationChangedCommand>());
258
    } else if (command.userType() ==  valuesChangedCommandType) {
259
        nodeInstanceClient()->valuesChanged(command.value<ValuesChangedCommand>());
260
    } else if (command.userType() ==  pixmapChangedCommandType) {
261
        nodeInstanceClient()->pixmapChanged(command.value<PixmapChangedCommand>());
262
    } else if (command.userType() == childrenChangedCommandType) {
263
        nodeInstanceClient()->childrenChanged(command.value<ChildrenChangedCommand>());
264
    } else if (command.userType() == statePreviewImageChangedCommandType) {
265
        nodeInstanceClient()->statePreviewImagesChanged(command.value<StatePreviewImageChangedCommand>());
266
    } else if (command.userType() == componentCompletedCommandType) {
267
        nodeInstanceClient()->componentCompleted(command.value<ComponentCompletedCommand>());
268
    } else if (command.userType() == tokenCommandType) {
269
        nodeInstanceClient()->token(command.value<TokenCommand>());
270
    } else if (command.userType() == debugOutputCommandType) {
Marco Bubke's avatar
Marco Bubke committed
271
        nodeInstanceClient()->debugOutput(command.value<DebugOutputCommand>());
272 273
    } else if (command.userType() == puppetAliveCommandType) {
        puppetAlive(puppetStreamType);
274
    } else if (command.userType() == synchronizeCommandType) {
275 276 277
        SynchronizeCommand synchronizeCommand = command.value<SynchronizeCommand>();
        m_synchronizeId = synchronizeCommand.synchronizeId();
    }  else
278 279 280 281 282 283 284 285
        Q_ASSERT(false);
}

NodeInstanceClientInterface *NodeInstanceServerProxy::nodeInstanceClient() const
{
    return m_nodeInstanceView.data();
}

286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310
void NodeInstanceServerProxy::puppetAlive(NodeInstanceServerProxy::PuppetStreamType puppetStreamType)
{
    switch (puppetStreamType) {
    case FirstPuppetStream:
        m_firstTimer.stop();
        m_firstTimer.start();
        break;
    case SecondPuppetStream:
        m_secondTimer.stop();
        m_secondTimer.start();
        break;
    case ThirdPuppetStream:
        m_thirdTimer.stop();
        m_thirdTimer.start();
        break;
    default:
        break;
    }
}

void NodeInstanceServerProxy::processFinished()
{
    processFinished(-1, QProcess::CrashExit);
}

311
static void writeCommandToIODecive(const QVariant &command, QIODevice *ioDevice, unsigned int commandCounter)
312
{
313
    if (ioDevice) {
314 315
        QByteArray block;
        QDataStream out(&block, QIODevice::WriteOnly);
316
        out.setVersion(QDataStream::Qt_4_8);
317
        out << quint32(0);
318
        out << quint32(commandCounter);
319 320 321 322
        out << command;
        out.device()->seek(0);
        out << quint32(block.size() - sizeof(quint32));

323
        ioDevice->write(block);
324
    }
325 326 327 328
}

void NodeInstanceServerProxy::writeCommand(const QVariant &command)
{
329 330 331 332 333 334 335 336 337 338
    writeCommandToIODecive(command, m_firstSocket.data(), m_writeCommandCounter);
    writeCommandToIODecive(command, m_secondSocket.data(), m_writeCommandCounter);
    writeCommandToIODecive(command, m_thirdSocket.data(), m_writeCommandCounter);

    if (m_captureFileForTest.isWritable()) {
        qDebug() << "Write strean to file: " << m_captureFileForTest.fileName();
        writeCommandToIODecive(command, &m_captureFileForTest, m_writeCommandCounter);
        qDebug() << "\twrite file: " << m_captureFileForTest.pos();
    }

339
    m_writeCommandCounter++;
340 341 342 343 344
    if (m_runModus == TestModus) {
        static int synchronizeId = 0;
        synchronizeId++;
        SynchronizeCommand synchronizeCommand(synchronizeId);

345
        writeCommandToIODecive(QVariant::fromValue(synchronizeCommand), m_firstSocket.data(), m_writeCommandCounter);
346
        m_writeCommandCounter++;
347

348
        while (m_firstSocket->waitForReadyRead(100)) {
349 350 351 352 353
                readFirstDataStream();
                if (m_synchronizeId == synchronizeId)
                    return;
        }
    }
354 355
}

356
void NodeInstanceServerProxy::processFinished(int exitCode, QProcess::ExitStatus exitStatus)
357
{
358
    qWarning() << "Process finished:" << sender() << exitCode;
359

360 361 362
    if (m_captureFileForTest.isOpen()) {
        m_captureFileForTest.close();
        m_captureFileForTest.remove();
363 364 365
        QMessageBox::warning(Core::ICore::dialogParent(), tr("QML Puppet Crashed"),
                             tr("You are recording a puppet stream and the puppet crashed. "
                                "It is recommended to reopen the Qt Quick Designer and start again."));
366 367 368
    }


369 370
    writeCommand(QVariant::fromValue(EndPuppetCommand()));

371 372
    if (m_firstSocket) {
        m_firstSocket->waitForBytesWritten(1000);
373
        m_firstSocket->abort();
374 375 376 377
    }

    if (m_secondSocket) {
        m_secondSocket->waitForBytesWritten(1000);
378
        m_secondSocket->abort();
379 380 381 382
    }

    if (m_thirdSocket) {
        m_thirdSocket->waitForBytesWritten(1000);
383
        m_thirdSocket->abort();
384
    }
385

386 387
    if (exitStatus == QProcess::CrashExit)
        emit processCrashed();
388 389
}

390

391 392 393 394 395 396 397 398 399
void NodeInstanceServerProxy::readFirstDataStream()
{
    QList<QVariant> commandList;

    while (!m_firstSocket->atEnd()) {
        if (m_firstSocket->bytesAvailable() < int(sizeof(quint32)))
            break;

        QDataStream in(m_firstSocket.data());
400
        in.setVersion(QDataStream::Qt_4_8);
401

402
        if (m_firstBlockSize == 0)
403 404 405 406 407
            in >> m_firstBlockSize;

        if (m_firstSocket->bytesAvailable() < m_firstBlockSize)
            break;

408 409 410 411 412 413 414 415
        quint32 commandCounter;
        in >> commandCounter;
        bool commandLost = !((m_firstLastReadCommandCounter == 0 && commandCounter == 0) || (m_firstLastReadCommandCounter + 1 == commandCounter));
        if (commandLost)
            qDebug() << "server command lost: " << m_firstLastReadCommandCounter <<  commandCounter;
        m_firstLastReadCommandCounter = commandCounter;


416 417 418 419 420 421 422 423
        QVariant command;
        in >> command;
        m_firstBlockSize = 0;

        commandList.append(command);
    }

    foreach (const QVariant &command, commandList) {
424
        dispatchCommand(command, FirstPuppetStream);
425 426 427 428
    }
}

void NodeInstanceServerProxy::readSecondDataStream()
429 430 431
{
    QList<QVariant> commandList;

432 433
    while (!m_secondSocket->atEnd()) {
        if (m_secondSocket->bytesAvailable() < int(sizeof(quint32)))
434 435
            break;

436
        QDataStream in(m_secondSocket.data());
437
        in.setVersion(QDataStream::Qt_4_8);
438

439
        if (m_secondBlockSize == 0)
440
            in >> m_secondBlockSize;
441

442
        if (m_secondSocket->bytesAvailable() < m_secondBlockSize)
443 444
            break;

445 446 447 448 449 450 451 452
        quint32 commandCounter;
        in >> commandCounter;
        bool commandLost = !((m_secondLastReadCommandCounter == 0 && commandCounter == 0) || (m_secondLastReadCommandCounter + 1 == commandCounter));
        if (commandLost)
            qDebug() << "server command lost: " << m_secondLastReadCommandCounter <<  commandCounter;
        m_secondLastReadCommandCounter = commandCounter;


453 454
        QVariant command;
        in >> command;
455
        m_secondBlockSize = 0;
456 457 458 459 460

        commandList.append(command);
    }

    foreach (const QVariant &command, commandList) {
461
        dispatchCommand(command, SecondPuppetStream);
462 463 464
    }
}

465 466 467 468 469 470 471 472 473
void NodeInstanceServerProxy::readThirdDataStream()
{
    QList<QVariant> commandList;

    while (!m_thirdSocket->atEnd()) {
        if (m_thirdSocket->bytesAvailable() < int(sizeof(quint32)))
            break;

        QDataStream in(m_thirdSocket.data());
474
        in.setVersion(QDataStream::Qt_4_8);
475

476
        if (m_thirdBlockSize == 0)
477 478 479 480 481
            in >> m_thirdBlockSize;

        if (m_thirdSocket->bytesAvailable() < m_thirdBlockSize)
            break;

482 483 484 485 486 487 488 489
        quint32 commandCounter;
        in >> commandCounter;
        bool commandLost = !((m_thirdLastReadCommandCounter == 0 && commandCounter == 0) || (m_thirdLastReadCommandCounter + 1 == commandCounter));
        if (commandLost)
            qDebug() << "server command lost: " << m_thirdLastReadCommandCounter <<  commandCounter;
        m_thirdLastReadCommandCounter = commandCounter;


490 491 492 493 494 495 496 497
        QVariant command;
        in >> command;
        m_thirdBlockSize = 0;

        commandList.append(command);
    }

    foreach (const QVariant &command, commandList) {
498
        dispatchCommand(command, ThirdPuppetStream);
499 500 501
    }
}

502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532
void NodeInstanceServerProxy::printEditorProcessOutput()
{
    while (m_qmlPuppetEditorProcess->canReadLine()) {
        QByteArray line = m_qmlPuppetEditorProcess->readLine();
        line.chop(1);
        qDebug().nospace() << "Editor Puppet: " << qPrintable(line);
    }
    qDebug() << "\n";
}

void NodeInstanceServerProxy::printPreviewProcessOutput()
{
    while (m_qmlPuppetPreviewProcess->canReadLine()) {
        QByteArray line = m_qmlPuppetPreviewProcess->readLine();
        line.chop(1);
        qDebug().nospace() << "Preview Puppet: " << qPrintable(line);
    }
    qDebug() << "\n";
}

void NodeInstanceServerProxy::printRenderProcessOutput()
{
    while (m_qmlPuppetRenderProcess->canReadLine()) {
        QByteArray line = m_qmlPuppetRenderProcess->readLine();
        line.chop(1);
        qDebug().nospace() << "Render Puppet: " << qPrintable(line);
    }

    qDebug() << "\n";
}

533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572
void NodeInstanceServerProxy::createInstances(const CreateInstancesCommand &command)
{
    writeCommand(QVariant::fromValue(command));
}

void NodeInstanceServerProxy::changeFileUrl(const ChangeFileUrlCommand &command)
{
    writeCommand(QVariant::fromValue(command));
}

void NodeInstanceServerProxy::createScene(const CreateSceneCommand &command)
{
    writeCommand(QVariant::fromValue(command));
}

void NodeInstanceServerProxy::clearScene(const ClearSceneCommand &command)
{
    writeCommand(QVariant::fromValue(command));
}

void NodeInstanceServerProxy::removeInstances(const RemoveInstancesCommand &command)
{
    writeCommand(QVariant::fromValue(command));
}

void NodeInstanceServerProxy::removeProperties(const RemovePropertiesCommand &command)
{
    writeCommand(QVariant::fromValue(command));
}

void NodeInstanceServerProxy::changePropertyBindings(const ChangeBindingsCommand &command)
{
    writeCommand(QVariant::fromValue(command));
}

void NodeInstanceServerProxy::changePropertyValues(const ChangeValuesCommand &command)
{
    writeCommand(QVariant::fromValue(command));
}

573 574 575 576 577
void NodeInstanceServerProxy::changeAuxiliaryValues(const ChangeAuxiliaryCommand &command)
{
    writeCommand(QVariant::fromValue(command));
}

578 579 580 581 582 583 584 585 586 587 588 589 590 591 592
void NodeInstanceServerProxy::reparentInstances(const ReparentInstancesCommand &command)
{
    writeCommand(QVariant::fromValue(command));
}

void NodeInstanceServerProxy::changeIds(const ChangeIdsCommand &command)
{
    writeCommand(QVariant::fromValue(command));
}

void NodeInstanceServerProxy::changeState(const ChangeStateCommand &command)
{
    writeCommand(QVariant::fromValue(command));
}

593 594 595 596
void NodeInstanceServerProxy::completeComponent(const CompleteComponentCommand &command)
{
    writeCommand(QVariant::fromValue(command));
}
597

598
void NodeInstanceServerProxy::changeNodeSource(const ChangeNodeSourceCommand &command)
599 600 601 602
{
    writeCommand(QVariant::fromValue(command));
}

603 604 605 606 607
void NodeInstanceServerProxy::token(const TokenCommand &command)
{
    writeCommand(QVariant::fromValue(command));
}

608 609 610 611 612
void NodeInstanceServerProxy::removeSharedMemory(const RemoveSharedMemoryCommand &command)
{
   writeCommand(QVariant::fromValue(command));
}

613
} // namespace QmlDesigner