mirror of
https://github.com/rwengine/openrw.git
synced 2024-11-22 10:22:52 +01:00
Remove breakpoint system from ScriptMachine
This commit is contained in:
parent
0a982c1fca
commit
8a985309f9
@ -27,11 +27,6 @@ bool SCMOpcodes::findOpcode(ScriptFunctionID id, ScriptFunctionMeta** out)
|
||||
return false;
|
||||
}
|
||||
|
||||
void ScriptMachine::interuptNext()
|
||||
{
|
||||
interupt = true;
|
||||
}
|
||||
|
||||
void ScriptMachine::executeThread(SCMThread &t, int msPassed)
|
||||
{
|
||||
if( t.wakeCounter > 0 ) {
|
||||
@ -39,8 +34,6 @@ void ScriptMachine::executeThread(SCMThread &t, int msPassed)
|
||||
}
|
||||
if( t.wakeCounter > 0 ) return;
|
||||
|
||||
bool hasDebugging = !! bpHandler;
|
||||
|
||||
while( t.wakeCounter == 0 ) {
|
||||
auto pc = t.programCounter;
|
||||
auto opcode = _file->read<SCMOpcode>(pc);
|
||||
@ -128,22 +121,6 @@ void ScriptMachine::executeThread(SCMThread &t, int msPassed)
|
||||
|
||||
ScriptArguments sca(¶meters, &t, this);
|
||||
|
||||
if( hasDebugging )
|
||||
{
|
||||
auto activeBreakpoint = findBreakpoint(t, pc);
|
||||
if( activeBreakpoint || interupt )
|
||||
{
|
||||
interupt = false;
|
||||
SCMBreakpoint bp;
|
||||
bp.pc = t.programCounter;
|
||||
bp.thread = &t;
|
||||
bp.vm = this;
|
||||
bp.function = &code;
|
||||
bp.args = &sca;
|
||||
bpHandler(bp);
|
||||
}
|
||||
}
|
||||
|
||||
#if RW_SCRIPT_DEBUG
|
||||
static auto sDebugThreadName = getenv("OPENRW_DEBUG_THREAD");
|
||||
if (!sDebugThreadName || strncmp(t.name, sDebugThreadName, 8) == 0)
|
||||
@ -213,7 +190,7 @@ void ScriptMachine::executeThread(SCMThread &t, int msPassed)
|
||||
}
|
||||
|
||||
ScriptMachine::ScriptMachine(GameState* _state, SCMFile *file, SCMOpcodes *ops)
|
||||
: _file(file), _ops(ops), state(_state), interupt(false)
|
||||
: _file(file), _ops(ops), state(_state)
|
||||
{
|
||||
auto globals = _file->getGlobalsSize();
|
||||
globalData.resize(globals);
|
||||
@ -267,49 +244,3 @@ 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(const SCMBreakpointInfo& bpi)
|
||||
{
|
||||
breakpoints.push_back(bpi);
|
||||
}
|
||||
|
||||
void ScriptMachine::removeBreakpoint(const SCMBreakpointInfo& bpi)
|
||||
{
|
||||
for (size_t i = 0; i < breakpoints.size(); ++i)
|
||||
{
|
||||
if (bpi == breakpoints[i])
|
||||
{
|
||||
breakpoints.erase(breakpoints.begin() + i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -136,59 +136,6 @@ struct SCMThread
|
||||
std::array<pc_t, SCM_STACK_DEPTH> calls;
|
||||
};
|
||||
|
||||
#include <cstring>
|
||||
/**
|
||||
* 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];
|
||||
|
||||
bool operator == (const SCMBreakpointInfo& rhs) const
|
||||
{
|
||||
if (breakpointFlags != rhs.breakpointFlags) return false;
|
||||
if ((breakpointFlags & BP_ProgramCounter) != 0)
|
||||
{
|
||||
if (programCounter != rhs.programCounter) return false;
|
||||
}
|
||||
if ((breakpointFlags & BP_ThreadName) != 0)
|
||||
{
|
||||
if (strncmp(threadName, rhs.threadName, 17) != 0) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
SCMThread::pc_t pc;
|
||||
SCMThread* thread;
|
||||
ScriptMachine* vm;
|
||||
ScriptFunctionMeta* function;
|
||||
ScriptArguments* args;
|
||||
/** The breakpoint entry that triggered this breakpoint */
|
||||
SCMBreakpointInfo* info;
|
||||
};
|
||||
|
||||
/**
|
||||
* Implements the actual fetch-execute mechanism for the game script virtual machine.
|
||||
*
|
||||
@ -205,9 +152,6 @@ struct SCMBreakpoint
|
||||
* Within ScriptMachine, each thread's program counter is used to execute an instruction
|
||||
* by consuming the correct number of arguments, allowing the next instruction to be found,
|
||||
* and then dispatching a call to the opcode's function.
|
||||
*
|
||||
* Breakpoints can be set which will call the breakpoint hander, where it is possible
|
||||
* to halt execution by refusing to return until the handler is ready to continue.
|
||||
*/
|
||||
class ScriptMachine
|
||||
{
|
||||
@ -228,32 +172,6 @@ public:
|
||||
|
||||
GameState* getState() const { return state; }
|
||||
|
||||
typedef std::function<void (const SCMBreakpoint&)> BreakpointHandler;
|
||||
|
||||
/**
|
||||
* Set the breakpoint handler callback.
|
||||
*
|
||||
* When the VM reaches an instruction marked as a brekapoint
|
||||
* by addBreakpoint, the handler will be called with information
|
||||
* about the state of the VM and the active thread.
|
||||
*/
|
||||
void setBreakpointHandler(const BreakpointHandler& handler);
|
||||
|
||||
/**
|
||||
* Adds a breakpoint
|
||||
*/
|
||||
void addBreakpoint(const SCMBreakpointInfo& bpi);
|
||||
|
||||
/**
|
||||
* Removes a breakpoint.
|
||||
*/
|
||||
void removeBreakpoint(const SCMBreakpointInfo& bpi);
|
||||
|
||||
/**
|
||||
* Interupt VM execution at the start of the next instruction
|
||||
*/
|
||||
void interuptNext();
|
||||
|
||||
/**
|
||||
* @brief executes threads until they are all in waiting state.
|
||||
*/
|
||||
@ -263,18 +181,12 @@ private:
|
||||
SCMFile* _file;
|
||||
SCMOpcodes* _ops;
|
||||
GameState* state;
|
||||
bool interupt;
|
||||
|
||||
std::list<SCMThread> _activeThreads;
|
||||
|
||||
void executeThread(SCMThread& t, int msPassed);
|
||||
|
||||
SCMBreakpointInfo* findBreakpoint(SCMThread& t, SCMThread::pc_t pc);
|
||||
|
||||
std::vector<SCMByte> globalData;
|
||||
|
||||
BreakpointHandler bpHandler;
|
||||
std::vector<SCMBreakpointInfo> breakpoints;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -255,26 +255,6 @@ void RWGame::startScript(const std::string& name)
|
||||
|
||||
script = new ScriptMachine(state, f, opcodes);
|
||||
|
||||
// Set up breakpoint handler
|
||||
script->setBreakpointHandler(
|
||||
[&](const SCMBreakpoint& bp)
|
||||
{
|
||||
log.info("Script", "Breakpoint hit!");
|
||||
std::stringstream ss;
|
||||
ss << " " << bp.function->description << ".";
|
||||
ss << " Args:";
|
||||
for(size_t a = 0; a < bp.args->getParameters().size(); a++)
|
||||
{
|
||||
auto& arg = bp.args->getParameters()[a];
|
||||
ss << " " << arg.integerValue();
|
||||
if( a != bp.args->getParameters().size()-1 )
|
||||
{
|
||||
ss << ",";
|
||||
}
|
||||
}
|
||||
|
||||
log.info("Script", ss.str());
|
||||
});
|
||||
state->script = script;
|
||||
}
|
||||
else {
|
||||
|
Loading…
Reference in New Issue
Block a user