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 77
#include "puppetcreator.h"

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

85 86 87

namespace QmlDesigner {

88 89 90 91 92 93 94 95 96 97 98 99
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;
}

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

122 123
   puppetCreator.createPuppetExecutableIfMissing(puppetVersion);

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

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

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

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

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

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

160 161 162 163 164 165 166 167 168 169 170 171 172 173 174
       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()));
175
       }
176

177
   } else {
178 179
       QMessageBox::warning(Core::ICore::dialogParent(),
                            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 199 200 201

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

   connect(&m_firstTimer, SIGNAL(timeout()), this, SLOT(processFinished()));
   connect(&m_secondTimer, SIGNAL(timeout()), this, SLOT(processFinished()));
   connect(&m_thirdTimer, SIGNAL(timeout()), this, SLOT(processFinished()));
202 203 204 205
}

NodeInstanceServerProxy::~NodeInstanceServerProxy()
{
206 207
    disconnect(this, SLOT(processFinished(int,QProcess::ExitStatus)));

208 209
    writeCommand(QVariant::fromValue(EndPuppetCommand()));

210 211
    if (m_firstSocket) {
        m_firstSocket->waitForBytesWritten(1000);
212
        m_firstSocket->abort();
213
    }
214

215 216
    if (m_secondSocket) {
        m_secondSocket->waitForBytesWritten(1000);
217
        m_secondSocket->abort();
218
    }
219

220 221
    if (m_thirdSocket) {
        m_thirdSocket->waitForBytesWritten(1000);
222
        m_thirdSocket->abort();
223
    }
224

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

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

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

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

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

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

284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308
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);
}

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

321
        ioDevice->write(block);
322
    }
323 324 325 326
}

void NodeInstanceServerProxy::writeCommand(const QVariant &command)
{
327 328 329 330 331 332 333 334 335 336
    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();
    }

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

343
        writeCommandToIODecive(QVariant::fromValue(synchronizeCommand), m_firstSocket.data(), m_writeCommandCounter);
344
        m_writeCommandCounter++;
345

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

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

358 359 360
    if (m_captureFileForTest.isOpen()) {
        m_captureFileForTest.close();
        m_captureFileForTest.remove();
361 362 363
        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."));
364 365 366
    }


367 368
    writeCommand(QVariant::fromValue(EndPuppetCommand()));

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

    if (m_secondSocket) {
        m_secondSocket->waitForBytesWritten(1000);
376
        m_secondSocket->abort();
377 378 379 380
    }

    if (m_thirdSocket) {
        m_thirdSocket->waitForBytesWritten(1000);
381
        m_thirdSocket->abort();
382
    }
383

384 385
    if (exitStatus == QProcess::CrashExit)
        emit processCrashed();
386 387
}

388

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

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

        QDataStream in(m_firstSocket.data());
398
        in.setVersion(QDataStream::Qt_4_8);
399

400
        if (m_firstBlockSize == 0)
401 402 403 404 405
            in >> m_firstBlockSize;

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

406 407 408 409 410 411 412 413
        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;


414 415 416 417 418 419 420 421
        QVariant command;
        in >> command;
        m_firstBlockSize = 0;

        commandList.append(command);
    }

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

void NodeInstanceServerProxy::readSecondDataStream()
427 428 429
{
    QList<QVariant> commandList;

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

434
        QDataStream in(m_secondSocket.data());
435
        in.setVersion(QDataStream::Qt_4_8);
436

437
        if (m_secondBlockSize == 0)
438
            in >> m_secondBlockSize;
439

440
        if (m_secondSocket->bytesAvailable() < m_secondBlockSize)
441 442
            break;

443 444 445 446 447 448 449 450
        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;


451 452
        QVariant command;
        in >> command;
453
        m_secondBlockSize = 0;
454 455 456 457 458

        commandList.append(command);
    }

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

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

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

        QDataStream in(m_thirdSocket.data());
472
        in.setVersion(QDataStream::Qt_4_8);
473

474
        if (m_thirdBlockSize == 0)
475 476 477 478 479
            in >> m_thirdBlockSize;

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

480 481 482 483 484 485 486 487
        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;


488 489 490 491 492 493 494 495
        QVariant command;
        in >> command;
        m_thirdBlockSize = 0;

        commandList.append(command);
    }

    foreach (const QVariant &command, commandList) {
496
        dispatchCommand(command, ThirdPuppetStream);
497 498 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
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";
}

531 532 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
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));
}

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

576 577 578 579 580 581 582 583 584 585 586 587 588 589 590
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));
}

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

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

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

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

611
} // namespace QmlDesigner