Example #1
0
void QmlCppEngine::slaveEngineStateChanged
    (DebuggerEngine *slaveEngine, const DebuggerState newState)
{
    DebuggerEngine *otherEngine = (slaveEngine == m_cppEngine)
         ? m_qmlEngine : m_cppEngine;

    QTC_CHECK(otherEngine != slaveEngine);

    if (debug) {
        EDEBUG("GOT SLAVE STATE: " << slaveEngine << newState);
        EDEBUG("  OTHER ENGINE: " << otherEngine << otherEngine->state());
        EDEBUG("  COMBINED ENGINE: " << this << state() << isDying());
    }

    // Idea is to follow the state of the cpp engine, except where we are stepping in QML.
    // That is, when the QmlEngine moves between InferiorStopOk, and InferiorRunOk, InferiorStopOk ...
    //
    // Accordingly, the 'active engine' is the cpp engine until the qml engine enters the
    // InferiorStopOk state. The cpp engine becomes the active one again as soon as it itself enters
    // the InferiorStopOk state.

    if (slaveEngine == m_cppEngine) {
        switch (newState) {
        case DebuggerNotReady: {
            // Can this ever happen?
            break;
        }
        case EngineSetupRequested: {
            // set by queueSetupEngine()
            QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state());
            break;
        }
        case EngineSetupFailed: {
            qmlEngine()->quitDebugger();
            notifyEngineSetupFailed();
            break;
        }
        case EngineSetupOk: {
            notifyEngineSetupOk();
            break;
        }
        case InferiorSetupRequested: {
            // set by queueSetupInferior()
            QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
            break;
        }
        case InferiorSetupFailed: {
            qmlEngine()->quitDebugger();
            notifyInferiorSetupFailed();
            break;
        }
        case InferiorSetupOk: {
            notifyInferiorSetupOk();
            break;
        }
        case EngineRunRequested: {
            // set by queueRunEngine()
            break;
        }
        case EngineRunFailed: {
            qmlEngine()->quitDebugger();
            notifyEngineRunFailed();
            break;
        }
        case InferiorUnrunnable: {
            qmlEngine()->quitDebugger();
            notifyInferiorUnrunnable();
            break;
        }
        case InferiorRunRequested: {
            // might be set already by notifyInferiorRunRequested()
            QTC_ASSERT(state() == InferiorRunRequested
                       || state() == InferiorStopOk, qDebug() << state());
            if (state() != InferiorRunRequested)
                notifyInferiorRunRequested();
            break;
        }
        case InferiorRunOk: {
            QTC_ASSERT(state() == EngineRunRequested
                       || state() == InferiorRunRequested, qDebug() << state());
            if (state() == EngineRunRequested)
                notifyEngineRunAndInferiorRunOk();
            else if (state() == InferiorRunRequested)
                notifyInferiorRunOk();

            if (qmlEngine()->state() == InferiorStopOk) {
                // track qml engine again
                setState(InferiorStopRequested);
                notifyInferiorStopOk();
                setActiveEngine(m_qmlEngine);
            }
            break;
        }
        case InferiorRunFailed: {
            qmlEngine()->quitDebugger();
            notifyInferiorRunFailed();
            break;
        }
        case InferiorStopRequested: {
            if (m_activeEngine == cppEngine()) {
                // might be set by doInterruptInferior()
                QTC_ASSERT(state() == InferiorStopRequested
                           || state() == InferiorRunOk, qDebug() << state());
                if (state() == InferiorRunOk)
                    setState(InferiorStopRequested);
            } else {
                // we're debugging qml, but got an interrupt, or abort
                QTC_ASSERT(state() == InferiorRunOk
                          || state() == InferiorStopOk
                           || state() == InferiorRunRequested, qDebug() << state());

                if (state() == InferiorRunOk) {
                    setState(InferiorStopRequested);
                } else if (state() == InferiorStopOk) {
                    notifyInferiorRunRequested();
                    notifyInferiorRunOk();
                    setState(InferiorStopRequested);
                } else if (state() == InferiorRunRequested) {
                    notifyInferiorRunOk();
                    setState(InferiorStopRequested);
                }
                // now track cpp engine
                setActiveEngine(m_cppEngine);
            }
            break;
        }
        case InferiorStopOk: {
            if (isDying()) {
                EDEBUG("... CPP ENGINE STOPPED DURING SHUTDOWN ");
                QTC_ASSERT(state() == InferiorStopRequested
                           || state() == InferiorRunOk
                           || state() == InferiorStopOk, qDebug() << state());

                // Just to make sure, we're shutting down anyway ...
                setActiveEngine(m_cppEngine);

                if (state() == InferiorStopRequested)
                    setState(InferiorStopOk);
                // otherwise we're probably inside notifyInferiorStopOk already
            } else {
                if (m_activeEngine != cppEngine()) {
                    showStatusMessage(tr("C++ debugger activated"));
                    setActiveEngine(m_cppEngine);
                }

                QTC_ASSERT(state() == InferiorStopRequested
                           || state() == InferiorRunRequested
                           || state() == EngineRunRequested
                           || state() == InferiorRunOk
                           || state() == InferiorStopOk, qDebug() << state());
                switch (state()) {
                case InferiorStopRequested:
                    EDEBUG("... CPP ENGINE STOPPED EXPECTEDLY");
                    notifyInferiorStopOk();
                    break;
                case EngineRunRequested:
                    EDEBUG("... CPP ENGINE STOPPED ON STARTUP");
                    notifyEngineRunAndInferiorStopOk();
                    break;
                case InferiorRunOk:
                    EDEBUG("... CPP ENGINE STOPPED SPONTANEOUSLY");
                    notifyInferiorSpontaneousStop();
                    break;
                case InferiorRunRequested:
                    // can happen if qml engine was active
                    notifyInferiorRunFailed();
                default:
                    break;
                }
            }
            break;
        }
        case InferiorStopFailed: {
            QTC_ASSERT(state() == InferiorStopRequested, qDebug() << state());
            notifyInferiorStopFailed();
            break;
        }
        case InferiorExitOk: {
            // InferiorExitOk will be called through notifyInferiorExited
            // when InferiorShutDownOk is reached
            qmlEngine()->quitDebugger();
            break;
        }
        case InferiorShutdownRequested: {
            // might be set by queueShutdownInferior() already
            QTC_ASSERT(state() == InferiorShutdownRequested
                       || state() == InferiorStopOk, qDebug() << state());
            if (state() == InferiorStopOk)
                setState(InferiorShutdownRequested);
            qmlEngine()->quitDebugger();
            break;
        }
        case InferiorShutdownFailed: {
            QTC_ASSERT(state() == InferiorShutdownRequested, qDebug() << state());
            notifyInferiorShutdownFailed();
            break;
        }
        case InferiorShutdownOk: {
            if (state() == InferiorShutdownRequested) {
                notifyInferiorShutdownOk();
            } else {
                // we got InferiorExitOk before, but ignored it ...
                notifyInferiorExited();
            }
            break;
        }
        case EngineShutdownRequested: {
            // set by queueShutdownEngine()
            QTC_ASSERT(state() == EngineShutdownRequested, qDebug() << state());
            break;
        }
        case EngineShutdownFailed: {
            QTC_ASSERT(state() == EngineShutdownRequested, qDebug() << state());
            notifyEngineShutdownFailed();
            break;
        }
        case EngineShutdownOk: {
            QTC_ASSERT(state() == EngineShutdownRequested, qDebug() << state());
            notifyEngineShutdownOk();
            break;
        }
        case DebuggerFinished: {
            // set by queueFinishDebugger()
            QTC_ASSERT(state() == DebuggerFinished, qDebug() << state());
            break;
        }
        }
    } else {
        // QML engine state change
        if (newState == InferiorStopOk) {
            if (isDying()) {
                EDEBUG("... QML ENGINE STOPPED DURING SHUTDOWN ");

                // Just to make sure, we're shutting down anyway ...
                setActiveEngine(m_cppEngine);

                if (state() == InferiorStopRequested)
                    notifyInferiorStopOk();
                // otherwise we're probably inside notifyInferiorStopOk already
            } else {
                if (m_activeEngine != qmlEngine()) {
                    showStatusMessage(tr("QML debugger activated"));
                    setActiveEngine(m_qmlEngine);
                }

                QTC_ASSERT(state() == InferiorRunOk
                           || state() == InferiorStopRequested
                           || state() == InferiorShutdownRequested, qDebug() << state());

                if (state() == InferiorRunOk)
                    notifyInferiorSpontaneousStop();
                else if (state() == InferiorStopRequested)
                    notifyInferiorStopOk();
            }

        } else if (newState == InferiorRunOk) {
            if (m_activeEngine == qmlEngine()) {
                QTC_ASSERT(state() == InferiorRunRequested, qDebug() << state());
                notifyInferiorRunOk();
            }
        }
    }
}
void GdbCoreEngine::runEngine()
{
    QTC_ASSERT(state() == EngineRunRequested, qDebug() << state());
    notifyInferiorUnrunnable();
    updateAll();
}