project64/Source/Project64/UserInterface/Debugger/Debugger-Scripts.cpp

433 lines
11 KiB
C++
Raw Normal View History

2017-08-18 05:08:22 +00:00
/****************************************************************************
* *
* 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 "DebuggerUI.h"
//char* CEditEval::m_EvalString;
CDebugScripts::CDebugScripts(CDebuggerUI* debugger) :
CDebugDialog<CDebugScripts>(debugger)
2017-08-18 05:08:22 +00:00
{
m_SelectedScriptName = (char*)malloc(MAX_PATH);
2019-12-25 00:41:20 +00:00
//CScriptSystem::SetScriptsWindow(this);
2017-08-18 05:08:22 +00:00
}
CDebugScripts::~CDebugScripts(void)
{
2019-12-25 00:41:20 +00:00
free(m_SelectedScriptName);
2017-08-18 05:08:22 +00:00
}
2018-01-18 06:53:07 +00:00
LRESULT CDebugScripts::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
2017-08-18 05:08:22 +00:00
{
DlgResize_Init(false, true);
DlgSavePos_Init(DebuggerUI_ScriptsPos);
HFONT monoFont = CreateFont(-11, 0, 0, 0,
FW_DONTCARE, FALSE, FALSE, FALSE, DEFAULT_CHARSET,
OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
2020-05-12 12:19:05 +00:00
CLEARTYPE_QUALITY, FF_DONTCARE, L"Consolas"
);
m_InstanceInfoEdit.Attach(GetDlgItem(IDC_CTX_INFO_EDIT));
m_ScriptList.Attach(GetDlgItem(IDC_SCRIPT_LIST));
2020-05-12 12:19:05 +00:00
m_ScriptList.AddColumn(L"Script", 0, 0);
m_ScriptList.SetColumnWidth(0, 100);
m_ScriptList.SetExtendedListViewStyle(LVS_EX_FULLROWSELECT | LVS_EX_DOUBLEBUFFER);
m_ScriptList.ModifyStyle(LVS_OWNERDRAWFIXED, 0, 0);
m_EvalEdit.Attach(GetDlgItem(IDC_EVAL_EDIT));
m_EvalEdit.SetScriptWindow(this);
m_EvalEdit.SetFont(monoFont);
m_EvalEdit.EnableWindow(FALSE);
m_ConsoleEdit.Attach(GetDlgItem(IDC_CONSOLE_EDIT));
m_ConsoleEdit.SetLimitText(0);
m_ConsoleEdit.SetFont(monoFont);
RefreshList();
2019-12-25 00:41:20 +00:00
LoadWindowPos();
WindowCreated();
return 0;
2017-08-18 05:08:22 +00:00
}
void CDebugScripts::OnExitSizeMove(void)
{
SaveWindowPos(true);
}
2017-08-18 05:08:22 +00:00
void CDebugScripts::ConsolePrint(const char* text)
{
::ShowWindow(*this, SW_SHOWNOACTIVATE);
// Get scrollbar state
SCROLLINFO scroll;
scroll.cbSize = sizeof(SCROLLINFO);
scroll.fMask = SIF_ALL;
m_ConsoleEdit.GetScrollInfo(SB_VERT, &scroll);
m_ConsoleEdit.SetRedraw(FALSE);
2020-05-12 12:19:05 +00:00
m_ConsoleEdit.AppendText(stdstr(text).ToUTF16().c_str());
m_ConsoleEdit.SetRedraw(TRUE);
2018-01-18 06:53:07 +00:00
if ((scroll.nPage + scroll.nPos) - 1 == (uint32_t)scroll.nMax)
{
m_ConsoleEdit.ScrollCaret();
}
2017-08-18 05:08:22 +00:00
}
void CDebugScripts::RefreshConsole()
{
2019-12-25 00:41:20 +00:00
CGuard guard(m_CS);
m_Debugger->OpenScriptsWindow();
CScriptSystem* scriptSystem = m_Debugger->ScriptSystem();
vector<char*>* logData = scriptSystem->LogData();
while (logData->size() != 0)
{
ConsolePrint((*logData)[0]);
free((*logData)[0]);
logData->erase(logData->begin() + 0);
}
2017-08-18 05:08:22 +00:00
}
void CDebugScripts::ConsoleClear()
{
2020-05-12 12:19:05 +00:00
m_ConsoleEdit.SetWindowText(L"");
2017-08-18 05:08:22 +00:00
}
void CDebugScripts::ConsoleCopy()
{
if (!OpenClipboard())
{
return;
}
EmptyClipboard();
2017-08-18 05:08:22 +00:00
2020-05-12 12:19:05 +00:00
size_t nChars = m_ConsoleEdit.GetWindowTextLength() + 1;
2017-08-18 05:08:22 +00:00
2020-05-12 12:19:05 +00:00
HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, nChars * sizeof(wchar_t));
2017-08-18 05:08:22 +00:00
2020-05-12 12:19:05 +00:00
wchar_t* memBuf = (wchar_t*)GlobalLock(hMem);
m_ConsoleEdit.GetWindowText(memBuf, nChars);
2017-08-18 05:08:22 +00:00
GlobalUnlock(hMem);
2018-01-18 06:53:07 +00:00
SetClipboardData(CF_TEXT, hMem);
GlobalFree(hMem);
CloseClipboard();
2017-08-18 05:08:22 +00:00
}
void CDebugScripts::RefreshList()
{
2019-12-25 00:41:20 +00:00
CGuard guard(m_CS);
2019-12-25 00:41:20 +00:00
int nIndex = m_ScriptList.GetSelectedIndex();
CPath SearchPath("Scripts", "*");
if (!SearchPath.FindFirst(CPath::FIND_ATTRIBUTE_ALLFILES))
{
2019-12-25 00:41:20 +00:00
return;
}
m_ScriptList.SetRedraw(false);
m_ScriptList.DeleteAllItems();
do
{
stdstr scriptFileName = SearchPath.GetNameExtension();
2020-05-12 12:19:05 +00:00
m_ScriptList.AddItem(0, 0, scriptFileName.ToUTF16().c_str());
} while (SearchPath.FindNext());
m_ScriptList.SetRedraw(true);
m_ScriptList.Invalidate();
if (nIndex >= 0)
{
m_ScriptList.SelectItem(nIndex);
RefreshStatus();
}
2017-08-18 05:08:22 +00:00
}
LRESULT CDebugScripts::OnClicked(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
switch (wID)
{
case IDCANCEL:
EndDialog(0);
break;
case ID_POPUP_RUN:
RunSelected();
break;
case ID_POPUP_STOP:
StopSelected();
break;
case ID_POPUP_SCRIPT_EDIT:
EditSelected();
break;
case IDC_CLEAR_BTN:
ConsoleClear();
break;
case IDC_COPY_BTN:
ConsoleCopy();
break;
}
return FALSE;
2017-08-18 05:08:22 +00:00
}
2019-12-25 00:41:20 +00:00
LRESULT CDebugScripts::OnScriptListDblClicked(NMHDR* pNMHDR)
2017-08-18 05:08:22 +00:00
{
// Run script on double click
NMITEMACTIVATE* pIA = reinterpret_cast<NMITEMACTIVATE*>(pNMHDR);
int nItem = pIA->iItem;
2017-08-18 05:08:22 +00:00
m_ScriptList.SelectItem(nItem);
2017-08-18 05:08:22 +00:00
2020-01-07 03:43:09 +00:00
ToggleSelected();
return 0;
2017-08-18 05:08:22 +00:00
}
void CDebugScripts::RefreshStatus()
{
2019-12-25 00:41:20 +00:00
CGuard guard(m_CS);
INSTANCE_STATE state = m_Debugger->ScriptSystem()->GetInstanceState(m_SelectedScriptName);
char* szState = "";
switch (state)
{
2019-12-25 00:41:20 +00:00
case STATE_RUNNING: szState = "Running"; break;
case STATE_STARTED: szState = "Started"; break;
case STATE_STOPPED: szState = "Stopped"; break;
case STATE_INVALID: szState = "Not running"; break;
}
stdstr instanceInfo = stdstr_f("%s (%s)", m_SelectedScriptName, szState);
2020-05-12 12:19:05 +00:00
m_InstanceInfoEdit.SetWindowText(instanceInfo.ToUTF16().c_str());
if (state == STATE_RUNNING)
{
m_EvalEdit.EnableWindow(TRUE);
}
else
{
m_EvalEdit.EnableWindow(FALSE);
}
2017-08-18 05:08:22 +00:00
}
2019-12-25 00:41:20 +00:00
LRESULT CDebugScripts::OnScriptListClicked(NMHDR* pNMHDR)
2017-08-18 05:08:22 +00:00
{
// Select instance for console input
NMITEMACTIVATE* pIA = reinterpret_cast<NMITEMACTIVATE*>(pNMHDR);
int nItem = pIA->iItem;
2020-05-12 12:19:05 +00:00
wchar_t ScriptName[MAX_PATH];
m_ScriptList.GetItemText(nItem, 0, ScriptName, MAX_PATH);
strcpy(m_SelectedScriptName, stdstr().FromUTF16(ScriptName).c_str());
RefreshStatus();
return 0;
2017-08-18 05:08:22 +00:00
}
2019-12-25 00:41:20 +00:00
LRESULT CDebugScripts::OnScriptListRClicked(NMHDR* pNMHDR)
2017-08-18 05:08:22 +00:00
{
OnScriptListClicked(pNMHDR);
HMENU hMenu = LoadMenu(GetModuleHandle(NULL), MAKEINTRESOURCE(IDR_SCRIPT_POPUP));
HMENU hPopupMenu = GetSubMenu(hMenu, 0);
2017-08-18 05:08:22 +00:00
/*
if (m_Breakpoints->m_RBP.size() == 0 && m_Breakpoints->m_WBP.size() == 0)
{
EnableMenuItem(hPopupMenu, ID_POPUPMENU_CLEARALLBPS, MF_DISABLED | MF_GRAYED);
}
*/
2017-08-18 05:08:22 +00:00
POINT mouse;
GetCursorPos(&mouse);
2017-08-18 05:08:22 +00:00
TrackPopupMenu(hPopupMenu, TPM_LEFTALIGN, mouse.x, mouse.y, 0, m_hWnd, NULL);
2017-08-18 05:08:22 +00:00
DestroyMenu(hMenu);
2017-08-18 05:08:22 +00:00
return 0;
2017-08-18 05:08:22 +00:00
}
LRESULT CDebugScripts::OnScriptListCustomDraw(NMHDR* pNMHDR)
{
NMLVCUSTOMDRAW* pLVCD = reinterpret_cast<NMLVCUSTOMDRAW*>(pNMHDR);
DWORD drawStage = pLVCD->nmcd.dwDrawStage;
switch (drawStage)
{
case CDDS_PREPAINT:
return CDRF_NOTIFYITEMDRAW;
case CDDS_ITEMPREPAINT:
return CDRF_NOTIFYSUBITEMDRAW;
case (CDDS_ITEMPREPAINT | CDDS_SUBITEM):
break;
default:
return CDRF_DODEFAULT;
}
DWORD nItem = pLVCD->nmcd.dwItemSpec;
2020-05-12 12:19:05 +00:00
wchar_t scriptName[MAX_PATH];
m_ScriptList.GetItemText(nItem, 0, scriptName, MAX_PATH);
2020-05-12 12:19:05 +00:00
INSTANCE_STATE state = m_Debugger->ScriptSystem()->GetInstanceState(stdstr("").FromUTF16(scriptName).c_str());
if (state == STATE_STARTED)
{
pLVCD->clrTextBk = RGB(0xFF, 0xFF, 0xAA);
}
else if (state == STATE_RUNNING)
{
pLVCD->clrTextBk = RGB(0xAA, 0xFF, 0xAA);
}
return CDRF_DODEFAULT;
2017-08-18 05:08:22 +00:00
}
2020-05-12 12:19:05 +00:00
void CDebugScripts::EvaluateInSelectedInstance(const char* code)
2017-08-18 05:08:22 +00:00
{
INSTANCE_STATE state = m_Debugger->ScriptSystem()->GetInstanceState(m_SelectedScriptName);
if (state == STATE_RUNNING || state == STATE_STARTED)
{
CScriptInstance* instance = m_Debugger->ScriptSystem()->GetInstance(m_SelectedScriptName);
//instance->EvalAsync(code);
instance->Eval(code);
}
2017-08-18 05:08:22 +00:00
}
// Console input
2018-01-18 06:53:07 +00:00
LRESULT CEditEval::OnKeyDown(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
2017-08-18 05:08:22 +00:00
{
if (wParam == VK_UP)
{
if (m_HistoryIdx > 0)
{
2020-05-12 12:19:05 +00:00
wchar_t* code = m_History[--m_HistoryIdx];
SetWindowText(code);
int selEnd = wcslen(code);
SetSel(selEnd, selEnd);
}
}
else if (wParam == VK_DOWN)
{
int size = m_History.size();
if (m_HistoryIdx < size - 1)
{
2020-05-12 12:19:05 +00:00
wchar_t* code = m_History[++m_HistoryIdx];
SetWindowText(code);
int selEnd = wcslen(code);
SetSel(selEnd, selEnd);
}
else if (m_HistoryIdx < size)
{
2020-05-12 12:19:05 +00:00
SetWindowText(L"");
m_HistoryIdx++;
}
}
else if (wParam == VK_RETURN)
{
if (m_ScriptWindow == NULL)
{
bHandled = FALSE;
return 0;
}
size_t codeLength = GetWindowTextLength() + 1;
2020-05-12 12:19:05 +00:00
wchar_t* code = (wchar_t*)malloc(codeLength * sizeof(wchar_t));
GetWindowText(code, codeLength);
2020-05-12 12:19:05 +00:00
m_ScriptWindow->EvaluateInSelectedInstance(stdstr().FromUTF16(code).c_str());
2020-05-12 12:19:05 +00:00
SetWindowText(L"");
int historySize = m_History.size();
// remove duplicate
for (int i = 0; i < historySize; i++)
{
2020-05-12 12:19:05 +00:00
if (wcscmp(code, m_History[i]) == 0)
{
free(m_History[i]);
m_History.erase(m_History.begin() + i);
historySize--;
break;
}
}
// remove oldest if maxed
if (historySize >= HISTORY_MAX_ENTRIES)
{
m_History.erase(m_History.begin() + 0);
historySize--;
}
m_History.push_back(code);
m_HistoryIdx = ++historySize;
}
bHandled = FALSE;
return 0;
2017-08-18 05:08:22 +00:00
}
void CDebugScripts::RunSelected()
{
INSTANCE_STATE state = m_Debugger->ScriptSystem()->GetInstanceState(m_SelectedScriptName);
if (state == STATE_INVALID || state == STATE_STOPPED)
{
m_Debugger->ScriptSystem()->RunScript(m_SelectedScriptName);
}
else
{
m_Debugger->Debug_LogScriptsWindow("[Error: Script is already running]\n");
}
2017-08-18 05:08:22 +00:00
}
void CDebugScripts::StopSelected()
{
2019-12-25 00:41:20 +00:00
m_Debugger->ScriptSystem()->StopScript(m_SelectedScriptName);
2019-12-25 00:41:20 +00:00
//m_Debugger->Debug_RefreshScriptsWindow();
2020-01-07 03:43:09 +00:00
}
void CDebugScripts::ToggleSelected()
{
INSTANCE_STATE state = m_Debugger->ScriptSystem()->GetInstanceState(m_SelectedScriptName);
if (state == STATE_INVALID || state == STATE_STOPPED)
{
RunSelected();
}
else
{
StopSelected();
}
}
void CDebugScripts::EditSelected()
{
2020-05-12 12:19:05 +00:00
ShellExecute(NULL, L"edit", stdstr(m_SelectedScriptName).ToUTF16().c_str(), NULL, L"Scripts", SW_SHOWNORMAL);
}