187 lines
5.4 KiB
C++
187 lines
5.4 KiB
C++
#include <fstream>
|
|
#include <map>
|
|
#include <windows.h>
|
|
|
|
#include "ScriptTypes.h"
|
|
#include "debugger.h"
|
|
|
|
#pragma once
|
|
|
|
#define SCRIPTSYS_SCRIPTS_DIR "Scripts\\"
|
|
#define SCRIPTSYS_MODULES_DIR "Scripts\\modules\\"
|
|
|
|
class CScriptSystem
|
|
{
|
|
typedef std::map<JSInstanceName, CScriptInstance *> JSInstanceMap;
|
|
typedef std::vector<JSAppCallback> JSAppCallbackList;
|
|
typedef std::map<JSInstanceName, JSInstanceStatus> JSInstanceStatusMap;
|
|
typedef std::vector<JSSysCommand> JSSysCommandQueue;
|
|
|
|
enum
|
|
{
|
|
JS_CPU_CB_RANGE_CACHE_SIZE = 256
|
|
};
|
|
|
|
struct JSCpuCbListInfo
|
|
{
|
|
size_t numCallbacks;
|
|
uint32_t minAddrStart;
|
|
uint32_t maxAddrEnd;
|
|
size_t numRangeCacheEntries;
|
|
bool bRangeCacheExceeded;
|
|
struct
|
|
{
|
|
uint32_t addrStart;
|
|
uint32_t addrEnd;
|
|
} rangeCache[JS_CPU_CB_RANGE_CACHE_SIZE];
|
|
};
|
|
|
|
HANDLE m_hThread;
|
|
|
|
CriticalSection m_CmdQueueCS;
|
|
JSSysCommandQueue m_CmdQueue;
|
|
HANDLE m_hCmdEvent;
|
|
std::set<JSInstanceName> m_StopsIssued;
|
|
|
|
CriticalSection m_InstancesCS;
|
|
JSInstanceMap m_Instances;
|
|
JSAppCallbackList m_AppCallbackHooks[JS_NUM_APP_HOOKS];
|
|
JSAppCallbackID m_NextAppCallbackId;
|
|
|
|
volatile size_t m_AppCallbackCount;
|
|
|
|
volatile JSCpuCbListInfo m_CpuExecCbInfo;
|
|
volatile JSCpuCbListInfo m_CpuReadCbInfo;
|
|
volatile JSCpuCbListInfo m_CpuWriteCbInfo;
|
|
|
|
CriticalSection m_UIStateCS;
|
|
JSInstanceStatusMap m_UIInstanceStatus;
|
|
stdstr m_UILog;
|
|
|
|
CDebuggerUI * m_Debugger;
|
|
|
|
std::set<std::string> m_AutorunList;
|
|
|
|
stdstr m_InstallDirFullPath;
|
|
stdstr m_ScriptsDirFullPath;
|
|
stdstr m_ModulesDirFullPath;
|
|
|
|
public:
|
|
CScriptSystem(CDebuggerUI * debugger);
|
|
~CScriptSystem();
|
|
|
|
CDebuggerUI * Debugger();
|
|
|
|
void StartScript(const char * instanceName, const char * path);
|
|
void StopScript(const char * instanceName);
|
|
void Input(const char * instanceName, const char * code);
|
|
|
|
stdstr InstallDirPath();
|
|
stdstr ScriptsDirPath();
|
|
stdstr ModulesDirPath();
|
|
|
|
JSInstanceStatus GetStatus(const char * instanceName);
|
|
void NotifyStatus(const char * instanceName, JSInstanceStatus status);
|
|
void ConsoleLog(const char * format, ...);
|
|
void ConsolePrint(const char * format, ...);
|
|
void ConsoleClear();
|
|
stdstr GetConsoleBuffer();
|
|
|
|
void PostCMethodCall(const char * instanceName, void * dukThisHeapPtr, duk_c_function func,
|
|
JSDukArgSetupFunc argSetupFunc = nullptr,
|
|
void * argSetupParam = nullptr,
|
|
size_t argSetupParamSize = 0);
|
|
|
|
bool HaveAppCallbacks(JSAppHookID hookId);
|
|
|
|
// Note: Unguarded for speed, shouldn't matter
|
|
inline bool HaveAppCallbacks()
|
|
{
|
|
return m_AppCallbackCount != 0;
|
|
}
|
|
|
|
inline bool HaveCpuExecCallbacks(uint32_t address)
|
|
{
|
|
return HaveCpuCallbacks(m_CpuExecCbInfo, m_AppCallbackHooks[JS_HOOK_CPU_EXEC], address);
|
|
}
|
|
|
|
inline bool HaveCpuReadCallbacks(uint32_t address)
|
|
{
|
|
return HaveCpuCallbacks(m_CpuReadCbInfo, m_AppCallbackHooks[JS_HOOK_CPU_READ], address);
|
|
}
|
|
|
|
inline bool HaveCpuWriteCallbacks(uint32_t address)
|
|
{
|
|
return HaveCpuCallbacks(m_CpuWriteCbInfo, m_AppCallbackHooks[JS_HOOK_CPU_WRITE], address);
|
|
}
|
|
|
|
static void UpdateCpuCbListInfo(volatile JSCpuCbListInfo & info, JSAppCallbackList & callbacks);
|
|
|
|
void DoMouseEvent(JSAppHookID hookId, int x, int y, DWORD uMsg = (DWORD)-1);
|
|
void InvokeAppCallbacks(JSAppHookID hookId, void * env = nullptr);
|
|
|
|
void ExecAutorunList();
|
|
std::set<std::string> & AutorunList();
|
|
void LoadAutorunList();
|
|
void SaveAutorunList();
|
|
|
|
JSAppCallbackID RawAddAppCallback(JSAppHookID hookId, JSAppCallback & callback);
|
|
void RawRemoveAppCallback(JSAppHookID hookId, JSAppCallbackID callbackId);
|
|
|
|
private:
|
|
inline bool HaveCpuCallbacks(volatile JSCpuCbListInfo & info, JSAppCallbackList & callbacks, uint32_t address)
|
|
{
|
|
if (info.numCallbacks == 0 || address < info.minAddrStart || address > info.maxAddrEnd)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (!info.bRangeCacheExceeded)
|
|
{
|
|
for (size_t i = 0; i < info.numRangeCacheEntries; i++)
|
|
{
|
|
if (address >= info.rangeCache[i].addrStart && address <= info.rangeCache[i].addrEnd)
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
CGuard guard(m_InstancesCS);
|
|
|
|
for (JSAppCallback & callback : callbacks)
|
|
{
|
|
if (address >= callback.m_Params.addrStart && address <= callback.m_Params.addrEnd)
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void InitDirectories();
|
|
|
|
void PostCommand(JSSysCommandID id, stdstr paramA = "", stdstr paramB = "", void * paramC = nullptr);
|
|
|
|
static DWORD WINAPI ThreadProc(void * _this);
|
|
void ThreadProc();
|
|
|
|
bool ProcessCommand(JSSysCommand & cmd);
|
|
bool ProcessCommandQueue(std::vector<JSSysCommand> & queue);
|
|
void PullCommands(JSSysCommandID id, std::vector<JSSysCommand> & out);
|
|
|
|
void OnStartScript(const char * name, const char * path);
|
|
void OnStopScript(const char * name);
|
|
void OnInput(const char * name, const char * code);
|
|
void OnCMethodCall(const char * name, JSSysCMethodCall * methodCall);
|
|
void OnSweep(bool bIfDone);
|
|
|
|
bool RawRemoveInstance(const char * key);
|
|
void RefreshCallbackMaps();
|
|
|
|
static stdstr FixStringReturns(const char * str);
|
|
};
|