Permalink
Browse files

Debugger: Refactor to allow simpler broadcasting.

It's okay to mix a bit for simple ones, I think.
  • Loading branch information...
unknownbrackets committed Sep 1, 2018
1 parent c10b203 commit 4ce2b64ef753a389fdb683345e7f2792c35479c2
@@ -56,21 +56,15 @@
#include "Core/Debugger/WebSocket/HLESubscriber.h"
#include "Core/Debugger/WebSocket/SteppingSubscriber.h"
typedef void *(*SubscriberInit)(DebuggerEventHandlerMap &map);
typedef void (*Subscribershutdown)(void *p);
struct SubscriberInfo {
SubscriberInit init;
Subscribershutdown shutdown;
};
static const std::vector<SubscriberInfo> subscribers({
{ &WebSocketBreakpointInit, nullptr },
{ &WebSocketCPUCoreInit, nullptr },
{ &WebSocketDisasmInit, &WebSocketDisasmShutdown },
{ &WebSocketGameInit, nullptr },
{ &WebSocketGPUBufferInit, nullptr },
{ &WebSocketHLEInit, nullptr },
{ &WebSocketSteppingInit, &WebSocketSteppingShutdown },
typedef DebuggerSubscriber *(*SubscriberInit)(DebuggerEventHandlerMap &map);
static const std::vector<SubscriberInit> subscribers({
&WebSocketBreakpointInit,
&WebSocketCPUCoreInit,
&WebSocketDisasmInit,
&WebSocketGameInit,
&WebSocketGPUBufferInit,
&WebSocketHLEInit,
&WebSocketSteppingInit,
});
// To handle webserver restart, keep track of how many running.
@@ -132,10 +126,10 @@ void HandleDebuggerRequest(const http::Request &request) {
SteppingBroadcaster stepping;
std::unordered_map<std::string, DebuggerEventHandler> eventHandlers;
std::vector<void *> subscriberData;
for (auto info : subscribers) {
std::vector<DebuggerSubscriber *> subscriberData;
for (auto init : subscribers) {
std::lock_guard<std::mutex> guard(lifecycleLock);
subscriberData.push_back(info.init(eventHandlers));
subscriberData.push_back(init(eventHandlers));
}
// There's a tradeoff between responsiveness to incoming events, and polling for changes.
@@ -178,6 +172,12 @@ void HandleDebuggerRequest(const http::Request &request) {
game.Broadcast(ws);
stepping.Broadcast(ws);
for (size_t i = 0; i < subscribers.size(); ++i) {
if (subscriberData[i]) {
subscriberData[i]->Broadcast(ws);
}
}
if (stopRequested) {
ws->Close(net::WebSocketClose::GOING_AWAY);
}
@@ -188,11 +188,7 @@ void HandleDebuggerRequest(const http::Request &request) {
std::lock_guard<std::mutex> guard(lifecycleLock);
for (size_t i = 0; i < subscribers.size(); ++i) {
if (subscribers[i].shutdown) {
subscribers[i].shutdown(subscriberData[i]);
} else {
assert(!subscriberData[i]);
}
delete subscriberData[i];
}
delete ws;
@@ -23,7 +23,7 @@
#include "Core/Debugger/WebSocket/WebSocketUtils.h"
#include "Core/MIPS/MIPSDebugInterface.h"
void *WebSocketBreakpointInit(DebuggerEventHandlerMap &map) {
DebuggerSubscriber *WebSocketBreakpointInit(DebuggerEventHandlerMap &map) {
// No need to bind or alloc state, these are all global.
map["cpu.breakpoint.add"] = &WebSocketCPUBreakpointAdd;
map["cpu.breakpoint.update"] = &WebSocketCPUBreakpointUpdate;
@@ -19,7 +19,7 @@
#include "Core/Debugger/WebSocket/WebSocketUtils.h"
void *WebSocketBreakpointInit(DebuggerEventHandlerMap &map);
DebuggerSubscriber *WebSocketBreakpointInit(DebuggerEventHandlerMap &map);
void WebSocketCPUBreakpointAdd(DebuggerRequest &req);
void WebSocketCPUBreakpointUpdate(DebuggerRequest &req);
@@ -25,7 +25,7 @@
#include "Core/MIPS/MIPS.h"
#include "Core/MIPS/MIPSDebugInterface.h"
void *WebSocketCPUCoreInit(DebuggerEventHandlerMap &map) {
DebuggerSubscriber *WebSocketCPUCoreInit(DebuggerEventHandlerMap &map) {
// No need to bind or alloc state, these are all global.
map["cpu.stepping"] = &WebSocketCPUStepping;
map["cpu.resume"] = &WebSocketCPUResume;
@@ -19,7 +19,7 @@
#include "Core/Debugger/WebSocket/WebSocketUtils.h"
void *WebSocketCPUCoreInit(DebuggerEventHandlerMap &map);
DebuggerSubscriber *WebSocketCPUCoreInit(DebuggerEventHandlerMap &map);
void WebSocketCPUStepping(DebuggerRequest &req);
void WebSocketCPUResume(DebuggerRequest &req);
@@ -28,11 +28,12 @@
#include "Core/MIPS/MIPSAsm.h"
#include "Core/MIPS/MIPSDebugInterface.h"
struct WebSocketDisasmState {
class WebSocketDisasmState : public DebuggerSubscriber {
public:
WebSocketDisasmState() {
disasm_.setCpu(currentDebugMIPS);
}
~WebSocketDisasmState() {
~WebSocketDisasmState() override {
disasm_.clear();
}
@@ -49,7 +50,7 @@ struct WebSocketDisasmState {
DisassemblyManager disasm_;
};
void *WebSocketDisasmInit(DebuggerEventHandlerMap &map) {
DebuggerSubscriber *WebSocketDisasmInit(DebuggerEventHandlerMap &map) {
auto p = new WebSocketDisasmState();
map["memory.base"] = std::bind(&WebSocketDisasmState::Base, p, std::placeholders::_1);
map["memory.disasm"] = std::bind(&WebSocketDisasmState::Disasm, p, std::placeholders::_1);
@@ -59,10 +60,6 @@ void *WebSocketDisasmInit(DebuggerEventHandlerMap &map) {
return p;
}
void WebSocketDisasmShutdown(void *p) {
delete static_cast<WebSocketDisasmState *>(p);
}
static DebugInterface *CPUFromRequest(DebuggerRequest &req) {
if (!req.HasParam("thread"))
return currentDebugMIPS;
@@ -19,5 +19,4 @@
#include "Core/Debugger/WebSocket/WebSocketUtils.h"
void *WebSocketDisasmInit(DebuggerEventHandlerMap &map);
void WebSocketDisasmShutdown(void *p);
DebuggerSubscriber *WebSocketDisasmInit(DebuggerEventHandlerMap &map);
@@ -28,7 +28,7 @@
#include "Core/Screenshot.h"
#include "GPU/Debugger/Stepping.h"
void *WebSocketGPUBufferInit(DebuggerEventHandlerMap &map) {
DebuggerSubscriber *WebSocketGPUBufferInit(DebuggerEventHandlerMap &map) {
// No need to bind or alloc state, these are all global.
map["gpu.buffer.screenshot"] = &WebSocketGPUBufferScreenshot;
map["gpu.buffer.renderColor"] = &WebSocketGPUBufferRenderColor;
@@ -19,7 +19,7 @@
#include "Core/Debugger/WebSocket/WebSocketUtils.h"
void *WebSocketGPUBufferInit(DebuggerEventHandlerMap &map);
DebuggerSubscriber *WebSocketGPUBufferInit(DebuggerEventHandlerMap &map);
void WebSocketGPUBufferScreenshot(DebuggerRequest &req);
void WebSocketGPUBufferRenderColor(DebuggerRequest &req);
@@ -20,7 +20,7 @@
#include "Core/ELF/ParamSFO.h"
#include "Core/System.h"
void *WebSocketGameInit(DebuggerEventHandlerMap &map) {
DebuggerSubscriber *WebSocketGameInit(DebuggerEventHandlerMap &map) {
map["game.status"] = &WebSocketGameStatus;
map["version"] = &WebSocketVersion;
@@ -19,7 +19,7 @@
#include "Core/Debugger/WebSocket/WebSocketUtils.h"
void *WebSocketGameInit(DebuggerEventHandlerMap &map);
DebuggerSubscriber *WebSocketGameInit(DebuggerEventHandlerMap &map);
void WebSocketGameStatus(DebuggerRequest &req);
void WebSocketVersion(DebuggerRequest &req);
@@ -27,7 +27,7 @@
#include "Core/MIPS/MIPSStackWalk.h"
#include "Core/HLE/sceKernelThread.h"
void *WebSocketHLEInit(DebuggerEventHandlerMap &map) {
DebuggerSubscriber *WebSocketHLEInit(DebuggerEventHandlerMap &map) {
map["hle.thread.list"] = &WebSocketHLEThreadList;
map["hle.thread.wake"] = &WebSocketHLEThreadWake;
map["hle.thread.stop"] = &WebSocketHLEThreadStop;
@@ -19,7 +19,7 @@
#include "Core/Debugger/WebSocket/WebSocketUtils.h"
void *WebSocketHLEInit(DebuggerEventHandlerMap &map);
DebuggerSubscriber *WebSocketHLEInit(DebuggerEventHandlerMap &map);
void WebSocketHLEThreadList(DebuggerRequest &req);
void WebSocketHLEThreadWake(DebuggerRequest &req);
@@ -28,11 +28,11 @@
using namespace MIPSAnalyst;
struct WebSocketSteppingState {
struct WebSocketSteppingState : public DebuggerSubscriber {
WebSocketSteppingState() {
disasm_.setCpu(currentDebugMIPS);
}
~WebSocketSteppingState() {
~WebSocketSteppingState() override {
disasm_.clear();
}
@@ -51,7 +51,7 @@ struct WebSocketSteppingState {
DisassemblyManager disasm_;
};
void *WebSocketSteppingInit(DebuggerEventHandlerMap &map) {
DebuggerSubscriber *WebSocketSteppingInit(DebuggerEventHandlerMap &map) {
auto p = new WebSocketSteppingState();
map["cpu.stepInto"] = std::bind(&WebSocketSteppingState::Into, p, std::placeholders::_1);
map["cpu.stepOver"] = std::bind(&WebSocketSteppingState::Over, p, std::placeholders::_1);
@@ -62,10 +62,6 @@ void *WebSocketSteppingInit(DebuggerEventHandlerMap &map) {
return p;
}
void WebSocketSteppingShutdown(void *p) {
delete static_cast<WebSocketSteppingState *>(p);
}
static DebugInterface *CPUFromRequest(DebuggerRequest &req, uint32_t *threadID = nullptr) {
if (!req.HasParam("thread")) {
if (threadID)
@@ -19,5 +19,4 @@
#include "Core/Debugger/WebSocket/WebSocketUtils.h"
void *WebSocketSteppingInit(DebuggerEventHandlerMap &map);
void WebSocketSteppingShutdown(void *p);
DebuggerSubscriber *WebSocketSteppingInit(DebuggerEventHandlerMap &map);
@@ -98,5 +98,13 @@ struct DebuggerRequest {
bool responsePartial_ = false;
};
class DebuggerSubscriber {
public:
virtual ~DebuggerSubscriber() {}
// Subscribers can also broadcast if they have simple cases to.
virtual void Broadcast(net::WebSocketServer *ws) {}
};
typedef std::function<void(DebuggerRequest &req)> DebuggerEventHandler;
typedef std::unordered_map<std::string, DebuggerEventHandler> DebuggerEventHandlerMap;

0 comments on commit 4ce2b64

Please sign in to comment.