nodeinstanceserverproxy.cpp 24.4 KB
Newer Older
hjk's avatar
hjk committed
1
/****************************************************************************
2
**
3 4
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
5
**
hjk's avatar
hjk committed
6
** This file is part of Qt Creator.
7
**
hjk's avatar
hjk committed
8 9 10 11
** 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
12 13 14
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
15
**
16 17
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
18 19 20 21 22
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
23
**
hjk's avatar
hjk committed
24
****************************************************************************/
25

26 27
#include "nodeinstanceserverproxy.h"

Tim Jenssen's avatar
Tim Jenssen committed
28
#include "puppetcreator.h"
29

Tim Jenssen's avatar
Tim Jenssen committed
30 31 32 33 34 35 36 37 38 39 40 41 42 43
#include <createinstancescommand.h>
#include <createscenecommand.h>
#include <changevaluescommand.h>
#include <changebindingscommand.h>
#include <changeauxiliarycommand.h>
#include <changefileurlcommand.h>
#include <removeinstancescommand.h>
#include <clearscenecommand.h>
#include <removepropertiescommand.h>
#include <reparentinstancescommand.h>
#include <changeidscommand.h>
#include <changestatecommand.h>
#include <completecomponentcommand.h>
#include <changenodesourcecommand.h>
44

Tim Jenssen's avatar
Tim Jenssen committed
45 46 47 48 49 50 51 52 53 54 55
#include <informationchangedcommand.h>
#include <pixmapchangedcommand.h>
#include <valueschangedcommand.h>
#include <childrenchangedcommand.h>
#include <statepreviewimagechangedcommand.h>
#include <componentcompletedcommand.h>
#include <tokencommand.h>
#include <removesharedmemorycommand.h>
#include <endpuppetcommand.h>
#include <synchronizecommand.h>
#include <debugoutputcommand.h>
56

Tim Jenssen's avatar
Tim Jenssen committed
57 58
#include <nodeinstanceview.h>
#include <import.h>
59 60 61
#include <rewriterview.h>

#ifndef QMLDESIGNER_TEST
Tim Jenssen's avatar
Tim Jenssen committed
62
#include <qmldesignerplugin.h>
63
#endif
64

65
#include <coreplugin/icore.h>
66
#include <utils/hostosinfo.h>
67
#include <coreplugin/messagebox.h>
68
#include <coreplugin/editormanager/editormanager.h>
69 70 71 72
#include <projectexplorer/kit.h>
#include <qtsupport/qtkitinformation.h>
#include <qtsupport/baseqtversion.h>
#include <qtsupport/qtsupportconstants.h>
73

Tim Jenssen's avatar
Tim Jenssen committed
74 75
#include <QLocalServer>
#include <QLocalSocket>
76
#include <QLoggingCategory>
Tim Jenssen's avatar
Tim Jenssen committed
77 78 79 80 81 82 83 84
#include <QProcess>
#include <QCoreApplication>
#include <QUuid>
#include <QFileInfo>
#include <QDir>
#include <QTimer>
#include <QTextStream>
#include <QMessageBox>
85 86 87

namespace QmlDesigner {

88 89
static Q_LOGGING_CATEGORY(instanceViewBenchmark, "qtc.nodeinstances.init")

90
void NodeInstanceServerProxy::showCannotConnectToPuppetWarningAndSwitchToEditMode()
91
{
92
#ifndef QMLDESIGNER_TEST
93 94 95
    Core::AsynchronousMessageBox::warning(tr("Cannot Connect to QML Emulation Layer (QML Puppet)"),
                                          tr("The executable of the QML emulation layer (QML Puppet) may not be responding. "
                                             "Switching to another kit might help."));
96 97

    QmlDesignerPlugin::instance()->switchToTextModeDeferred();
98
    m_nodeInstanceView->emitDocumentMessage(tr("Cannot Connect to QML Emulation Layer (QML Puppet)"));
99
#endif
100 101 102

}

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

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

127
   PuppetCreator puppetCreator(kit, project, QString(), nodeInstanceView->model());
128
   puppetCreator.setQrcMappingString(qrcMappingString());
129

130
   puppetCreator.createPuppetExecutableIfMissing();
131

132
   m_qmlPuppetEditorProcess = puppetCreator.createPuppetProcess("editormode",
133 134
                                                              socketToken,
                                                              this,
135
                                                              SLOT(printEditorProcessOutput()),
136 137 138
                                                              SLOT(processFinished(int,QProcess::ExitStatus)));

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

151 152 153
   const int second = 1000;
   const int waitConstant = 8 * second;
   if (m_qmlPuppetEditorProcess->waitForStarted(waitConstant)) {
154 155
       connect(m_qmlPuppetEditorProcess.data(), static_cast<void (QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished),
            m_qmlPuppetEditorProcess.data(), &QProcess::deleteLater);
156
    qCInfo(instanceViewBenchmark) << "puppets started:" << m_benchmarkTimer.elapsed();
157

158
       if (runModus == NormalModus) {
159
           m_qmlPuppetPreviewProcess->waitForStarted(waitConstant / 2);
160 161
           connect(m_qmlPuppetPreviewProcess.data(), static_cast<void (QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished),
                m_qmlPuppetPreviewProcess.data(), &QProcess::deleteLater);
162

163
           m_qmlPuppetRenderProcess->waitForStarted(waitConstant / 2);
164 165
           connect(m_qmlPuppetRenderProcess.data(), static_cast<void (QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished),
                m_qmlPuppetRenderProcess.data(), &QProcess::deleteLater);
166
       }
167

168
       bool connectedToPuppet = true;
169

170
       if (!m_localServer->hasPendingConnections())
171
           connectedToPuppet = m_localServer->waitForNewConnection(waitConstant / 4);
172 173 174 175 176 177 178

       if (connectedToPuppet) {
           m_firstSocket = m_localServer->nextPendingConnection();
           connect(m_firstSocket.data(), SIGNAL(readyRead()), this, SLOT(readFirstDataStream()));

           if (runModus == NormalModus) {
               if (!m_localServer->hasPendingConnections())
179
                   connectedToPuppet = m_localServer->waitForNewConnection(waitConstant / 4);
180 181 182 183 184 185

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

                   if (!m_localServer->hasPendingConnections())
186
                        connectedToPuppet = m_localServer->waitForNewConnection(waitConstant / 4);
187

188
    qCInfo(instanceViewBenchmark) << "puppets connected:" << m_benchmarkTimer.elapsed();
189 190 191 192 193 194 195 196 197 198 199 200
                   if (connectedToPuppet) {
                       m_thirdSocket = m_localServer->nextPendingConnection();
                       connect(m_thirdSocket.data(), SIGNAL(readyRead()), this, SLOT(readThirdDataStream()));
                   } else {
                       showCannotConnectToPuppetWarningAndSwitchToEditMode();
                   }
               } else {
                   showCannotConnectToPuppetWarningAndSwitchToEditMode();
               }
           }
       } else {
           showCannotConnectToPuppetWarningAndSwitchToEditMode();
201
       }
202

203
   } else {
204
       showCannotConnectToPuppetWarningAndSwitchToEditMode();
205
   }
206

207 208 209
   m_localServer->close();


210 211 212 213 214 215
   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;
   }
216

217
#ifndef QMLDESIGNER_TEST
218 219 220 221 222 223 224 225
   DesignerSettings settings = QmlDesignerPlugin::instance()->settings();
   int timeOutTime = settings.value(DesignerSettingsKey::PUPPET_KILL_TIMEOUT).toInt();
   m_firstTimer.setInterval(timeOutTime);
   m_secondTimer.setInterval(timeOutTime);
   m_thirdTimer.setInterval(timeOutTime);

    if (QmlDesignerPlugin::instance()->settings().value(DesignerSettingsKey::
            DEBUG_PUPPET).toString().isEmpty()) {
226 227 228 229
       connect(&m_firstTimer, SIGNAL(timeout()), this, SLOT(processFinished()));
       connect(&m_secondTimer, SIGNAL(timeout()), this, SLOT(processFinished()));
       connect(&m_thirdTimer, SIGNAL(timeout()), this, SLOT(processFinished()));
   }
230
#endif
231 232 233 234
}

NodeInstanceServerProxy::~NodeInstanceServerProxy()
{
235 236
    disconnect(this, SLOT(processFinished(int,QProcess::ExitStatus)));

237 238
    writeCommand(QVariant::fromValue(EndPuppetCommand()));

239 240
    if (m_firstSocket) {
        m_firstSocket->waitForBytesWritten(1000);
241
        m_firstSocket->abort();
242
    }
243

244 245
    if (m_secondSocket) {
        m_secondSocket->waitForBytesWritten(1000);
246
        m_secondSocket->abort();
247
    }
248

249 250
    if (m_thirdSocket) {
        m_thirdSocket->waitForBytesWritten(1000);
251
        m_thirdSocket->abort();
252
    }
253

254
    if (m_qmlPuppetEditorProcess) {
255
        QTimer::singleShot(3000, m_qmlPuppetEditorProcess.data(), SLOT(terminate()));
256 257
        QTimer::singleShot(6000, m_qmlPuppetEditorProcess.data(), SLOT(kill()));
    }
258

259
    if (m_qmlPuppetPreviewProcess) {
260
        QTimer::singleShot(3000, m_qmlPuppetPreviewProcess.data(), SLOT(terminate()));
261 262
        QTimer::singleShot(6000, m_qmlPuppetPreviewProcess.data(), SLOT(kill()));
    }
263

264
    if (m_qmlPuppetRenderProcess) {
265
         QTimer::singleShot(3000, m_qmlPuppetRenderProcess.data(), SLOT(terminate()));
266 267
         QTimer::singleShot(6000, m_qmlPuppetRenderProcess.data(), SLOT(kill()));
    }
268 269
}

270
void NodeInstanceServerProxy::dispatchCommand(const QVariant &command, PuppetStreamType puppetStreamType)
271 272 273 274
{
    static const int informationChangedCommandType = QMetaType::type("InformationChangedCommand");
    static const int valuesChangedCommandType = QMetaType::type("ValuesChangedCommand");
    static const int pixmapChangedCommandType = QMetaType::type("PixmapChangedCommand");
275
    static const int childrenChangedCommandType = QMetaType::type("ChildrenChangedCommand");
276
    static const int statePreviewImageChangedCommandType = QMetaType::type("StatePreviewImageChangedCommand");
277
    static const int componentCompletedCommandType = QMetaType::type("ComponentCompletedCommand");
278
    static const int synchronizeCommandType = QMetaType::type("SynchronizeCommand");
279
    static const int tokenCommandType = QMetaType::type("TokenCommand");
Marco Bubke's avatar
Marco Bubke committed
280
    static const int debugOutputCommandType = QMetaType::type("DebugOutputCommand");
281
    static const int puppetAliveCommandType = QMetaType::type("PuppetAliveCommand");
282

283
    qCInfo(instanceViewBenchmark) << "dispatching command" << command.userType() << command.typeName();
284
    if (command.userType() ==  informationChangedCommandType) {
285
        nodeInstanceClient()->informationChanged(command.value<InformationChangedCommand>());
286
    } else if (command.userType() ==  valuesChangedCommandType) {
287
        nodeInstanceClient()->valuesChanged(command.value<ValuesChangedCommand>());
288
    } else if (command.userType() ==  pixmapChangedCommandType) {
289
        nodeInstanceClient()->pixmapChanged(command.value<PixmapChangedCommand>());
290
    } else if (command.userType() == childrenChangedCommandType) {
291
        nodeInstanceClient()->childrenChanged(command.value<ChildrenChangedCommand>());
292
    } else if (command.userType() == statePreviewImageChangedCommandType) {
293
        nodeInstanceClient()->statePreviewImagesChanged(command.value<StatePreviewImageChangedCommand>());
294
    } else if (command.userType() == componentCompletedCommandType) {
295
        nodeInstanceClient()->componentCompleted(command.value<ComponentCompletedCommand>());
296
    } else if (command.userType() == tokenCommandType) {
297
        nodeInstanceClient()->token(command.value<TokenCommand>());
298
    } else if (command.userType() == debugOutputCommandType) {
Marco Bubke's avatar
Marco Bubke committed
299
        nodeInstanceClient()->debugOutput(command.value<DebugOutputCommand>());
300 301
    } else if (command.userType() == puppetAliveCommandType) {
        puppetAlive(puppetStreamType);
302
    } else if (command.userType() == synchronizeCommandType) {
303 304 305
        SynchronizeCommand synchronizeCommand = command.value<SynchronizeCommand>();
        m_synchronizeId = synchronizeCommand.synchronizeId();
    }  else
306
        Q_ASSERT(false);
307
     qCInfo(instanceViewBenchmark) << "dispatching command" << "done" << command.userType();
308 309 310 311 312 313 314
}

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

315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334
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;
    }
}

335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358
QString NodeInstanceServerProxy::qrcMappingString() const
{
    if (m_nodeInstanceView && m_nodeInstanceView.data()->model()) {
        RewriterView *rewriterView = m_nodeInstanceView.data()->model()->rewriterView();
        if (rewriterView) {
            QString mappingString;

            typedef QPair<QString, QString> StringPair;

            foreach (const StringPair &pair, rewriterView->qrcMapping()) {
                if (!mappingString.isEmpty())
                    mappingString.append(QLatin1String(","));
                mappingString.append(pair.first);
                mappingString.append(QLatin1String("="));
                mappingString.append(pair.second);
            }

            return mappingString;
        }
    }

    return QString();
}

359 360 361 362 363
void NodeInstanceServerProxy::processFinished()
{
    processFinished(-1, QProcess::CrashExit);
}

364
static void writeCommandToIODecive(const QVariant &command, QIODevice *ioDevice, unsigned int commandCounter)
365
{
366
    if (ioDevice) {
367 368
        QByteArray block;
        QDataStream out(&block, QIODevice::WriteOnly);
369
        out.setVersion(QDataStream::Qt_4_8);
370
        out << quint32(0);
371
        out << quint32(commandCounter);
372 373 374 375
        out << command;
        out.device()->seek(0);
        out << quint32(block.size() - sizeof(quint32));

376
        ioDevice->write(block);
377
    }
378 379 380 381
}

void NodeInstanceServerProxy::writeCommand(const QVariant &command)
{
382 383 384 385 386
    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()) {
Robert Loehning's avatar
Robert Loehning committed
387
        qDebug() << "Write stream to file: " << m_captureFileForTest.fileName();
388 389 390 391
        writeCommandToIODecive(command, &m_captureFileForTest, m_writeCommandCounter);
        qDebug() << "\twrite file: " << m_captureFileForTest.pos();
    }

392
    m_writeCommandCounter++;
393 394 395 396 397
    if (m_runModus == TestModus) {
        static int synchronizeId = 0;
        synchronizeId++;
        SynchronizeCommand synchronizeCommand(synchronizeId);

398
        writeCommandToIODecive(QVariant::fromValue(synchronizeCommand), m_firstSocket.data(), m_writeCommandCounter);
399
        m_writeCommandCounter++;
400

401
        while (m_firstSocket->waitForReadyRead(100)) {
402 403 404 405 406
                readFirstDataStream();
                if (m_synchronizeId == synchronizeId)
                    return;
        }
    }
407 408
}

409
void NodeInstanceServerProxy::processFinished(int exitCode, QProcess::ExitStatus exitStatus)
410
{
Tim Jenssen's avatar
Tim Jenssen committed
411 412 413 414 415
    QProcess* finishedProcess = qobject_cast<QProcess*>(sender());
    if (finishedProcess)
        qWarning() << "Process" << (exitStatus == QProcess::CrashExit ? "crashed:" : "finished:") << finishedProcess->arguments() << "exitCode:" << exitCode;
    else
        qWarning() << "Process" << (exitStatus == QProcess::CrashExit ? "crashed:" : "finished:") << sender() << "exitCode:" << exitCode;
416

417 418
    if (m_captureFileForTest.isOpen()) {
        m_captureFileForTest.close();
419
        Core::AsynchronousMessageBox::warning(tr("QML Emulation Layer (QML Puppet) Crashed"),
420
                             tr("You are recording a puppet stream and the emulations layer crashed. "
421
                                "It is recommended to reopen the Qt Quick Designer and start again."));
422 423 424
    }


425 426
    writeCommand(QVariant::fromValue(EndPuppetCommand()));

427 428
    if (m_firstSocket) {
        m_firstSocket->waitForBytesWritten(1000);
429
        m_firstSocket->abort();
430 431 432 433
    }

    if (m_secondSocket) {
        m_secondSocket->waitForBytesWritten(1000);
434
        m_secondSocket->abort();
435 436 437 438
    }

    if (m_thirdSocket) {
        m_thirdSocket->waitForBytesWritten(1000);
439
        m_thirdSocket->abort();
440
    }
441

442 443
    if (exitStatus == QProcess::CrashExit)
        emit processCrashed();
444 445
}

446

447 448 449 450 451 452 453 454 455
void NodeInstanceServerProxy::readFirstDataStream()
{
    QList<QVariant> commandList;

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

        QDataStream in(m_firstSocket.data());
456
        in.setVersion(QDataStream::Qt_4_8);
457

458
        if (m_firstBlockSize == 0)
459 460 461 462 463
            in >> m_firstBlockSize;

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

464 465 466 467 468 469 470 471
        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;


472 473 474 475 476 477 478 479
        QVariant command;
        in >> command;
        m_firstBlockSize = 0;

        commandList.append(command);
    }

    foreach (const QVariant &command, commandList) {
480
        dispatchCommand(command, FirstPuppetStream);
481 482 483 484
    }
}

void NodeInstanceServerProxy::readSecondDataStream()
485 486 487
{
    QList<QVariant> commandList;

488 489
    while (!m_secondSocket->atEnd()) {
        if (m_secondSocket->bytesAvailable() < int(sizeof(quint32)))
490 491
            break;

492
        QDataStream in(m_secondSocket.data());
493
        in.setVersion(QDataStream::Qt_4_8);
494

495
        if (m_secondBlockSize == 0)
496
            in >> m_secondBlockSize;
497

498
        if (m_secondSocket->bytesAvailable() < m_secondBlockSize)
499 500
            break;

501 502 503 504 505 506 507 508
        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;


509 510
        QVariant command;
        in >> command;
511
        m_secondBlockSize = 0;
512 513 514 515 516

        commandList.append(command);
    }

    foreach (const QVariant &command, commandList) {
517
        dispatchCommand(command, SecondPuppetStream);
518 519 520
    }
}

521 522 523 524 525 526 527 528 529
void NodeInstanceServerProxy::readThirdDataStream()
{
    QList<QVariant> commandList;

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

        QDataStream in(m_thirdSocket.data());
530
        in.setVersion(QDataStream::Qt_4_8);
531

532
        if (m_thirdBlockSize == 0)
533 534 535 536 537
            in >> m_thirdBlockSize;

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

538 539 540 541 542 543 544 545
        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;


546 547 548 549 550 551 552 553
        QVariant command;
        in >> command;
        m_thirdBlockSize = 0;

        commandList.append(command);
    }

    foreach (const QVariant &command, commandList) {
554
        dispatchCommand(command, ThirdPuppetStream);
555 556 557
    }
}

558 559
void NodeInstanceServerProxy::printEditorProcessOutput()
{
560
    while (m_qmlPuppetEditorProcess && m_qmlPuppetEditorProcess->canReadLine()) {
561 562
        QByteArray line = m_qmlPuppetEditorProcess->readLine();
        line.chop(1);
563
        qDebug().nospace() << "Editor Puppet: " << line;
564 565 566 567 568 569
    }
    qDebug() << "\n";
}

void NodeInstanceServerProxy::printPreviewProcessOutput()
{
570
    while (m_qmlPuppetPreviewProcess && m_qmlPuppetPreviewProcess->canReadLine()) {
571 572
        QByteArray line = m_qmlPuppetPreviewProcess->readLine();
        line.chop(1);
573
        qDebug().nospace() << "Preview Puppet: " << line;
574 575 576 577 578 579
    }
    qDebug() << "\n";
}

void NodeInstanceServerProxy::printRenderProcessOutput()
{
580
    while (m_qmlPuppetRenderProcess && m_qmlPuppetRenderProcess->canReadLine()) {
581 582
        QByteArray line = m_qmlPuppetRenderProcess->readLine();
        line.chop(1);
583
        qDebug().nospace() << "Render Puppet: " << line;
584 585 586 587 588
    }

    qDebug() << "\n";
}

589 590 591 592 593 594 595 596 597 598 599 600
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)
{
601
    qCInfo(instanceViewBenchmark) << Q_FUNC_INFO << m_benchmarkTimer.elapsed();
602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629
    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));
}

630 631 632 633 634
void NodeInstanceServerProxy::changeAuxiliaryValues(const ChangeAuxiliaryCommand &command)
{
    writeCommand(QVariant::fromValue(command));
}

635 636 637 638 639 640 641 642 643 644 645 646 647 648 649
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));
}

650 651 652 653
void NodeInstanceServerProxy::completeComponent(const CompleteComponentCommand &command)
{
    writeCommand(QVariant::fromValue(command));
}
654

655
void NodeInstanceServerProxy::changeNodeSource(const ChangeNodeSourceCommand &command)
656 657 658 659
{
    writeCommand(QVariant::fromValue(command));
}

660 661 662 663 664
void NodeInstanceServerProxy::token(const TokenCommand &command)
{
    writeCommand(QVariant::fromValue(command));
}

665 666 667 668 669
void NodeInstanceServerProxy::removeSharedMemory(const RemoveSharedMemoryCommand &command)
{
   writeCommand(QVariant::fromValue(command));
}

670 671 672 673 674
void NodeInstanceServerProxy::benchmark(const QString &message)
{
    qCInfo(instanceViewBenchmark) << message << m_benchmarkTimer.elapsed();
}

675
} // namespace QmlDesigner