forked from qt-creator/qt-creator
QmlDebugger: Refactored QmlEngine and QmlCppEngine
Reviewed by: hjk
This commit is contained in:
@@ -30,27 +30,24 @@ DebuggerEngine *createQmlCppEngine(const DebuggerStartParameters &sp)
|
||||
|
||||
} // namespace Internal
|
||||
|
||||
struct QmlCppEnginePrivate
|
||||
{
|
||||
class QmlCppEnginePrivate {
|
||||
public:
|
||||
QmlCppEnginePrivate();
|
||||
~QmlCppEnginePrivate() {}
|
||||
|
||||
friend class QmlCppEngine;
|
||||
private:
|
||||
QmlEngine *m_qmlEngine;
|
||||
DebuggerEngine *m_cppEngine;
|
||||
DebuggerEngine *m_activeEngine;
|
||||
bool m_shutdownOk;
|
||||
bool m_shutdownDeferred;
|
||||
bool m_shutdownDone;
|
||||
bool m_isInitialStartup;
|
||||
DebuggerState m_errorState;
|
||||
};
|
||||
|
||||
QmlCppEnginePrivate::QmlCppEnginePrivate()
|
||||
: m_qmlEngine(0)
|
||||
, m_cppEngine(0)
|
||||
, m_activeEngine(0)
|
||||
, m_shutdownOk(true)
|
||||
, m_shutdownDeferred(false)
|
||||
, m_shutdownDone(false)
|
||||
, m_isInitialStartup(true)
|
||||
QmlCppEnginePrivate::QmlCppEnginePrivate() :
|
||||
m_qmlEngine(0),
|
||||
m_cppEngine(0),
|
||||
m_activeEngine(0),
|
||||
m_errorState(InferiorRunOk)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -58,7 +55,6 @@ QmlCppEngine::QmlCppEngine(const DebuggerStartParameters &sp)
|
||||
: DebuggerEngine(sp), d(new QmlCppEnginePrivate)
|
||||
{
|
||||
d->m_qmlEngine = qobject_cast<QmlEngine*>(Internal::createQmlEngine(sp));
|
||||
d->m_qmlEngine->setAttachToRunningExternalApp(true);
|
||||
|
||||
if (startParameters().cppEngineType == GdbEngineType) {
|
||||
d->m_cppEngine = Internal::createGdbEngine(sp);
|
||||
@@ -87,10 +83,10 @@ QmlCppEngine::QmlCppEngine(const DebuggerStartParameters &sp)
|
||||
|
||||
QmlCppEngine::~QmlCppEngine()
|
||||
{
|
||||
delete d->m_qmlEngine;
|
||||
d->m_qmlEngine = 0;
|
||||
delete d->m_cppEngine;
|
||||
d->m_cppEngine = 0;
|
||||
if (d->m_qmlEngine)
|
||||
delete d->m_qmlEngine;
|
||||
if (d->m_cppEngine)
|
||||
delete d->m_cppEngine;
|
||||
}
|
||||
|
||||
void QmlCppEngine::editorChanged(Core::IEditor *editor)
|
||||
@@ -128,6 +124,15 @@ void QmlCppEngine::setActiveEngine(DebuggerLanguage language)
|
||||
}
|
||||
}
|
||||
|
||||
DebuggerLanguage QmlCppEngine::activeEngine() const
|
||||
{
|
||||
if (d->m_activeEngine == d->m_cppEngine)
|
||||
return CppLanguage;
|
||||
if (d->m_activeEngine == d->m_qmlEngine)
|
||||
return QmlLanguage;
|
||||
return AnyLanguage;
|
||||
}
|
||||
|
||||
void QmlCppEngine::setToolTipExpression(const QPoint & mousePos,
|
||||
TextEditor::ITextEditor *editor, int cursorPos)
|
||||
{
|
||||
@@ -332,17 +337,31 @@ void QmlCppEngine::executeReturn()
|
||||
|
||||
void QmlCppEngine::continueInferior()
|
||||
{
|
||||
d->m_activeEngine->continueInferior();
|
||||
if (d->m_activeEngine->state() == InferiorStopOk) {
|
||||
d->m_activeEngine->continueInferior();
|
||||
} else {
|
||||
notifyInferiorRunRequested();
|
||||
}
|
||||
}
|
||||
|
||||
void QmlCppEngine::interruptInferior()
|
||||
{
|
||||
d->m_activeEngine->interruptInferior();
|
||||
if (d->m_activeEngine->state() == InferiorRunOk) {
|
||||
d->m_activeEngine->requestInterruptInferior();
|
||||
} else {
|
||||
if (d->m_activeEngine->state() == InferiorStopOk && (!checkErrorState(InferiorStopFailed))) {
|
||||
notifyInferiorStopOk();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QmlCppEngine::requestInterruptInferior()
|
||||
{
|
||||
d->m_activeEngine->requestInterruptInferior();
|
||||
DebuggerEngine::requestInterruptInferior();
|
||||
|
||||
if (d->m_activeEngine->state() == InferiorRunOk) {
|
||||
d->m_activeEngine->requestInterruptInferior();
|
||||
}
|
||||
}
|
||||
|
||||
void QmlCppEngine::executeRunToLine(const QString &fileName, int lineNumber)
|
||||
@@ -375,6 +394,50 @@ void QmlCppEngine::frameDown()
|
||||
d->m_activeEngine->frameDown();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
|
||||
bool QmlCppEngine::checkErrorState(const DebuggerState stateToCheck)
|
||||
{
|
||||
if (d->m_errorState != stateToCheck)
|
||||
return false;
|
||||
|
||||
// reset state ( so that more than one error can accumulate over time )
|
||||
d->m_errorState = InferiorRunOk;
|
||||
switch (stateToCheck) {
|
||||
case InferiorRunOk:
|
||||
// nothing to do
|
||||
break;
|
||||
case EngineRunFailed:
|
||||
notifyEngineRunFailed();
|
||||
break;
|
||||
case EngineSetupFailed:
|
||||
notifyEngineSetupFailed();
|
||||
break;
|
||||
case EngineShutdownFailed:
|
||||
notifyEngineShutdownFailed();
|
||||
break;
|
||||
case InferiorSetupFailed:
|
||||
notifyInferiorSetupFailed();
|
||||
break;
|
||||
case InferiorRunFailed:
|
||||
notifyInferiorRunFailed();
|
||||
break;
|
||||
case InferiorUnrunnable:
|
||||
notifyInferiorUnrunnable();
|
||||
break;
|
||||
case InferiorStopFailed:
|
||||
notifyInferiorStopFailed();
|
||||
break;
|
||||
case InferiorShutdownFailed:
|
||||
notifyInferiorShutdownFailed();
|
||||
break;
|
||||
default:
|
||||
// unexpected
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void QmlCppEngine::notifyInferiorRunOk()
|
||||
{
|
||||
DebuggerEngine::notifyInferiorRunOk();
|
||||
@@ -390,56 +453,68 @@ void QmlCppEngine::setupEngine()
|
||||
|
||||
void QmlCppEngine::setupInferior()
|
||||
{
|
||||
// called through notifyEngineSetupOk
|
||||
if (!checkErrorState(InferiorSetupFailed)) {
|
||||
notifyInferiorSetupOk();
|
||||
}
|
||||
}
|
||||
|
||||
void QmlCppEngine::runEngine()
|
||||
{
|
||||
// should never happen
|
||||
showMessage(QString(Q_FUNC_INFO), LogError);
|
||||
if (!checkErrorState(EngineRunFailed)) {
|
||||
if (d->m_errorState == InferiorRunOk) {
|
||||
switch (d->m_activeEngine->state()) {
|
||||
case InferiorRunOk:
|
||||
notifyEngineRunAndInferiorRunOk();
|
||||
break;
|
||||
case InferiorStopOk:
|
||||
notifyEngineRunAndInferiorStopOk();
|
||||
break;
|
||||
default: // not supported?
|
||||
notifyEngineRunFailed();
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
notifyEngineRunFailed();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QmlCppEngine::shutdownInferior()
|
||||
{
|
||||
// user wants to stop inferior: always use cpp engine for this.
|
||||
if (d->m_activeEngine == d->m_qmlEngine) {
|
||||
d->m_activeEngine = d->m_cppEngine;
|
||||
|
||||
// we end up in this state after trying to shut down while debugging qml.
|
||||
// b/c qml does not shutdown by itself, restore previous state and continue.
|
||||
if (d->m_qmlEngine->state() == InferiorShutdownRequested) {
|
||||
d->m_qmlEngine->setState(InferiorStopOk, true);
|
||||
}
|
||||
|
||||
if (d->m_qmlEngine->state() == InferiorStopOk) {
|
||||
d->m_qmlEngine->continueInferior();
|
||||
if (!checkErrorState(InferiorShutdownFailed)) {
|
||||
if (d->m_cppEngine->state() == InferiorStopOk) {
|
||||
d->m_cppEngine->shutdownInferior();
|
||||
} else {
|
||||
notifyInferiorShutdownOk();
|
||||
}
|
||||
}
|
||||
if (d->m_cppEngine->state() == InferiorRunOk) {
|
||||
// first interrupt c++ engine; when done, we can shutdown.
|
||||
d->m_shutdownDeferred = true;
|
||||
d->m_cppEngine->requestInterruptInferior();
|
||||
}
|
||||
|
||||
void QmlCppEngine::initEngineShutdown()
|
||||
{
|
||||
if (d->m_qmlEngine->state() != DebuggerFinished) {
|
||||
d->m_qmlEngine->quitDebugger();
|
||||
} else
|
||||
if (d->m_cppEngine->state() != DebuggerFinished) {
|
||||
d->m_cppEngine->quitDebugger();
|
||||
} else
|
||||
if (state() == EngineSetupRequested) {
|
||||
if (!checkErrorState(EngineSetupFailed)) {
|
||||
notifyEngineSetupOk();
|
||||
}
|
||||
} else
|
||||
if (state() == InferiorStopRequested) {
|
||||
checkErrorState(InferiorStopFailed);
|
||||
} else {
|
||||
quitDebugger();
|
||||
}
|
||||
if (!d->m_shutdownDeferred)
|
||||
d->m_cppEngine->shutdownInferior();
|
||||
}
|
||||
|
||||
void QmlCppEngine::shutdownEngine()
|
||||
{
|
||||
d->m_cppEngine->shutdownEngine();
|
||||
d->m_qmlEngine->shutdownEngineAsSlave();
|
||||
notifyEngineShutdownOk();
|
||||
}
|
||||
|
||||
void QmlCppEngine::finishDebugger()
|
||||
{
|
||||
if (!d->m_shutdownDone) {
|
||||
d->m_shutdownDone = true;
|
||||
if (d->m_shutdownOk) {
|
||||
notifyEngineShutdownOk();
|
||||
} else {
|
||||
notifyEngineShutdownFailed();
|
||||
}
|
||||
if (!checkErrorState(EngineShutdownFailed)) {
|
||||
showStatusMessage(tr("Debugging finished"));
|
||||
notifyEngineShutdownOk();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -450,229 +525,105 @@ void QmlCppEngine::setupSlaveEngineOnTimer()
|
||||
|
||||
void QmlCppEngine::setupSlaveEngine()
|
||||
{
|
||||
if (state() == InferiorRunRequested)
|
||||
if (d->m_qmlEngine->state() == DebuggerNotReady)
|
||||
d->m_qmlEngine->startDebugger(runControl());
|
||||
}
|
||||
|
||||
void QmlCppEngine::masterEngineStateChanged(const DebuggerState &newState)
|
||||
{
|
||||
//qDebug() << "gdb state set to" << newState;
|
||||
|
||||
switch(newState) {
|
||||
case EngineSetupRequested:
|
||||
// go through this state
|
||||
break;
|
||||
|
||||
case EngineSetupFailed:
|
||||
notifyEngineSetupFailed();
|
||||
break;
|
||||
|
||||
case EngineSetupOk:
|
||||
notifyEngineSetupOk();
|
||||
break;
|
||||
|
||||
case InferiorSetupRequested:
|
||||
// go through this state
|
||||
break;
|
||||
|
||||
case InferiorSetupFailed:
|
||||
notifyInferiorSetupFailed();
|
||||
break;
|
||||
|
||||
case EngineRunRequested:
|
||||
setState(newState);
|
||||
break;
|
||||
|
||||
case EngineRunFailed:
|
||||
notifyEngineRunFailed();
|
||||
break;
|
||||
|
||||
case InferiorUnrunnable:
|
||||
setState(newState);
|
||||
break;
|
||||
|
||||
case InferiorRunRequested:
|
||||
setState(newState);
|
||||
break;
|
||||
|
||||
case InferiorRunOk:
|
||||
if (d->m_qmlEngine->state() == DebuggerNotReady) {
|
||||
if (d->m_isInitialStartup) {
|
||||
d->m_isInitialStartup = false;
|
||||
setupSlaveEngineOnTimer();
|
||||
} else {
|
||||
setupSlaveEngine();
|
||||
}
|
||||
} else {
|
||||
notifyInferiorRunOk();
|
||||
}
|
||||
break;
|
||||
|
||||
case InferiorRunFailed:
|
||||
notifyInferiorRunFailed();
|
||||
break;
|
||||
|
||||
case InferiorStopRequested:
|
||||
if (state() == InferiorRunRequested) {
|
||||
// if stopping on startup, move on to normal state
|
||||
// and go forward. Also, stop connection and continue later if needed.
|
||||
d->m_qmlEngine->pauseConnection();
|
||||
setState(EngineRunRequested, true);
|
||||
notifyEngineRunAndInferiorRunOk();
|
||||
setState(newState);
|
||||
} else {
|
||||
setState(newState);
|
||||
}
|
||||
break;
|
||||
|
||||
case InferiorStopOk:
|
||||
// debugger can stop while qml connection is not made yet, so we can
|
||||
// end up in an illegal state transition here.
|
||||
if (state() == InferiorStopRequested
|
||||
|| state() == InferiorRunFailed)
|
||||
{
|
||||
setState(newState);
|
||||
} else if (state() == InferiorRunOk) {
|
||||
// if we break on CPP side while running & engine is QML, switch.
|
||||
if (d->m_activeEngine == d->m_qmlEngine) {
|
||||
setActiveEngine(CppLanguage);
|
||||
}
|
||||
setState(newState);
|
||||
} else if (state() == InferiorRunRequested) {
|
||||
setState(newState, true);
|
||||
}
|
||||
if (d->m_shutdownDeferred) {
|
||||
d->m_activeEngine = d->m_cppEngine;
|
||||
d->m_shutdownDeferred = false;
|
||||
shutdownInferior();
|
||||
}
|
||||
break;
|
||||
|
||||
case InferiorStopFailed:
|
||||
setState(newState);
|
||||
if (d->m_shutdownDeferred) {
|
||||
d->m_activeEngine = d->m_cppEngine;
|
||||
d->m_shutdownDeferred = false;
|
||||
shutdownInferior();
|
||||
}
|
||||
break;
|
||||
|
||||
// here, we shut down the qml engine first.
|
||||
// but due to everything being asynchronous, we cannot guarantee
|
||||
// that it is shut down completely before gdb engine is shut down.
|
||||
case InferiorShutdownRequested:
|
||||
if (d->m_activeEngine == d->m_qmlEngine) {
|
||||
d->m_activeEngine = d->m_cppEngine;
|
||||
}
|
||||
|
||||
d->m_qmlEngine->shutdownInferiorAsSlave();
|
||||
setState(newState);
|
||||
break;
|
||||
|
||||
case InferiorShutdownOk:
|
||||
setState(newState);
|
||||
d->m_qmlEngine->shutdownEngineAsSlave();
|
||||
break;
|
||||
|
||||
case InferiorShutdownFailed:
|
||||
setState(newState);
|
||||
d->m_qmlEngine->shutdownEngineAsSlave();
|
||||
break;
|
||||
|
||||
case EngineShutdownRequested:
|
||||
setState(newState);
|
||||
break;
|
||||
|
||||
case EngineShutdownOk:
|
||||
finishDebugger();
|
||||
break;
|
||||
|
||||
case EngineShutdownFailed:
|
||||
d->m_shutdownOk = false;
|
||||
finishDebugger();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
if (newState == InferiorStopOk) {
|
||||
setActiveEngine(CppLanguage);
|
||||
}
|
||||
engineStateChanged(newState);
|
||||
}
|
||||
|
||||
void QmlCppEngine::slaveEngineStateChanged(const DebuggerState &newState)
|
||||
{
|
||||
//qDebug() << " qml engine changed to" << newState;
|
||||
|
||||
if (d->m_activeEngine == d->m_qmlEngine) {
|
||||
handleSlaveEngineStateChangeAsActive(newState);
|
||||
} else {
|
||||
handleSlaveEngineStateChange(newState);
|
||||
if (newState == InferiorStopOk) {
|
||||
setActiveEngine(QmlLanguage);
|
||||
}
|
||||
engineStateChanged(newState);
|
||||
}
|
||||
|
||||
void QmlCppEngine::handleSlaveEngineStateChange(const DebuggerState &newState)
|
||||
|
||||
void QmlCppEngine::engineStateChanged(const DebuggerState &newState)
|
||||
{
|
||||
switch(newState) {
|
||||
switch (newState) {
|
||||
case InferiorRunOk:
|
||||
if (state() == InferiorRunRequested) {
|
||||
// force state back so that the notification will succeed on init
|
||||
setState(EngineRunRequested, true);
|
||||
notifyEngineRunAndInferiorRunOk();
|
||||
} else {
|
||||
// we have to manually override state with current one, because
|
||||
// otherwise we'll have debugger controls in inconsistent state.
|
||||
setState(state(), true);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case InferiorStopOk:
|
||||
if (state() == InferiorRunOk) {
|
||||
// breakpoint was hit while running the app; change the active engine.
|
||||
setActiveEngine(QmlLanguage);
|
||||
setState(InferiorStopOk);
|
||||
// startup?
|
||||
if (d->m_qmlEngine->state() == DebuggerNotReady) {
|
||||
setupSlaveEngine();
|
||||
} else
|
||||
if (d->m_cppEngine->state() == DebuggerNotReady) {
|
||||
setupEngine();
|
||||
} else
|
||||
if (state() == EngineSetupRequested) {
|
||||
notifyEngineSetupOk();
|
||||
} else
|
||||
// breakpoint?
|
||||
if (state() == InferiorStopOk) {
|
||||
continueInferior();
|
||||
} else
|
||||
if (state() == InferiorStopRequested) {
|
||||
checkErrorState(InferiorStopFailed);
|
||||
} else
|
||||
if (state() == InferiorRunRequested && (!checkErrorState(InferiorRunFailed)) && (!checkErrorState(InferiorUnrunnable))) {
|
||||
notifyInferiorRunOk();
|
||||
}
|
||||
break;
|
||||
|
||||
case InferiorRunFailed:
|
||||
notifyInferiorRunFailed();
|
||||
break;
|
||||
|
||||
case EngineShutdownFailed:
|
||||
d->m_shutdownOk = false;
|
||||
break;
|
||||
|
||||
default:
|
||||
// reset wrapper engine state to current state.
|
||||
setState(state(), true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void QmlCppEngine::handleSlaveEngineStateChangeAsActive(const DebuggerState &newState)
|
||||
{
|
||||
switch(newState) {
|
||||
case InferiorRunRequested:
|
||||
setState(newState);
|
||||
// follow the inferior
|
||||
if (state() == InferiorStopOk && checkErrorState(InferiorRunOk)) {
|
||||
continueInferior();
|
||||
}
|
||||
break;
|
||||
|
||||
case InferiorRunOk:
|
||||
setState(newState);
|
||||
case InferiorStopRequested:
|
||||
// follow the inferior
|
||||
if (state() == InferiorRunOk && checkErrorState(InferiorRunOk)) {
|
||||
requestInterruptInferior();
|
||||
}
|
||||
break;
|
||||
|
||||
case InferiorStopOk:
|
||||
setState(newState);
|
||||
// check breakpoints
|
||||
if (state() == InferiorRunRequested) {
|
||||
checkErrorState(InferiorRunFailed);
|
||||
} else
|
||||
if (checkErrorState(InferiorRunOk)) {
|
||||
if (state() == InferiorRunOk) {
|
||||
requestInterruptInferior();
|
||||
} else
|
||||
if (state() == InferiorStopRequested) {
|
||||
interruptInferior();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case EngineRunFailed:
|
||||
case EngineSetupFailed:
|
||||
case EngineShutdownFailed:
|
||||
case InferiorSetupFailed:
|
||||
case InferiorRunFailed:
|
||||
notifyInferiorRunFailed();
|
||||
case InferiorUnrunnable:
|
||||
case InferiorStopFailed:
|
||||
case InferiorShutdownFailed:
|
||||
if (d->m_errorState == InferiorRunOk) {
|
||||
d->m_errorState = newState;
|
||||
}
|
||||
break;
|
||||
|
||||
case InferiorShutdownRequested:
|
||||
if (d->m_cppEngine->state() == InferiorRunOk) {
|
||||
// occurs when user presses stop button from debugger UI.
|
||||
shutdownInferior();
|
||||
if (activeEngine() == QmlLanguage) {
|
||||
setActiveEngine(CppLanguage);
|
||||
}
|
||||
break;
|
||||
|
||||
case DebuggerFinished:
|
||||
initEngineShutdown();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ public:
|
||||
explicit QmlCppEngine(const DebuggerStartParameters &sp);
|
||||
virtual ~QmlCppEngine();
|
||||
|
||||
DebuggerLanguage activeEngine() const;
|
||||
void setActiveEngine(DebuggerLanguage language);
|
||||
|
||||
virtual void setToolTipExpression(const QPoint &mousePos,
|
||||
@@ -107,9 +108,9 @@ private slots:
|
||||
|
||||
private:
|
||||
void setupSlaveEngineOnTimer();
|
||||
void finishDebugger();
|
||||
void handleSlaveEngineStateChange(const DebuggerState &newState);
|
||||
void handleSlaveEngineStateChangeAsActive(const DebuggerState &newState);
|
||||
void initEngineShutdown();
|
||||
bool checkErrorState(const DebuggerState stateToCheck);
|
||||
void engineStateChanged(const DebuggerState &newState);
|
||||
|
||||
private:
|
||||
QScopedPointer<QmlCppEnginePrivate> d;
|
||||
|
||||
@@ -143,26 +143,23 @@ static QDataStream &operator>>(QDataStream &s, StackFrame &frame)
|
||||
|
||||
} // namespace Internal
|
||||
|
||||
|
||||
using namespace Internal;
|
||||
|
||||
struct QmlEnginePrivate
|
||||
{
|
||||
class QmlEnginePrivate {
|
||||
public:
|
||||
explicit QmlEnginePrivate(QmlEngine *q);
|
||||
|
||||
friend class QmlEngine;
|
||||
private:
|
||||
int m_ping;
|
||||
QmlAdapter *m_adapter;
|
||||
ProjectExplorer::ApplicationLauncher m_applicationLauncher;
|
||||
bool m_addedAdapterToObjectPool;
|
||||
bool m_attachToRunningExternalApp;
|
||||
bool m_hasShutdown;
|
||||
};
|
||||
|
||||
QmlEnginePrivate::QmlEnginePrivate(QmlEngine *q)
|
||||
: m_ping(0)
|
||||
, m_adapter(new QmlAdapter(q))
|
||||
, m_addedAdapterToObjectPool(false)
|
||||
, m_attachToRunningExternalApp(false)
|
||||
, m_hasShutdown(false)
|
||||
QmlEnginePrivate::QmlEnginePrivate(QmlEngine *q) :
|
||||
m_ping(0)
|
||||
, m_adapter(new QmlAdapter(q))
|
||||
{
|
||||
}
|
||||
|
||||
@@ -180,16 +177,7 @@ QmlEngine::QmlEngine(const DebuggerStartParameters &startParameters)
|
||||
|
||||
QmlEngine::~QmlEngine()
|
||||
{
|
||||
}
|
||||
|
||||
void QmlEngine::setAttachToRunningExternalApp(bool value)
|
||||
{
|
||||
d->m_attachToRunningExternalApp = value;
|
||||
}
|
||||
|
||||
void QmlEngine::pauseConnection()
|
||||
{
|
||||
d->m_adapter->pauseConnection();
|
||||
delete d->m_adapter;
|
||||
}
|
||||
|
||||
void QmlEngine::gotoLocation(const QString &fileName, int lineNumber, bool setMarker)
|
||||
@@ -242,11 +230,11 @@ void QmlEngine::connectionEstablished()
|
||||
ExtensionSystem::PluginManager::instance();
|
||||
pluginManager->addObject(d->m_adapter);
|
||||
pluginManager->addObject(this);
|
||||
d->m_addedAdapterToObjectPool = true;
|
||||
|
||||
showMessage(tr("QML Debugger connected."), StatusBar);
|
||||
|
||||
notifyEngineRunAndInferiorRunOk();
|
||||
|
||||
}
|
||||
|
||||
void QmlEngine::connectionStartupFailed()
|
||||
@@ -271,20 +259,53 @@ void QmlEngine::serviceConnectionError(const QString &serviceName)
|
||||
.arg(serviceName), StatusBar);
|
||||
}
|
||||
|
||||
void QmlEngine::pauseConnection()
|
||||
{
|
||||
d->m_adapter->pauseConnection();
|
||||
}
|
||||
|
||||
void QmlEngine::closeConnection()
|
||||
{
|
||||
ExtensionSystem::PluginManager *pluginManager = ExtensionSystem::PluginManager::instance();
|
||||
if (pluginManager->allObjects().contains(this)) {
|
||||
disconnect(d->m_adapter, SIGNAL(connectionStartupFailed()), this, SLOT(connectionStartupFailed()));
|
||||
d->m_adapter->closeConnection();
|
||||
|
||||
pluginManager->removeObject(d->m_adapter);
|
||||
pluginManager->removeObject(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void QmlEngine::runEngine()
|
||||
{
|
||||
QTC_ASSERT(state() == EngineRunRequested, qDebug() << state());
|
||||
|
||||
if (!d->m_attachToRunningExternalApp) {
|
||||
d->m_applicationLauncher.start(ProjectExplorer::ApplicationLauncher::Gui,
|
||||
startParameters().executable,
|
||||
startParameters().processArgs);
|
||||
if (!isSlaveEngine()) {
|
||||
startApplicationLauncher();
|
||||
}
|
||||
|
||||
d->m_adapter->beginConnection();
|
||||
showMessage(tr("QML Debugger connecting..."), StatusBar);
|
||||
}
|
||||
|
||||
void QmlEngine::startApplicationLauncher()
|
||||
{
|
||||
if (!d->m_applicationLauncher.isRunning()) {
|
||||
d->m_applicationLauncher.start(ProjectExplorer::ApplicationLauncher::Gui,
|
||||
startParameters().executable,
|
||||
startParameters().processArgs);
|
||||
}
|
||||
}
|
||||
|
||||
void QmlEngine::stopApplicationLauncher()
|
||||
{
|
||||
if (d->m_applicationLauncher.isRunning()) {
|
||||
disconnect(&d->m_applicationLauncher, SIGNAL(processExited(int)), this, SLOT(disconnected()));
|
||||
d->m_applicationLauncher.stop();
|
||||
}
|
||||
}
|
||||
|
||||
void QmlEngine::handleRemoteSetupDone(int port)
|
||||
{
|
||||
if (port != -1)
|
||||
@@ -299,82 +320,25 @@ void QmlEngine::handleRemoteSetupFailed(const QString &message)
|
||||
notifyInferiorSetupFailed();
|
||||
}
|
||||
|
||||
void QmlEngine::shutdownInferiorAsSlave()
|
||||
{
|
||||
resetLocation();
|
||||
|
||||
// This can be issued in almost any state. We assume, though,
|
||||
// that at this point of time the inferior is not running anymore,
|
||||
// even if stop notification were not issued or got lost.
|
||||
if (state() == InferiorRunOk) {
|
||||
setState(InferiorStopRequested);
|
||||
setState(InferiorStopOk);
|
||||
setState(InferiorShutdownRequested);
|
||||
setState(InferiorShutdownOk);
|
||||
} else {
|
||||
// force
|
||||
setState(InferiorShutdownRequested, true);
|
||||
setState(InferiorShutdownOk);
|
||||
}
|
||||
}
|
||||
|
||||
void QmlEngine::shutdownEngineAsSlave()
|
||||
{
|
||||
if (d->m_hasShutdown)
|
||||
return;
|
||||
|
||||
disconnect(d->m_adapter, SIGNAL(connectionStartupFailed()),
|
||||
this, SLOT(connectionStartupFailed()));
|
||||
d->m_adapter->closeConnection();
|
||||
|
||||
if (d->m_addedAdapterToObjectPool) {
|
||||
ExtensionSystem::PluginManager *pluginManager =
|
||||
ExtensionSystem::PluginManager::instance();
|
||||
pluginManager->removeObject(d->m_adapter);
|
||||
pluginManager->removeObject(this);
|
||||
}
|
||||
|
||||
if (d->m_attachToRunningExternalApp) {
|
||||
setState(EngineShutdownRequested, true);
|
||||
setState(EngineShutdownOk, true);
|
||||
setState(DebuggerFinished, true);
|
||||
} else {
|
||||
if (d->m_applicationLauncher.isRunning()) {
|
||||
// should only happen if engine is ill
|
||||
disconnect(&d->m_applicationLauncher, SIGNAL(processExited(int)),
|
||||
this, SLOT(disconnected()));
|
||||
d->m_applicationLauncher.stop();
|
||||
}
|
||||
}
|
||||
d->m_hasShutdown = true;
|
||||
}
|
||||
|
||||
void QmlEngine::shutdownInferior()
|
||||
{
|
||||
// don't do normal shutdown if running as slave engine
|
||||
if (d->m_attachToRunningExternalApp)
|
||||
return;
|
||||
|
||||
QTC_ASSERT(state() == InferiorShutdownRequested, qDebug() << state());
|
||||
if (!d->m_applicationLauncher.isRunning()) {
|
||||
showMessage(tr("Trying to stop while process is no longer running."), LogError);
|
||||
} else {
|
||||
disconnect(&d->m_applicationLauncher, SIGNAL(processExited(int)),
|
||||
this, SLOT(disconnected()));
|
||||
if (!d->m_attachToRunningExternalApp)
|
||||
d->m_applicationLauncher.stop();
|
||||
if (isSlaveEngine()) {
|
||||
resetLocation();
|
||||
}
|
||||
stopApplicationLauncher();
|
||||
notifyInferiorShutdownOk();
|
||||
}
|
||||
|
||||
void QmlEngine::shutdownEngine()
|
||||
{
|
||||
QTC_ASSERT(state() == EngineShutdownRequested, qDebug() << state());
|
||||
closeConnection();
|
||||
|
||||
shutdownEngineAsSlave();
|
||||
// double check (ill engine?):
|
||||
stopApplicationLauncher();
|
||||
|
||||
notifyEngineShutdownOk();
|
||||
showMessage(QString(), StatusBar);
|
||||
if (!isSlaveEngine())
|
||||
showMessage(QString(), StatusBar);
|
||||
}
|
||||
|
||||
void QmlEngine::setupEngine()
|
||||
|
||||
@@ -51,13 +51,11 @@ public:
|
||||
void handleRemoteSetupDone(int port);
|
||||
void handleRemoteSetupFailed(const QString &message);
|
||||
|
||||
void setAttachToRunningExternalApp(bool value);
|
||||
void shutdownInferiorAsSlave();
|
||||
void shutdownEngineAsSlave();
|
||||
void pauseConnection();
|
||||
void gotoLocation(const QString &fileName, int lineNumber, bool setMarker);
|
||||
void gotoLocation(const Internal::StackFrame &frame, bool setMarker);
|
||||
|
||||
void pauseConnection();
|
||||
|
||||
public slots:
|
||||
void messageReceived(const QByteArray &message);
|
||||
void disconnected();
|
||||
@@ -128,6 +126,10 @@ private:
|
||||
void expandObject(const QByteArray &iname, quint64 objectId);
|
||||
void sendPing();
|
||||
|
||||
void closeConnection();
|
||||
void startApplicationLauncher();
|
||||
void stopApplicationLauncher();
|
||||
|
||||
bool isShadowBuildProject() const;
|
||||
QString fromShadowBuildFilename(const QString &filename) const;
|
||||
QString mangleFilenamePaths(const QString &filename,
|
||||
|
||||
Reference in New Issue
Block a user