1
0
mirror of https://github.com/rwengine/openrw.git synced 2024-10-05 16:47:19 +02:00
openrw/rwengine/include/script/ScriptMachine.hpp

98 lines
2.0 KiB
C++
Raw Normal View History

2014-07-21 01:34:28 +02:00
#pragma once
#ifndef _SCRIPTMACHINE_HPP_
#define _SCRIPTMACHINE_HPP_
#include <script/ScriptTypes.hpp>
#include <sstream>
#include <iomanip>
2014-07-21 01:34:28 +02:00
#include <string>
#include <vector>
2014-07-21 01:34:28 +02:00
#define SCM_CONDITIONAL_MASK 0xF000
#define SCM_THREAD_LOCAL_SIZE 256
class SCMFile;
2014-07-21 01:34:28 +02:00
struct SCMException
{
virtual ~SCMException() { }
virtual std::string what() const = 0;
};
struct IllegalInstruction : SCMException
{
SCMOpcode opcode;
unsigned int offset;
std::string thread;
2014-07-21 01:34:28 +02:00
IllegalInstruction(SCMOpcode opcode, unsigned int offset, const std::string& thread)
: opcode(opcode), offset(offset), thread(thread) { }
2014-07-21 01:34:28 +02:00
std::string what() const {
std::stringstream ss;
ss << "Illegal Instruction " <<
std::setfill('0') << std::setw(4) << std::hex << opcode <<
" encountered at offset " <<
std::setfill('0') << std::setw(4) << std::hex << offset <<
" on thread " << thread;
2014-07-21 01:34:28 +02:00
return ss.str();
}
};
struct UnknownType : SCMException
{
SCMByte type;
unsigned int offset;
std::string thread;
2014-07-21 01:34:28 +02:00
UnknownType(SCMByte type, unsigned int offset, const std::string& thread)
: type(type), offset(offset), thread(thread) {}
2014-07-21 01:34:28 +02:00
std::string what() const {
std::stringstream ss;
ss << "Unkown data type " <<
std::setfill('0') << std::hex << static_cast<unsigned int>(type) <<
" encountered at offset " <<
std::setfill('0') << std::hex << offset <<
" on thread " << thread;
2014-07-21 01:34:28 +02:00
return ss.str();
}
};
static SCMMicrocodeTable knownOps;
struct SCMThread
{
typedef unsigned int pc_t;
2014-07-21 01:34:28 +02:00
std::string name;
pc_t programCounter;
/** Number of MS until the thread should be waked (-1 = yeilded) */
int wakeCounter;
SCMByte locals[SCM_THREAD_LOCAL_SIZE];
2014-07-21 01:34:28 +02:00
};
class ScriptMachine
{
SCMFile* _file;
SCMOpcodes* _ops;
2014-07-21 01:34:28 +02:00
std::vector<SCMThread> _activeThreads;
2014-07-21 01:34:28 +02:00
void executeThread(SCMThread& t, int msPassed);
2014-07-21 01:34:28 +02:00
public:
ScriptMachine(SCMFile* file, SCMOpcodes* ops);
~ScriptMachine();
void startThread(SCMThread::pc_t start);
2014-07-21 01:34:28 +02:00
SCMByte* getGlobals();
2014-07-21 01:34:28 +02:00
/**
* @brief executes threads until they are all in waiting state.
*/
void execute(float dt);
2014-07-21 01:34:28 +02:00
};
#endif