project64/Source/Project64/UserInterface/Debugger/ScriptSystem.cpp

203 lines
4.6 KiB
C++
Raw Normal View History

2017-08-18 05:08:22 +00:00
#include <stdafx.h>
#include "ScriptSystem.h"
#include "Debugger-Scripts.h"
#include "ScriptInstance.h"
#include "ScriptHook.h"
CScriptSystem::CScriptSystem(CDebuggerUI* debugger)
{
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData);
m_NextCallbackId = 0;
m_NumCallbacks = 0;
m_Debugger = debugger;
m_HookCPUExec = new CScriptHook(this);
2018-12-07 04:19:28 +00:00
m_HookCPUExecOpcode = new CScriptHook(this);
m_HookCPURead = new CScriptHook(this);
m_HookCPUWrite = new CScriptHook(this);
m_HookCPUGPRValue = new CScriptHook(this);
m_HookFrameDrawn = new CScriptHook(this);
RegisterHook("exec", m_HookCPUExec);
RegisterHook("read", m_HookCPURead);
RegisterHook("write", m_HookCPUWrite);
RegisterHook("opcode", m_HookCPUExecOpcode);
2019-12-25 00:41:20 +00:00
RegisterHook("gprvalue", m_HookCPUGPRValue);
RegisterHook("draw", m_HookFrameDrawn);
HMODULE hInst = GetModuleHandle(NULL);
2020-05-12 12:19:05 +00:00
HRSRC hRes = FindResource(hInst, MAKEINTRESOURCE(IDR_JSAPI_TEXT), L"TEXT");
HGLOBAL hGlob = LoadResource(hInst, hRes);
DWORD resSize = SizeofResource(hInst, hRes);
m_APIScript = (char*)malloc(resSize + 1);
void* resData = LockResource(hGlob);
memcpy(m_APIScript, resData, resSize);
m_APIScript[resSize] = '\0';
FreeResource(hGlob);
2017-08-18 05:08:22 +00:00
}
CScriptSystem::~CScriptSystem()
{
for (size_t i = 0; i < m_Hooks.size(); i++)
{
delete m_Hooks[i].cbList;
}
2017-08-18 05:08:22 +00:00
UnregisterHooks();
free(m_APIScript);
2017-08-18 05:08:22 +00:00
}
const char* CScriptSystem::APIScript()
{
return m_APIScript;
2017-08-18 05:08:22 +00:00
}
2021-01-19 05:58:59 +00:00
void CScriptSystem::RunScript(const char * path)
2017-08-18 05:08:22 +00:00
{
2019-12-25 00:41:20 +00:00
CGuard guard(m_CS);
CScriptInstance* scriptInstance = new CScriptInstance(m_Debugger);
2019-04-28 07:38:35 +00:00
char* pathSaved = (char*)malloc(strlen(path)+1); // freed via DeleteStoppedInstances
strcpy(pathSaved, path);
2019-12-25 00:41:20 +00:00
m_RunningInstances.push_back({ pathSaved, scriptInstance });
scriptInstance->Start(pathSaved);
2017-08-18 05:08:22 +00:00
}
2021-01-19 05:58:59 +00:00
void CScriptSystem::StopScript(const char* path)
2017-08-18 05:08:22 +00:00
{
CScriptInstance* scriptInstance = GetInstance(path);
2017-08-18 05:08:22 +00:00
if (scriptInstance == NULL)
{
return;
}
2017-08-18 05:08:22 +00:00
scriptInstance->ForceStop();
2019-12-25 00:41:20 +00:00
DeleteStoppedInstances();
2017-08-18 05:08:22 +00:00
}
void CScriptSystem::DeleteStoppedInstances()
{
2019-12-25 00:41:20 +00:00
CGuard guard(m_CS);
int lastIndex = m_RunningInstances.size() - 1;
for (int i = lastIndex; i >= 0; i--)
{
if (m_RunningInstances[i].scriptInstance->GetState() == STATE_STOPPED)
{
free(m_RunningInstances[i].path);
CScriptInstance* instance = m_RunningInstances[i].scriptInstance;
delete instance;
m_RunningInstances.erase(m_RunningInstances.begin() + i);
}
}
2017-08-18 05:08:22 +00:00
}
2020-05-12 12:19:05 +00:00
INSTANCE_STATE CScriptSystem::GetInstanceState(const char* path)
2017-08-18 05:08:22 +00:00
{
2019-12-25 00:41:20 +00:00
CGuard guard(m_CS);
for (size_t i = 0; i < m_RunningInstances.size(); i++)
{
if (strcmp(m_RunningInstances[i].path, path) == 0)
{
2019-12-25 00:41:20 +00:00
INSTANCE_STATE ret = m_RunningInstances[i].scriptInstance->GetState();
return ret;
}
}
2019-12-25 00:41:20 +00:00
return STATE_INVALID;
2017-08-18 05:08:22 +00:00
}
2020-05-12 12:19:05 +00:00
CScriptInstance* CScriptSystem::GetInstance(const char* path)
2017-08-18 05:08:22 +00:00
{
2019-12-25 00:41:20 +00:00
CGuard guard(m_CS);
for (size_t i = 0; i < m_RunningInstances.size(); i++)
{
if (strcmp(m_RunningInstances[i].path, path) == 0)
{
2019-12-25 00:41:20 +00:00
CScriptInstance *ret = m_RunningInstances[i].scriptInstance;
return ret;
}
}
return NULL;
2017-08-18 05:08:22 +00:00
}
bool CScriptSystem::HasCallbacksForInstance(CScriptInstance* scriptInstance)
{
for (size_t i = 0; i < m_Hooks.size(); i++)
{
if (m_Hooks[i].cbList->HasContext(scriptInstance))
{
return true;
}
}
return false;
2017-08-18 05:08:22 +00:00
}
void CScriptSystem::ClearCallbacksForInstance(CScriptInstance* scriptInstance)
{
for (size_t i = 0; i < m_Hooks.size(); i++)
{
m_Hooks[i].cbList->RemoveByInstance(scriptInstance);
}
2017-08-18 05:08:22 +00:00
}
void CScriptSystem::RemoveCallbackById(int callbackId)
{
for (size_t i = 0; i < m_Hooks.size(); i++)
{
m_Hooks[i].cbList->RemoveById(callbackId);
}
2017-08-18 05:08:22 +00:00
}
void CScriptSystem::RegisterHook(const char* hookId, CScriptHook* cbList)
{
HOOKENTRY hook = { hookId, cbList };
m_Hooks.push_back(hook);
2017-08-18 05:08:22 +00:00
}
void CScriptSystem::UnregisterHooks()
{
m_Hooks.clear();
2017-08-18 05:08:22 +00:00
}
CScriptHook* CScriptSystem::GetHook(const char* hookId)
{
size_t size = m_Hooks.size();
for (size_t i = 0; i < size; i++)
{
if (strcmp(m_Hooks[i].hookId, hookId) == 0)
{
return m_Hooks[i].cbList;
}
}
return NULL;
2017-08-18 05:08:22 +00:00
}
int CScriptSystem::GetNextCallbackId()
{
return m_NextCallbackId++;
}
void CScriptSystem::CallbackAdded()
{
m_NumCallbacks++;
}
void CScriptSystem::CallbackRemoved()
{
if (m_NumCallbacks > 0)
{
m_NumCallbacks--;
}
}