Adds support for step over, step into and step out.
This commit is contained in:
parent
a2d8293c04
commit
d5cc939a6b
|
@ -37,8 +37,37 @@ void AngelscriptDebugger::on_line_callback(asIScriptContext* ctx, AngelscriptDeb
|
|||
const char* scriptSection = nullptr;
|
||||
int column = 0;
|
||||
int line = ctx->GetLineNumber(0, &column, &scriptSection);
|
||||
if (line == 0)
|
||||
if (line == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (d->_next && d->_nextContext == ctx && d->_nextDepth >= ctx->GetCallstackSize()) {
|
||||
d->_next = false;
|
||||
ctx->Suspend();
|
||||
d->_pausedContexts.push_back(ctx);
|
||||
auto* o = new DebugAdapterProtocol::StoppedEvent(new DebugAdapterProtocol::StoppedEventBody("step", "", ""));
|
||||
|
||||
d->Send(o);
|
||||
return;
|
||||
}
|
||||
if (d->_stepInto && d->_nextContext == ctx) {
|
||||
d->_stepInto = false;
|
||||
ctx->Suspend();
|
||||
d->_pausedContexts.push_back(ctx);
|
||||
auto* o = new DebugAdapterProtocol::StoppedEvent(new DebugAdapterProtocol::StoppedEventBody("step", "", ""));
|
||||
|
||||
d->Send(o);
|
||||
return;
|
||||
}
|
||||
if (d->_stepOut && d->_nextContext == ctx && d->_nextDepth > ctx->GetCallstackSize()) {
|
||||
d->_stepOut = false;
|
||||
ctx->Suspend();
|
||||
d->_pausedContexts.push_back(ctx);
|
||||
auto* o = new DebugAdapterProtocol::StoppedEvent(new DebugAdapterProtocol::StoppedEventBody("step", "", ""));
|
||||
|
||||
d->Send(o);
|
||||
return;
|
||||
}
|
||||
|
||||
auto resolvedScriptPath = d->GetResolvedScriptPath(scriptSection);
|
||||
auto sectionBreakpoints = d->_breakpoints.find(resolvedScriptPath);
|
||||
|
@ -257,7 +286,7 @@ void AngelscriptDebugger::OnRequest(asio::ip::tcp::socket* client, DebugAdapterP
|
|||
const char* scriptSection = nullptr;
|
||||
int column = 0;
|
||||
int line;
|
||||
if (i == 0 && ctx->GetExceptionString() != nullptr) {
|
||||
if (i == 0 && ctx->GetExceptionFunction() != nullptr) {
|
||||
line = ctx->GetExceptionLineNumber(&column, &scriptSection);
|
||||
} else {
|
||||
line = ctx->GetLineNumber(i, &column, &scriptSection);
|
||||
|
@ -330,7 +359,48 @@ void AngelscriptDebugger::OnRequest(asio::ip::tcp::socket* client, DebugAdapterP
|
|||
auto body = new DebugAdapterProtocol::VariablesResponseBody(variables);
|
||||
response->body = body;
|
||||
Send(client, response);
|
||||
} else if (msg->GetCommand() == "next") {
|
||||
Next(_pausedContexts.at(0));
|
||||
} else if (msg->GetCommand() == "stepIn") {
|
||||
StepInto(_pausedContexts.at(0));
|
||||
} else if (msg->GetCommand() == "stepOut") {
|
||||
StepOut(_pausedContexts.at(0));
|
||||
} else {
|
||||
std::cout << "Unhandled message: " << msg->GetCommand() << std::endl;
|
||||
Send(client, new DebugAdapterProtocol::DefinedResponse<DebugAdapterProtocol::ResponseBody, empty>(msg->seq));
|
||||
}
|
||||
}
|
||||
void AngelscriptDebugger::Next(asIScriptContext* ctx) {
|
||||
_nextContext = ctx;
|
||||
_next = true;
|
||||
_nextDepth = ctx->GetCallstackSize();
|
||||
_storedVariableReferences.clear();
|
||||
while (!_pausedContexts.empty()) {
|
||||
auto* c = _pausedContexts[_pausedContexts.size() - 1];
|
||||
_pausedContexts.pop_back();
|
||||
std::thread([](asIScriptContext* c) { c->Execute(); }, c).detach();
|
||||
}
|
||||
}
|
||||
|
||||
void AngelscriptDebugger::StepInto(asIScriptContext* ctx) {
|
||||
_nextContext = ctx;
|
||||
_stepInto = true;
|
||||
_nextDepth = ctx->GetCallstackSize();
|
||||
_storedVariableReferences.clear();
|
||||
while (!_pausedContexts.empty()) {
|
||||
auto* c = _pausedContexts[_pausedContexts.size() - 1];
|
||||
_pausedContexts.pop_back();
|
||||
std::thread([](asIScriptContext* c) { c->Execute(); }, c).detach();
|
||||
}
|
||||
}
|
||||
void AngelscriptDebugger::StepOut(asIScriptContext* ctx) {
|
||||
_nextContext = ctx;
|
||||
_stepOut = true;
|
||||
_nextDepth = ctx->GetCallstackSize();
|
||||
_storedVariableReferences.clear();
|
||||
while (!_pausedContexts.empty()) {
|
||||
auto* c = _pausedContexts[_pausedContexts.size() - 1];
|
||||
_pausedContexts.pop_back();
|
||||
std::thread([](asIScriptContext* c) { c->Execute(); }, c).detach();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -56,6 +56,10 @@ private:
|
|||
void OnRequest(asio::ip::tcp::socket* client, DebugAdapterProtocol::Request* msg);
|
||||
std::string GetResolvedScriptPath(const char* scriptSection);
|
||||
|
||||
void Next(asIScriptContext* ctx);
|
||||
void StepInto(asIScriptContext* ctx);
|
||||
void StepOut(asIScriptContext* ctx);
|
||||
|
||||
asio::io_context _ioContext;
|
||||
asio::ip::tcp::acceptor* _server;
|
||||
std::unordered_set<asio::ip::tcp::socket*> _connections;
|
||||
|
@ -64,6 +68,12 @@ private:
|
|||
std::vector<asIScriptContext*> _pausedContexts;
|
||||
std::optional<std::string> _scriptPath;
|
||||
|
||||
asIScriptContext* _nextContext;
|
||||
bool _next;
|
||||
size_t _nextDepth;
|
||||
bool _stepInto;
|
||||
bool _stepOut;
|
||||
|
||||
struct StackScope {
|
||||
size_t StackLevel;
|
||||
uint8_t Type;
|
||||
|
|
|
@ -182,7 +182,7 @@ namespace DebugAdapterProtocol {
|
|||
EventDefinition(Stopped, "stopped", {
|
||||
std::string reason;
|
||||
std::optional<std::string> description;
|
||||
std::optional<size_t> number;
|
||||
std::optional<size_t> threadId = 0;
|
||||
std::optional<bool> preserveFocusHint = false;
|
||||
std::optional<std::string> text;
|
||||
std::optional<bool> allThreadsStopped = true;
|
||||
|
@ -197,7 +197,7 @@ namespace DebugAdapterProtocol {
|
|||
auto o = EventBody::ToJson();
|
||||
o["reason"] = reason;
|
||||
JsonSerializeOptional(o, description);
|
||||
JsonSerializeOptional(o, number);
|
||||
JsonSerializeOptional(o, threadId);
|
||||
JsonSerializeOptional(o, preserveFocusHint);
|
||||
JsonSerializeOptional(o, text);
|
||||
JsonSerializeOptional(o, allThreadsStopped);
|
||||
|
|
Loading…
Reference in New Issue