Dap Interface with Spidermonkey debug

Spidermonkey provide a mechanics to debug all comportaments and real
from a different place with JS code this allow us to reuse the current
scriptinterface but addind the new Debugger object definition only for
debugging without change any code from other place like GUI &
simulation.

Debugger Adapter Interface is a protocol that commons IDE implement to
being able for debugging, the concept is to provide sockets connections
with c++ but the Dap implementation in JS that allow us to extend for
more Request / Events that DAP provide.

Because Dap Interface its implemented with JS we need to handle message
in the main thread so we are calling in the main loop before GUI
messages
This commit is contained in:
trompetin17
2025-05-29 21:55:50 -05:00
parent 91105657d9
commit 678a33c100
8 changed files with 665 additions and 1 deletions
+40
View File
@@ -84,6 +84,7 @@ that of Atlas depending on commandline parameters.
#include "simulation2/Simulation2.h"
#include "simulation2/system/TurnManager.h"
#include "soundmanager/ISoundManager.h"
#include "dapinterface/DapInterface.h"
#if OS_UNIX
#include <iostream>
@@ -362,7 +363,11 @@ static void RendererIncrementalLoad()
while (more && timer_Time() - startTime < maxTime);
}
#if CONFIG2_DAP_INTERFACE
static void Frame(RL::Interface* rlInterface, const int fixedFrameFrequency, DAP::Interface* dapInterface)
#else
static void Frame(RL::Interface* rlInterface, const int fixedFrameFrequency)
#endif // CONFIG2_DAP_INTERFACE
{
g_Profiler2.RecordFrameStart();
PROFILE2("frame");
@@ -426,6 +431,11 @@ static void Frame(RL::Interface* rlInterface, const int fixedFrameFrequency)
if (g_NetClient)
g_NetClient->Poll();
#if CONFIG2_DAP_INTERFACE
if (dapInterface)
dapInterface->TryHandleMessage();
#endif // CONFIG2_DAP_INTERFACE
std::optional<bool> completionCommand{g_GUI->TickObjects()};
if (completionCommand.has_value())
g_Shutdown = completionCommand.value() ? ShutdownType::RestartAsAtlas : ShutdownType::Quit;
@@ -505,6 +515,23 @@ static std::optional<RL::Interface> CreateRLInterface(const CmdLineArgs& args)
return std::make_optional<RL::Interface>(server_address.c_str());
}
#if CONFIG2_DAP_INTERFACE
static std::optional<DAP::Interface> CreateDAPInterface(const CmdLineArgs& args)
{
if (!args.Has("dap-interface"))
return std::nullopt;
const std::string server_address{args.Get("dapinterface.address").empty() ?
g_ConfigDB.Get("dapinterface.address", std::string{}) : args.Get("dapinterface.address")};
const int port{args.Get("dapinterface.port").empty() ?
g_ConfigDB.Get("dapinterface.port", int{}) : args.Get("dapinterface.port").ToInt()};
debug_printf("DAP interface listening on %s:%d\n", server_address.c_str(), port);
return std::make_optional<DAP::Interface>(server_address, port, *g_ScriptContext);
}
#endif // CONFIG2_DAP_INTERFACE
// moved into a helper function to ensure args is destroyed before
// exit(), which may result in a memory leak.
static void RunGameOrAtlas(const PS::span<const char* const> argv)
@@ -677,6 +704,10 @@ static void RunGameOrAtlas(const PS::span<const char* const> argv)
g_Mods.UpdateAvailableMods(modInterface);
}
#if CONFIG2_DAP_INTERFACE
std::optional<DAP::Interface> dapInterface{CreateDAPInterface(args)};
#endif // CONFIG2_DAP_INTERFACE
std::optional<ScriptInterface> guiScriptInterface;
if (isVisual)
@@ -702,7 +733,11 @@ static void RunGameOrAtlas(const PS::span<const char* const> argv)
while (g_Shutdown == ShutdownType::None)
{
if (isVisual)
#if CONFIG2_DAP_INTERFACE
Frame(rlInterface ? &*rlInterface : nullptr, fixedFrameFrequency, dapInterface ? &*dapInterface : nullptr);
#else
Frame(rlInterface ? &*rlInterface : nullptr, fixedFrameFrequency);
#endif
else if(rlInterface)
rlInterface->TryApplyMessage();
else
@@ -717,6 +752,11 @@ static void RunGameOrAtlas(const PS::span<const char* const> argv)
ShutdownNetworkAndUI();
guiScriptInterface.reset();
#if CONFIG2_DAP_INTERFACE
dapInterface.reset();
#endif // CONFIG2_DAP_INTERFACE
ShutdownConfigAndSubsequent();
MainControllerShutdown();