mirror of
https://github.com/ZDoom/gzdoom.git
synced 2025-04-23 03:10:58 +00:00
dap: add Globals display to debugger
This commit is contained in:
parent
3e163d6b1f
commit
9dbef641cd
5 changed files with 177 additions and 1 deletions
|
@ -1190,6 +1190,7 @@ set (PCH_SOURCES
|
|||
common/scripting/dap/IdProvider.cpp
|
||||
common/scripting/dap/Nodes/ArrayStateNode.cpp
|
||||
common/scripting/dap/Nodes/LocalScopeStateNode.cpp
|
||||
common/scripting/dap/Nodes/GlobalScopeStateNode.cpp
|
||||
common/scripting/dap/Nodes/ObjectStateNode.cpp
|
||||
common/scripting/dap/Nodes/StackFrameStateNode.cpp
|
||||
common/scripting/dap/Nodes/StackStateNode.cpp
|
||||
|
|
141
src/common/scripting/dap/Nodes/GlobalScopeStateNode.cpp
Normal file
141
src/common/scripting/dap/Nodes/GlobalScopeStateNode.cpp
Normal file
|
@ -0,0 +1,141 @@
|
|||
#include "GlobalScopeStateNode.h"
|
||||
#include <common/scripting/dap/Utilities.h>
|
||||
#include <common/scripting/dap/RuntimeState.h>
|
||||
|
||||
namespace DebugServer
|
||||
{
|
||||
// TODO: Do this dynamically?
|
||||
static const char *const GlobalNames[] = {
|
||||
"NotifyFontScale",
|
||||
"ConsoleState",
|
||||
"menuactive",
|
||||
"BackbuttonTime",
|
||||
"BackbuttonAlpha",
|
||||
"GameTicRate",
|
||||
"menuDelegate",
|
||||
"WP_NOCHANGE",
|
||||
"SmallFont",
|
||||
"SmallFont2",
|
||||
"BigFont",
|
||||
"ConFont",
|
||||
"NewConsoleFont",
|
||||
"NewSmallFont",
|
||||
"AlternativeSmallFont",
|
||||
"AlternativeBigFont",
|
||||
"OriginalSmallFont",
|
||||
"OriginalBigFont",
|
||||
"IntermissionFont",
|
||||
"CleanXfac",
|
||||
"CleanYfac",
|
||||
"CleanWidth",
|
||||
"CleanHeight",
|
||||
"CleanXfac_1",
|
||||
"CleanYfac_1",
|
||||
"CleanWidth_1",
|
||||
"CleanHeight_1",
|
||||
"AllServices",
|
||||
"Bindings",
|
||||
"AutomapBindings",
|
||||
"generic_ui",
|
||||
"deh",
|
||||
"gameinfo",
|
||||
"Teams",
|
||||
"LocalViewPitch",
|
||||
"StatusBar",
|
||||
"players",
|
||||
"playeringame",
|
||||
"PlayerClasses",
|
||||
"consoleplayer",
|
||||
"validcount",
|
||||
"multiplayer",
|
||||
"gameaction",
|
||||
"gamestate",
|
||||
"skyflatnum",
|
||||
"globalfreeze",
|
||||
"gametic",
|
||||
"demoplayback",
|
||||
"automapactive",
|
||||
"viewactive",
|
||||
"Net_Arbitrator",
|
||||
"netgame",
|
||||
"paused",
|
||||
"Terrains",
|
||||
"OptionMenuSettings",
|
||||
"musplaying",
|
||||
"AllClasses",
|
||||
"Level",
|
||||
// "level", technically its own global, but only the VM one is accessible by the VM
|
||||
"AllActorClasses",
|
||||
|
||||
nullptr};
|
||||
|
||||
GlobalScopeStateNode::GlobalScopeStateNode() { }
|
||||
|
||||
bool GlobalScopeStateNode::SerializeToProtocol(dap::Scope &scope)
|
||||
{
|
||||
scope.name = "Global";
|
||||
scope.expensive = false;
|
||||
scope.presentationHint = "globals";
|
||||
scope.variablesReference = GetId();
|
||||
|
||||
std::vector<std::string> childNames;
|
||||
GetChildNames(childNames);
|
||||
|
||||
scope.namedVariables = childNames.size();
|
||||
scope.indexedVariables = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GlobalScopeStateNode::GetChildNames(std::vector<std::string> &names)
|
||||
{
|
||||
for (int i = 0; GlobalNames[i] != nullptr; i++)
|
||||
{
|
||||
names.push_back(GlobalNames[i]);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GlobalScopeStateNode::GetChildNode(std::string name, std::shared_ptr<StateNodeBase> &node)
|
||||
{
|
||||
if (m_children.empty())
|
||||
{
|
||||
std::vector<std::string> childNames;
|
||||
GetChildNames(childNames);
|
||||
caseless_path_set childSet {childNames.begin(), childNames.end()};
|
||||
for (auto ns : Namespaces.AllNamespaces)
|
||||
{
|
||||
auto symbolIter = ns->Symbols.GetIterator();
|
||||
PSymbolTable::MapType::Pair *pair;
|
||||
while (symbolIter.NextPair(pair))
|
||||
{
|
||||
if (childSet.find(pair->Key.GetChars()) != childSet.end())
|
||||
{
|
||||
std::string symname = pair->Key.GetChars();
|
||||
PSymbol *val = pair->Value;
|
||||
if (val->SymbolName == NAME_None)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
PField *field = dyn_cast<PField>(val);
|
||||
if (field)
|
||||
{
|
||||
field->Type;
|
||||
// the offset is the address of the field
|
||||
void *addr = (void *)(field->Offset);
|
||||
VMValue val = GetVMValue(addr, field->Type);
|
||||
m_children[symname] = RuntimeState::CreateNodeForVariable(symname, val, field->Type);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (m_children.find(name) != m_children.end())
|
||||
{
|
||||
node = m_children[name];
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
20
src/common/scripting/dap/Nodes/GlobalScopeStateNode.h
Normal file
20
src/common/scripting/dap/Nodes/GlobalScopeStateNode.h
Normal file
|
@ -0,0 +1,20 @@
|
|||
#pragma once
|
||||
|
||||
#include <common/scripting/dap/GameInterfaces.h>
|
||||
#include <dap/protocol.h>
|
||||
|
||||
#include "StateNodeBase.h"
|
||||
|
||||
namespace DebugServer
|
||||
{
|
||||
class GlobalScopeStateNode : public StateNodeBase, public IProtocolScopeSerializable, public IStructuredState
|
||||
{
|
||||
caseless_path_map<std::shared_ptr<StateNodeBase>> m_children;
|
||||
public:
|
||||
GlobalScopeStateNode();
|
||||
|
||||
bool SerializeToProtocol(dap::Scope &scope) override;
|
||||
bool GetChildNames(std::vector<std::string> &names) override;
|
||||
bool GetChildNode(std::string name, std::shared_ptr<StateNodeBase> &node) override;
|
||||
};
|
||||
}
|
|
@ -1,10 +1,12 @@
|
|||
#include "StackFrameStateNode.h"
|
||||
|
||||
|
||||
#include <common/scripting/dap/Utilities.h>
|
||||
#include <string>
|
||||
|
||||
#include "LocalScopeStateNode.h"
|
||||
#include "RegistersScopeStateNode.h"
|
||||
#include "GlobalScopeStateNode.h"
|
||||
|
||||
namespace DebugServer
|
||||
{
|
||||
|
@ -20,6 +22,7 @@ StackFrameStateNode::StackFrameStateNode(VMFunction *nativeFunction, VMFrame *pa
|
|||
m_fakeStackFrame.MaxParam = 0;
|
||||
m_fakeStackFrame.NumParam = 0;
|
||||
m_stackFrame = &m_fakeStackFrame;
|
||||
m_globalsScope = std::make_shared<GlobalScopeStateNode>();
|
||||
}
|
||||
|
||||
StackFrameStateNode::StackFrameStateNode(VMFrame *stackFrame) : m_stackFrame(stackFrame), m_fakeStackFrame()
|
||||
|
@ -33,6 +36,7 @@ StackFrameStateNode::StackFrameStateNode(VMFrame *stackFrame) : m_stackFrame(sta
|
|||
}
|
||||
m_registersScope = std::make_shared<RegistersScopeStateNode>(m_stackFrame);
|
||||
}
|
||||
m_globalsScope = std::make_shared<GlobalScopeStateNode>();
|
||||
}
|
||||
|
||||
bool StackFrameStateNode::SerializeToProtocol(dap::StackFrame &stackFrame, PexCache *pexCache) const
|
||||
|
@ -86,10 +90,14 @@ bool StackFrameStateNode::SerializeToProtocol(dap::StackFrame &stackFrame, PexCa
|
|||
|
||||
bool StackFrameStateNode::GetChildNames(std::vector<std::string> &names)
|
||||
{
|
||||
auto scriptFunction = dynamic_cast<VMScriptFunction *>(m_stackFrame->Func);
|
||||
auto scriptFunction = GetVMScriptFunction(m_stackFrame->Func);
|
||||
if (scriptFunction)
|
||||
{
|
||||
names.push_back("Local");
|
||||
}
|
||||
names.push_back("Globals");
|
||||
if (scriptFunction)
|
||||
{
|
||||
names.push_back("Registers");
|
||||
}
|
||||
return true;
|
||||
|
@ -101,6 +109,11 @@ bool StackFrameStateNode::GetChildNode(std::string name, std::shared_ptr<StateNo
|
|||
{
|
||||
return false;
|
||||
}
|
||||
if (CaseInsensitiveEquals(name, "Globals"))
|
||||
{
|
||||
node = m_globalsScope;
|
||||
return true;
|
||||
}
|
||||
if (CaseInsensitiveEquals(name, "Registers"))
|
||||
{
|
||||
node = m_registersScope;
|
||||
|
|
|
@ -15,6 +15,7 @@ class StackFrameStateNode : public StateNodeBase, public IStructuredState
|
|||
VMFrame m_fakeStackFrame;
|
||||
std::shared_ptr<StateNodeBase> m_localScope = nullptr;
|
||||
std::shared_ptr<StateNodeBase> m_registersScope = nullptr;
|
||||
std::shared_ptr<StateNodeBase> m_globalsScope = nullptr;
|
||||
public:
|
||||
StackFrameStateNode(VMFunction *nativeFunction, VMFrame *parentStackFrame);
|
||||
explicit StackFrameStateNode(VMFrame *stackFrame);
|
||||
|
|
Loading…
Reference in a new issue