1
0
mirror of https://github.com/rwengine/openrw.git synced 2024-11-25 11:52:40 +01:00

Overhaul breakpoint handling

This commit is contained in:
Daniel Evans 2015-07-09 13:58:14 +01:00
parent 5461f1a5bb
commit 243bfb18a8
7 changed files with 96 additions and 26 deletions

View File

@ -134,8 +134,33 @@ struct SCMThread
std::array<pc_t, SCM_STACK_DEPTH> calls;
};
#include <cstring>
/**
* Breakpoint callback information
* Stores information about where breakpoints should be triggered.
*
* breakpointFlags stores the state to be checked against.
*/
struct SCMBreakpointInfo
{
enum /* Breakpoint Flags */ {
BP_ProgramCounter = 1,
BP_ThreadName = 2
};
uint8_t breakpointFlags;
SCMThread::pc_t programCounter;
char threadName[17];
static SCMBreakpointInfo breakThreadName(char threadName[17])
{
SCMBreakpointInfo i;
i.breakpointFlags = BP_ThreadName;
std::strncpy(i.threadName, threadName, 17);
return i;
}
};
/**
* Information about breakpoints that have been hit
*/
struct SCMBreakpoint
{
@ -144,6 +169,8 @@ struct SCMBreakpoint
ScriptMachine* vm;
ScriptFunctionMeta* function;
ScriptArguments* args;
/** The breakpoint entry that triggered this breakpoint */
SCMBreakpointInfo* info;
};
/**
@ -198,14 +225,13 @@ public:
/**
* Adds a breakpoint
* @param pc The instruction address to break on.
*/
void addBreakpoint(SCMThread::pc_t pc);
void addBreakpoint(const SCMBreakpointInfo& bpi);
/**
* Removes a breakpoint.
*/
void removeBreakpoint(SCMThread::pc_t pc);
void removeBreakpoint(const SCMBreakpointInfo& bpi);
/**
* Interupt VM execution at the start of the next instruction
@ -227,10 +253,12 @@ private:
void executeThread(SCMThread& t, int msPassed);
SCMBreakpointInfo* findBreakpoint(SCMThread& t, SCMThread::pc_t pc);
std::vector<SCMByte> globalData;
BreakpointHandler bpHandler;
std::set<SCMThread::pc_t> breakpoints;
std::vector<SCMBreakpointInfo> breakpoints;
};
#endif

View File

@ -277,6 +277,12 @@ void CharacterObject::setPosition(const glm::vec3& pos)
if( physCharacter )
{
btVector3 bpos(pos.x, pos.y, pos.z);
if( std::abs(-100.f - pos.z) < 0.01f )
{
// Find the ground position
auto gpos = engine->getGroundAtPosition(pos);
bpos.setZ(gpos.z+1.f);
}
physCharacter->warp(bpos);
}
position = pos;

View File

@ -135,8 +135,9 @@ void ScriptMachine::executeThread(SCMThread &t, int msPassed)
if( hasDebugging )
{
if( breakpoints.find(pc) != breakpoints.end() || interupt )
{
auto activeBreakpoint = findBreakpoint(t, pc);
if( activeBreakpoint || interupt )
{
interupt = false;
SCMBreakpoint bp;
bp.pc = t.programCounter;
@ -249,19 +250,42 @@ void ScriptMachine::execute(float dt)
}
}
SCMBreakpointInfo* ScriptMachine::findBreakpoint(SCMThread& t, SCMThread::pc_t pc)
{
for(std::vector<SCMBreakpointInfo>::iterator bp = breakpoints.begin(); bp != breakpoints.end(); ++bp)
{
if( (bp->breakpointFlags & SCMBreakpointInfo::BP_ProgramCounter) == SCMBreakpointInfo::BP_ProgramCounter )
{
if( bp->programCounter != pc )
{
continue;
}
}
if( (bp->breakpointFlags & SCMBreakpointInfo::BP_ThreadName) == SCMBreakpointInfo::BP_ThreadName )
{
if( std::strcmp(bp->threadName, t.name) != 0 )
{
continue;
}
}
return &(*bp);
}
return nullptr;
}
void ScriptMachine::setBreakpointHandler(const ScriptMachine::BreakpointHandler& handler)
{
bpHandler = handler;
}
void ScriptMachine::addBreakpoint(SCMThread::pc_t pc)
void ScriptMachine::addBreakpoint(const SCMBreakpointInfo& bpi)
{
breakpoints.insert(pc);
breakpoints.push_back(bpi);
}
void ScriptMachine::removeBreakpoint(SCMThread::pc_t pc)
void ScriptMachine::removeBreakpoint(const SCMBreakpointInfo& bpi)
{
breakpoints.erase(pc);
//breakpoints.erase(pc);
}

View File

@ -47,8 +47,8 @@ template<class Tobject>
void game_set_object_position(const ScriptArguments& args)
{
auto character = args.getObject<Tobject>(0);
glm::vec3 position(args[1].real, args[2].real, args[3].real + 1.f);
character->setPosition(position + spawnMagic);
glm::vec3 position(args[1].real, args[2].real, args[3].real);
character->setPosition(position);// + spawnMagic);
}
bool game_player_in_area_2d(const ScriptArguments& args)

View File

@ -28,7 +28,8 @@ DebugDraw* debug;
StdOutReciever logPrinter;
RWGame::RWGame(const std::string& gamepath, int argc, char* argv[])
: state(nullptr), world(nullptr), renderer(nullptr), script(nullptr), inFocus(true),
: state(nullptr), world(nullptr), renderer(nullptr), script(nullptr),
debugScript(false), inFocus(true),
showDebugStats(false), showDebugPaths(false), showDebugPhysics(false),
accum(0.f), timescale(1.f)
{
@ -36,7 +37,6 @@ RWGame::RWGame(const std::string& gamepath, int argc, char* argv[])
bool fullscreen = false;
bool newgame = false;
bool test = false;
bool debugscript = false;
std::string startSave;
for( int i = 1; i < argc; ++i )
@ -63,7 +63,7 @@ RWGame::RWGame(const std::string& gamepath, int argc, char* argv[])
}
if( strcmp( "--debug", argv[i] ) == 0 )
{
debugscript = true;
debugScript = true;
}
if( strcmp( "--load", argv[i] ) == 0 && i+1 < argc )
{
@ -212,7 +212,10 @@ void RWGame::startScript(const std::string& name)
if( f ) {
if( script ) delete script;
if ( ! httpserver) {
if ( debugScript ) {
if( httpserver ) {
delete httpserver;
}
httpserver_thread = new std::thread([&](){
httpserver = new HttpServer(this, world);
httpserver->run();
@ -228,8 +231,9 @@ void RWGame::startScript(const std::string& name)
/* If Debug server is available, break on the first opcode executed */
if( httpserver ) {
script->interuptNext();
//script->interuptNext();
}
//script->addBreakpoint(SCMBreakpointInfo::breakThreadName("i_save"));
// Set up breakpoint handler
script->setBreakpointHandler(

View File

@ -24,6 +24,7 @@ class RWGame
ScriptMachine* script;
// Background worker
WorkContext work;
bool debugScript;
HttpServer* httpserver = nullptr;
std::thread* httpserver_thread = nullptr;
sf::RenderWindow window;

View File

@ -143,16 +143,23 @@ void HttpServer::run()
buf[received] = '\0';
std::cout << "Got " << received << " bytes: " << buf << std::endl;
std::regex regex_http_first_line("(\\w+)\\s+(/.*?)\\s+HTTP/\\d+.\\d+");
std::cmatch regex_match;
std::regex_search(buf, regex_match, regex_http_first_line);
try
{
std::regex regex_http_first_line("(\\w+)\\s+(/.*?)\\s+HTTP/\\d+.\\d+");
std::cmatch regex_match;
std::regex_search(buf, regex_match, regex_http_first_line);
if (regex_match.size() == 3) {
std::string http_method = regex_match.str(1);
std::string http_path = regex_match.str(2);
if (regex_match.size() == 3) {
std::string http_method = regex_match.str(1);
std::string http_path = regex_match.str(2);
std::string response = dispatch(http_method, http_path);
client.send(response.c_str(), response.size());
std::string response = dispatch(http_method, http_path);
client.send(response.c_str(), response.size());
}
}
catch(std::regex_error er)
{
std::cerr << er.what() << " " << er.code() << std::endl;
}
client.disconnect();