AGS: Engine: Use a single function to send messages to editor debugger

From upstream 003243d6c925d176d6e206bed7c1c930952ba2da
This commit is contained in:
Walter Agazzi 2023-03-01 14:34:07 +01:00 committed by Thierry Crozat
parent 7e3ffd0161
commit 97d08215b5
5 changed files with 45 additions and 29 deletions

View File

@ -73,6 +73,23 @@ IAGSEditorDebugger *GetEditorDebugger(const char * /*instanceToken*/) {
#endif
void send_message_to_debugger(const std::vector<std::pair<String, String> > &tag_values, const String &command) {
String messageToSend = String::FromFormat(R"(<?xml version=" 1.0 " encoding=" Windows - 1252 "?><Debugger Command=" % s ">)", command.GetCStr());
#if AGS_PLATFORM_OS_WINDOWS
messageToSend.Append(String::FromFormat(" <EngineWindow>%d</EngineWindow> ", (int)sys_win_get_window()));
#endif
for (const auto &tag_value : tag_values) {
String tag_line = String::FromFormat(" <%s><![CDATA[%s]]></%s> ",
tag_value.first.GetCStr(), tag_value.second.GetCStr(), tag_value.first.GetCStr());
messageToSend.Append(tag_line);
}
messageToSend.Append("</Debugger>\n");
_G(editor_debugger)->SendMessageToEditor(messageToSend.GetCStr());
}
static const char *OutputMsgBufID = "buffer";
static const char *OutputFileID = "file";
static const char *OutputSystemID = "stdout";
@ -210,6 +227,7 @@ void init_debug(const ConfigTree &cfg, bool stderr_only) {
void apply_debug_config(const ConfigTree &cfg) {
apply_log_config(cfg, OutputSystemID, /* defaults */ true, { DbgGroupOption(kDbgGroup_Main, kDbgMsg_Info) });
bool legacy_log_enabled = CfgReadBoolInt(cfg, "misc", "log", false);
apply_log_config(cfg, OutputFileID,
/* defaults */
legacy_log_enabled, {
@ -314,30 +332,25 @@ struct Breakpoint {
int lineNumber = 0;
};
bool send_message_to_editor(const char *msg, const char *errorMsg) {
bool send_state_to_debugger(const String& msg, const String& errorMsg) {
// Get either saved callstack from a script error, or current execution point
String callStack = (errorMsg && cc_has_error()) ?
String callStack = (!errorMsg.IsEmpty() && cc_has_error()) ?
cc_get_error().CallStack : cc_get_callstack();
if (callStack.IsEmpty())
return false;
String message;
message.AppendFmt("<?xml version=\"1.0\" encoding=\"Windows-1252\"?><Debugger Command=\"%s\">", msg);
#if AGS_PLATFORM_OS_WINDOWS
message.AppendFmt(" <EngineWindow>%d</EngineWindow> ", (int)sys_win_get_window());
#endif
message.AppendFmt(" <ScriptState><![CDATA[%s]]></ScriptState> ", callStack.GetCStr());
if (errorMsg != nullptr) {
message.AppendFmt(" <ErrorMessage><![CDATA[%s]]></ErrorMessage> ", errorMsg);
}
message.Append("</Debugger>");
std::vector<std::pair<String, String>> script_info = {{"ScriptState", callStack}};
_G(editor_debugger)->SendMessageToEditor(message.GetCStr());
if (!errorMsg.IsEmpty()) {
script_info.emplace_back("ErrorMessage", errorMsg);
}
send_message_to_debugger(script_info, msg);
return true;
}
bool send_message_to_editor(const char *msg) {
return send_message_to_editor(msg, nullptr);
bool send_state_to_debugger(const char *msg) {
return send_state_to_debugger(String(msg), String());
}
bool init_editor_debugging() {
@ -356,11 +369,11 @@ bool init_editor_debugging() {
// Wait for the editor to send the initial breakpoints
// and then its READY message
while (check_for_messages_from_editor() != 2) {
while (check_for_messages_from_debugger() != 2) {
_G(platform)->Delay(10);
}
send_message_to_editor("START");
send_state_to_debugger("START");
Debug::Printf(kDbgMsg_Info, "External debugger initialized");
return true;
}
@ -369,7 +382,7 @@ bool init_editor_debugging() {
return false;
}
int check_for_messages_from_editor() {
int check_for_messages_from_debugger() {
if (_G(editor_debugger)->IsMessageAvailable()) {
char *msg = _G(editor_debugger)->GetNextMessage();
if (msg == nullptr) {
@ -442,17 +455,17 @@ int check_for_messages_from_editor() {
bool send_exception_to_editor(const char *qmsg) {
bool send_exception_to_debugger(const char *qmsg) {
#if AGS_PLATFORM_OS_WINDOWS
_G(want_exit) = false;
// allow the editor to break with the error message
if (editor_window_handle != NULL)
SetForegroundWindow(editor_window_handle);
if (!send_message_to_editor("ERROR", qmsg))
if (!send_state_to_debugger("ERROR", qmsg))
return false;
while ((check_for_messages_from_editor() == 0) && (!_G(want_exit))) {
while ((check_for_messages_from_debugger() == 0) && (!_G(want_exit))) {
_G(platform)->Delay(10);
}
#endif
@ -466,7 +479,7 @@ void break_into_debugger() {
if (editor_window_handle != NULL)
SetForegroundWindow(editor_window_handle);
send_message_to_editor("BREAK");
send_state_to_debugger("BREAK");
_G(game_paused_in_debugger) = 1;
while (_G(game_paused_in_debugger)) {

View File

@ -29,9 +29,12 @@ namespace AGS3 {
struct IAGSEditorDebugger;
struct ScriptPosition;
int check_for_messages_from_editor();
bool send_message_to_editor(const char *msg);
bool send_exception_to_editor(const char *qmsg);
int check_for_messages_from_debugger();
bool send_state_to_debugger(const char *msg);
bool send_exception_to_debugger(const char *qmsg);
// Returns current script's location and callstack
AGS::Shared::String get_cur_script(int numberOfLinesOfCallStack);
bool get_script_position(ScriptPosition &script_pos);
void check_debug_keys();
#define DBG_NOIFACE 1

View File

@ -1048,7 +1048,7 @@ void update_polled_stuff() {
quit("||exit!");
} else if (_G(editor_debugging_initialized))
check_for_messages_from_editor();
check_for_messages_from_debugger();
}
} // namespace AGS3

View File

@ -65,7 +65,7 @@ void start_game_init_editor_debugging() {
auto waitUntil = AGS_Clock::now() + std::chrono::milliseconds(500);
while (waitUntil > AGS_Clock::now()) {
// pick up any breakpoints in game_start
check_for_messages_from_editor();
check_for_messages_from_debugger();
}
ccSetDebugHook(scriptDebugHook);

View File

@ -61,8 +61,8 @@ using namespace AGS::Engine;
void quit_tell_editor_debugger(const String &qmsg, QuitReason qreason) {
if (_G(editor_debugging_initialized)) {
if (qreason & kQuitKind_GameException)
_G(handledErrorInEditor) = send_exception_to_editor(qmsg.GetCStr());
send_message_to_editor("EXIT");
_G(handledErrorInEditor) = send_exception_to_debugger(qmsg.GetCStr());
send_state_to_debugger("EXIT");
_G(editor_debugger)->Shutdown();
}
}