109 lines
3.1 KiB
C++
109 lines
3.1 KiB
C++
#pragma once
|
|
// Step 554: Debug Session Model
|
|
|
|
#include <map>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include "DebugValidationUtil.h"
|
|
|
|
struct DebugTargetContext {
|
|
std::string targetId;
|
|
std::string bufferId;
|
|
std::string executablePath;
|
|
bool attached = false;
|
|
};
|
|
|
|
struct DebugSessionState {
|
|
std::string sessionId;
|
|
bool active = false;
|
|
bool paused = false;
|
|
std::map<std::string, DebugTargetContext> targets;
|
|
std::string currentTargetId;
|
|
};
|
|
|
|
class DebugSessionModel {
|
|
public:
|
|
DebugSessionModel() {
|
|
state_.sessionId = "debug-session-1";
|
|
}
|
|
|
|
const DebugSessionState& state() const { return state_; }
|
|
|
|
bool start(const std::string& targetId,
|
|
const std::string& bufferId,
|
|
const std::string& executablePath) {
|
|
if (state_.active) return false;
|
|
state_.active = true;
|
|
state_.paused = false;
|
|
state_.targets.clear();
|
|
state_.currentTargetId.clear();
|
|
return addTargetInternal(targetId, bufferId, executablePath, false, true);
|
|
}
|
|
|
|
bool attach(const std::string& targetId,
|
|
const std::string& bufferId,
|
|
const std::string& executablePath) {
|
|
if (!state_.active) state_.active = true;
|
|
return addTargetInternal(targetId, bufferId, executablePath, true,
|
|
state_.currentTargetId.empty());
|
|
}
|
|
|
|
bool pause() {
|
|
if (!state_.active || state_.paused) return false;
|
|
state_.paused = true;
|
|
return true;
|
|
}
|
|
|
|
bool resume() {
|
|
if (!state_.active || !state_.paused) return false;
|
|
state_.paused = false;
|
|
return true;
|
|
}
|
|
|
|
bool stop() {
|
|
if (!state_.active) return false;
|
|
state_.active = false;
|
|
state_.paused = false;
|
|
state_.targets.clear();
|
|
state_.currentTargetId.clear();
|
|
return true;
|
|
}
|
|
|
|
bool switchTarget(const std::string& targetId) {
|
|
if (!state_.active) return false;
|
|
if (state_.targets.count(targetId) == 0) return false;
|
|
state_.currentTargetId = targetId;
|
|
return true;
|
|
}
|
|
|
|
bool hasTargetForBuffer(const std::string& bufferId) const {
|
|
for (const auto& kv : state_.targets) {
|
|
if (kv.second.bufferId == bufferId) return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
private:
|
|
DebugSessionState state_;
|
|
|
|
bool addTargetInternal(const std::string& targetId,
|
|
const std::string& bufferId,
|
|
const std::string& executablePath,
|
|
bool attached,
|
|
bool makeCurrent) {
|
|
if (!hasRequiredDebugIds(targetId, bufferId) || executablePath.empty()) return false;
|
|
if (state_.targets.count(targetId) != 0) return false;
|
|
|
|
DebugTargetContext context;
|
|
context.targetId = targetId;
|
|
context.bufferId = bufferId;
|
|
context.executablePath = executablePath;
|
|
context.attached = attached;
|
|
state_.targets[targetId] = context;
|
|
|
|
if (makeCurrent) state_.currentTargetId = targetId;
|
|
return true;
|
|
}
|
|
};
|