213 lines
5.4 KiB
C++
213 lines
5.4 KiB
C++
/****************************************************************************
|
|
* *
|
|
* Project64 - A Nintendo 64 emulator. *
|
|
* http://www.pj64-emu.com/ *
|
|
* Copyright (C) 2012 Project64. All rights reserved. *
|
|
* *
|
|
* License: *
|
|
* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html *
|
|
* *
|
|
****************************************************************************/
|
|
#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);
|
|
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);
|
|
RegisterHook("gprvalue", m_HookCPUGPRValue);
|
|
RegisterHook("draw", m_HookFrameDrawn);
|
|
|
|
HMODULE hInst = GetModuleHandle(NULL);
|
|
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);
|
|
}
|
|
|
|
CScriptSystem::~CScriptSystem()
|
|
{
|
|
for (size_t i = 0; i < m_Hooks.size(); i++)
|
|
{
|
|
delete m_Hooks[i].cbList;
|
|
}
|
|
|
|
UnregisterHooks();
|
|
free(m_APIScript);
|
|
}
|
|
|
|
const char* CScriptSystem::APIScript()
|
|
{
|
|
return m_APIScript;
|
|
}
|
|
|
|
void CScriptSystem::RunScript(const char * path)
|
|
{
|
|
CGuard guard(m_CS);
|
|
CScriptInstance* scriptInstance = new CScriptInstance(m_Debugger);
|
|
char* pathSaved = (char*)malloc(strlen(path)+1); // freed via DeleteStoppedInstances
|
|
strcpy(pathSaved, path);
|
|
|
|
m_RunningInstances.push_back({ pathSaved, scriptInstance });
|
|
scriptInstance->Start(pathSaved);
|
|
}
|
|
|
|
void CScriptSystem::StopScript(const char* path)
|
|
{
|
|
CScriptInstance* scriptInstance = GetInstance(path);
|
|
|
|
if (scriptInstance == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
scriptInstance->ForceStop();
|
|
DeleteStoppedInstances();
|
|
}
|
|
|
|
void CScriptSystem::DeleteStoppedInstances()
|
|
{
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
|
|
INSTANCE_STATE CScriptSystem::GetInstanceState(const char* path)
|
|
{
|
|
CGuard guard(m_CS);
|
|
|
|
for (size_t i = 0; i < m_RunningInstances.size(); i++)
|
|
{
|
|
if (strcmp(m_RunningInstances[i].path, path) == 0)
|
|
{
|
|
INSTANCE_STATE ret = m_RunningInstances[i].scriptInstance->GetState();
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
return STATE_INVALID;
|
|
}
|
|
|
|
CScriptInstance* CScriptSystem::GetInstance(const char* path)
|
|
{
|
|
CGuard guard(m_CS);
|
|
|
|
for (size_t i = 0; i < m_RunningInstances.size(); i++)
|
|
{
|
|
if (strcmp(m_RunningInstances[i].path, path) == 0)
|
|
{
|
|
CScriptInstance *ret = m_RunningInstances[i].scriptInstance;
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
void CScriptSystem::ClearCallbacksForInstance(CScriptInstance* scriptInstance)
|
|
{
|
|
for (size_t i = 0; i < m_Hooks.size(); i++)
|
|
{
|
|
m_Hooks[i].cbList->RemoveByInstance(scriptInstance);
|
|
}
|
|
}
|
|
|
|
void CScriptSystem::RemoveCallbackById(int callbackId)
|
|
{
|
|
for (size_t i = 0; i < m_Hooks.size(); i++)
|
|
{
|
|
m_Hooks[i].cbList->RemoveById(callbackId);
|
|
}
|
|
}
|
|
|
|
void CScriptSystem::RegisterHook(const char* hookId, CScriptHook* cbList)
|
|
{
|
|
HOOKENTRY hook = { hookId, cbList };
|
|
m_Hooks.push_back(hook);
|
|
}
|
|
|
|
void CScriptSystem::UnregisterHooks()
|
|
{
|
|
m_Hooks.clear();
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
int CScriptSystem::GetNextCallbackId()
|
|
{
|
|
return m_NextCallbackId++;
|
|
}
|
|
|
|
void CScriptSystem::CallbackAdded()
|
|
{
|
|
m_NumCallbacks++;
|
|
}
|
|
|
|
void CScriptSystem::CallbackRemoved()
|
|
{
|
|
if (m_NumCallbacks > 0)
|
|
{
|
|
m_NumCallbacks--;
|
|
}
|
|
}
|