| 1 | // SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. |
| 2 | // |
| 3 | // SPDX-License-Identifier: GPL-3.0-or-later |
| 4 | |
| 5 | #include "debugmanager.h" |
| 6 | #include "dap/dapdebugger.h" |
| 7 | #include "debuggersignals.h" |
| 8 | #include "debuggerglobals.h" |
| 9 | #include "interface/menumanager.h" |
| 10 | |
| 11 | #include "services/debugger/debuggerservice.h" |
| 12 | #include "services/language/languageservice.h" |
| 13 | #include "common/util/custompaths.h" |
| 14 | #include "services/project/projectinfo.h" |
| 15 | |
| 16 | using namespace DEBUG_NAMESPACE; |
| 17 | using namespace dpfservice; |
| 18 | DebugManager::DebugManager(QObject *parent) |
| 19 | : QObject(parent) |
| 20 | { |
| 21 | connect(debuggerSignals, &DebuggerSignals::receivedEvent, this, &DebugManager::handleEvents); |
| 22 | } |
| 23 | |
| 24 | bool DebugManager::initialize(dpfservice::WindowService *windowService, |
| 25 | dpfservice::DebuggerService *debuggerService) |
| 26 | { |
| 27 | currentDebugger = new DAPDebugger(this); |
| 28 | debuggers.insert("dap" , currentDebugger); |
| 29 | runner = new Runner(this); |
| 30 | |
| 31 | menuManager.reset(new MenuManager()); |
| 32 | menuManager->initialize(windowService); |
| 33 | |
| 34 | connect(currentDebugger, &AbstractDebugger::runStateChanged, this, &DebugManager::handleRunStateChanged); |
| 35 | |
| 36 | // bind debug services |
| 37 | using namespace std::placeholders; |
| 38 | if (!debuggerService->runCoredump) { |
| 39 | debuggerService->runCoredump = std::bind(&DebugManager::runCoredump, this, _1, _2, _3); |
| 40 | } |
| 41 | |
| 42 | if (!debuggerService->registerDebugger) { |
| 43 | debuggerService->registerDebugger = std::bind(&DebugManager::registerDebugger, this, _1, _2); |
| 44 | } |
| 45 | |
| 46 | return true; |
| 47 | } |
| 48 | |
| 49 | QWidget *DebugManager::getStackPane() const |
| 50 | { |
| 51 | return currentDebugger->getStackPane(); |
| 52 | } |
| 53 | |
| 54 | QWidget *DebugManager::getLocalsPane() const |
| 55 | { |
| 56 | return currentDebugger->getLocalsPane(); |
| 57 | } |
| 58 | |
| 59 | QWidget *DebugManager::getBreakpointPane() const |
| 60 | { |
| 61 | return currentDebugger->getBreakpointPane(); |
| 62 | } |
| 63 | |
| 64 | void DebugManager::registerDebugger(const QString &kit, AbstractDebugger *debugger) |
| 65 | { |
| 66 | auto iterator = debuggers.find(kit); |
| 67 | if (iterator == debuggers.end()) { |
| 68 | debuggers.insert(kit, debugger); |
| 69 | } |
| 70 | } |
| 71 | |
| 72 | void DebugManager::run() |
| 73 | { |
| 74 | AbstractDebugger::RunState state = currentDebugger->getRunState(); |
| 75 | switch (state) { |
| 76 | case AbstractDebugger::RunState::kNoRun: |
| 77 | case AbstractDebugger::RunState::kPreparing: |
| 78 | { |
| 79 | LanguageService *service = dpfGetService(LanguageService); |
| 80 | if (service) { |
| 81 | auto generator = service->create<LanguageGenerator>(activeProjectKitName); |
| 82 | if (generator) { |
| 83 | QString debugger = generator->debugger(); |
| 84 | if (debuggers.contains(debugger) && currentDebugger != debuggers[debugger]) { |
| 85 | disconnect(currentDebugger, &AbstractDebugger::runStateChanged, this, &DebugManager::handleRunStateChanged); |
| 86 | currentDebugger = debuggers[debugger]; |
| 87 | connect(currentDebugger, &AbstractDebugger::runStateChanged, this, &DebugManager::handleRunStateChanged); |
| 88 | } |
| 89 | } |
| 90 | } |
| 91 | AsynInvoke(currentDebugger->startDebug()); |
| 92 | break; |
| 93 | } |
| 94 | case AbstractDebugger::RunState::kRunning: |
| 95 | // TODO(mozart):stop debug |
| 96 | break; |
| 97 | case AbstractDebugger::RunState::kStopped: |
| 98 | continueDebug(); |
| 99 | break; |
| 100 | default: |
| 101 | ;// do nothing. |
| 102 | } |
| 103 | } |
| 104 | |
| 105 | void DebugManager::detachDebug() |
| 106 | { |
| 107 | AsynInvoke(currentDebugger->detachDebug()); |
| 108 | } |
| 109 | |
| 110 | void DebugManager::interruptDebug() |
| 111 | { |
| 112 | AsynInvoke(currentDebugger->interruptDebug()); |
| 113 | } |
| 114 | |
| 115 | void DebugManager::continueDebug() |
| 116 | { |
| 117 | AsynInvoke(currentDebugger->continueDebug()); |
| 118 | } |
| 119 | |
| 120 | void DebugManager::abortDebug() |
| 121 | { |
| 122 | AsynInvoke(currentDebugger->abortDebug()); |
| 123 | } |
| 124 | |
| 125 | void DebugManager::restartDebug() |
| 126 | { |
| 127 | AsynInvoke(currentDebugger->restartDebug()); |
| 128 | } |
| 129 | |
| 130 | void DebugManager::stepOver() |
| 131 | { |
| 132 | AsynInvoke(currentDebugger->stepOver()); |
| 133 | } |
| 134 | |
| 135 | void DebugManager::stepIn() |
| 136 | { |
| 137 | AsynInvoke(currentDebugger->stepIn()); |
| 138 | } |
| 139 | |
| 140 | void DebugManager::stepOut() |
| 141 | { |
| 142 | AsynInvoke(currentDebugger->stepOut()); |
| 143 | } |
| 144 | |
| 145 | void DebugManager::handleRunStateChanged(AbstractDebugger::RunState state) |
| 146 | { |
| 147 | menuManager->handleRunStateChanged(state); |
| 148 | |
| 149 | if(state == AbstractDebugger::kStart || state == AbstractDebugger::kRunning) { |
| 150 | emit debugStarted(); |
| 151 | } |
| 152 | } |
| 153 | |
| 154 | void DebugManager::handleEvents(const dpf::Event &event) |
| 155 | { |
| 156 | QString topic = event.topic(); |
| 157 | QString data = event.data().toString(); |
| 158 | if (event.data() == debugger.prepareDebugProgress.name) { |
| 159 | // TODO(logan) |
| 160 | } else if (event.data() == project.activedProject.name) { |
| 161 | auto projectInfo = qvariant_cast<ProjectInfo>(event.property(project.activedProject.pKeys[0])); |
| 162 | activeProjectKitName = projectInfo.kitName(); |
| 163 | } else if (event.data() == project.createdProject.name) { |
| 164 | auto projectInfo = qvariant_cast<ProjectInfo>(event.property(project.createdProject.pKeys[0])); |
| 165 | activeProjectKitName = projectInfo.kitName(); |
| 166 | } else if (event.data() == project.deletedProject.name) { |
| 167 | activeProjectKitName.clear(); |
| 168 | } else if (event.data() == editor.switchedFile.name) { |
| 169 | // TODO(logan) |
| 170 | } else if (event.data() == editor.openedFile.name) { |
| 171 | // TODO(logan) |
| 172 | } else if (event.data() == editor.closedFile.name) { |
| 173 | // TODO(logan) |
| 174 | } |
| 175 | } |
| 176 | |
| 177 | bool DebugManager::runCoredump(const QString &target, const QString &core, const QString &kit) |
| 178 | { |
| 179 | return QtConcurrent::run(currentDebugger, &AbstractDebugger::runCoredump, target, core, kit); |
| 180 | } |
| 181 | |