This commit is contained in:
romkazvo
2023-08-07 19:29:24 +08:00
commit 34d6c5d489
4832 changed files with 1389451 additions and 0 deletions

View File

@@ -0,0 +1,761 @@
// LUADBG.cpp : Defines the entry point for the application.
//
#include "stdafx.h"
#include "LUADBG.h"
#include "_TinyRegistry.h"
#include "_TinyFileEnum.h"
#include "_TinyBrowseFolder.h"
#include "AboutWnd.h"
#include <ICryPak.h>
#include <direct.h>
#ifndef WIN64
#include "Shlwapi.h"
#pragma comment (lib, "Shlwapi.lib")
#endif
_TINY_DECLARE_APP();
CLUADbg::CLUADbg()
{
m_pIScriptSystem = NULL;
m_pIPak = NULL;
m_pIVariable = NULL;
m_hRoot = NULL;
m_bDisabled = false;
m_pTreeToAdd = NULL;
}
CLUADbg::~CLUADbg()
{
_TinyRegistry cTReg;
_TinyVerify(cTReg.WriteNumber("Software\\Tiny\\LuaDebugger\\", "MainHorzSplitter", m_wndMainHorzSplitter.GetSplitterPos()));
_TinyVerify(cTReg.WriteNumber("Software\\Tiny\\LuaDebugger\\", "SrcEditSplitter", m_wndSrcEditSplitter.GetSplitterPos()));
_TinyVerify(cTReg.WriteNumber("Software\\Tiny\\LuaDebugger\\", "WatchSplitter", m_wndWatchSplitter.GetSplitterPos()));
_TinyVerify(cTReg.WriteNumber("Software\\Tiny\\LuaDebugger\\", "WatchCallstackSplitter", m_wndWatchCallstackSplitter.GetSplitterPos()));
_TinyVerify(cTReg.WriteNumber("Software\\Tiny\\LuaDebugger\\", "Fullscreen", ::IsZoomed(m_hWnd) ? 1 : 0));
}
TBBUTTON tbButtonsAdd [] =
{
{ 0, ID_DEBUG_RUN, TBSTATE_ENABLED, BTNS_BUTTON, { 0 }, 0L, 0 },
{ 1, ID_DEBUG_BREAK, 0, BTNS_BUTTON, { 0 }, 0L, 0 },
{ 2, ID_DEBUG_STOP, 0, BTNS_BUTTON, { 0 }, 0L, 0 },
{ 0, 0, TBSTATE_ENABLED, BTNS_SEP, { 0 }, 0L, 0 },
{ 3, ID_DEBUG_STEPINTO, TBSTATE_ENABLED, BTNS_BUTTON, { 0 }, 0L, 0 },
{ 4, ID_DEBUG_STEPOVER, TBSTATE_ENABLED, BTNS_BUTTON, { 0 }, 0L, 0 },
{ 5, ID_DEBUG_TOGGLEBREAKPOINT, TBSTATE_ENABLED, BTNS_BUTTON, { 0 }, 0L, 0 },
{ 6, ID_DEBUG_DISABLE, TBSTATE_ENABLED, BTNS_BUTTON, { 0 }, 0L, 0 },
{ 0, 0, TBSTATE_ENABLED, BTNS_SEP, { 0 }, 0L, 0 },
{ 7, IDM_ABOUT, TBSTATE_ENABLED, BTNS_BUTTON, { 0 }, 0L, 0 },
};
//! add a backslash if needed
inline void MyPathAddBackslash( char* szPath )
{
if(szPath[0]==0)
return;
size_t nLen = strlen(szPath);
if (szPath[nLen-1] == '\\')
return;
if (szPath[nLen-1] == '/')
{
szPath[nLen-1] = '\\';
return;
}
szPath[nLen] = '\\';
szPath[nLen+1] = '\0';
}
LRESULT CLUADbg::OnCreate(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
_TinyRect erect;
_TinyRect lrect;
_TinyRect wrect;
_TinyRegistry cTReg;
DWORD dwXOrigin=0,dwYOrigin=0,dwXSize=800,dwYSize=600;
if(cTReg.WriteNumber("Software\\Tiny\\LuaDebugger\\", "XOrigin",dwXOrigin))
{
cTReg.WriteNumber("Software\\Tiny\\LuaDebugger\\", "YOrigin",dwYOrigin);
cTReg.WriteNumber("Software\\Tiny\\LuaDebugger\\", "XSize",dwXSize);
cTReg.WriteNumber("Software\\Tiny\\LuaDebugger\\", "YSize",dwYSize);
}
SetWindowPos(dwXOrigin, dwYOrigin, dwXSize, dwYSize, SWP_NOZORDER | SWP_NOMOVE);
// TODO: Make sure fullscreen flag is loaded and used
// WS_MAXIMIZE
// DWORD dwFullscreen = 0;
// cTReg.ReadNumber("Software\\Tiny\\LuaDebugger\\", "Fullscreen", dwFullscreen);
// if (dwFullscreen == 1)
// ShowWindow(SW_MAXIMIZE);
CenterOnScreen();
GetClientRect(&wrect);
erect=wrect;
erect.top=0;
erect.bottom=32;
m_wToolbar.Create((ULONG_PTR) GetMenu(m_hWnd), WS_CHILD | WS_VISIBLE | TBSTYLE_TOOLTIPS, 0, &erect, this); //AMD Port
m_wToolbar.AddButtons(IDC_LUADBG, tbButtonsAdd, 10);
m_wndStatus.Create(0, NULL, this);
// Client area window
_TinyVerify(m_wndClient.Create(NULL, _T(""), WS_CHILD | WS_VISIBLE, 0, &wrect, this));
m_wndClient.NotifyReflection(TRUE);
// Splitter dividing source/file and watch windows
m_wndMainHorzSplitter.Create(&m_wndClient, NULL, NULL, true);
// Divides source and file view
m_wndSrcEditSplitter.Create(&m_wndMainHorzSplitter);
// Divides two watch windows
m_wndWatchSplitter.Create(&m_wndMainHorzSplitter);
// Divides the watch window and the cllstack
m_wndWatchCallstackSplitter.Create(&m_wndWatchSplitter);
// Add all scripts to the file tree
m_wFilesTree.Create(erect, &m_wndSrcEditSplitter, IDC_FILES);
char szRootPath[_MAX_PATH];
_getcwd(szRootPath, _MAX_PATH);
MyPathAddBackslash(szRootPath);
strcat(szRootPath, "SCRIPTS\\");
m_wFilesTree.ScanFiles(szRootPath);
_TinyVerify(m_wScriptWindow.Create(WS_VISIBLE | WS_CHILD | ES_WANTRETURN | WS_HSCROLL | WS_VSCROLL |
ES_AUTOHSCROLL | ES_AUTOVSCROLL | ES_MULTILINE, 0, &erect, &m_wndSrcEditSplitter));
m_wScriptWindow.SendMessage(EM_SETEVENTMASK,0,ENM_SCROLL);
m_wndFileViewCaption.Create("Scripts", &m_wFilesTree, &m_wndSrcEditSplitter);
m_wndSourceCaption.Create("Source", &m_wScriptWindow, &m_wndSrcEditSplitter);
m_wndSrcEditSplitter.SetFirstPan(&m_wndFileViewCaption);
m_wndSrcEditSplitter.SetSecondPan(&m_wndSourceCaption);
m_wLocals.Create(IDC_LOCALS,WS_CHILD|TVS_HASLINES|TVS_HASBUTTONS|TVS_LINESATROOT|WS_VISIBLE,WS_EX_CLIENTEDGE,&erect, &m_wndWatchSplitter);
m_wWatch.Create(IDC_WATCH,WS_CHILD|WS_VISIBLE|TVS_HASLINES|TVS_HASBUTTONS|TVS_LINESATROOT,WS_EX_CLIENTEDGE,&erect, &m_wndWatchSplitter);
m_wCallstack.Create(0,WS_CHILD|WS_VISIBLE|LVS_REPORT,WS_EX_CLIENTEDGE,&erect, &m_wndWatchSplitter);
m_wndLocalsCaption.Create("Locals", &m_wLocals, &m_wndWatchSplitter);
m_wndWatchCaption.Create("Watch", &m_wWatch, &m_wndWatchCallstackSplitter);
m_wndCallstackCaption.Create("Callstack", &m_wCallstack, &m_wndWatchCallstackSplitter);
m_wndWatchSplitter.SetFirstPan(&m_wndWatchCallstackSplitter);
m_wndWatchCallstackSplitter.SetFirstPan(&m_wndWatchCaption);
m_wndWatchCallstackSplitter.SetSecondPan(&m_wndCallstackCaption);
m_wndWatchSplitter.SetSecondPan(&m_wndLocalsCaption);
m_wndMainHorzSplitter.SetFirstPan(&m_wndSrcEditSplitter);
m_wndMainHorzSplitter.SetSecondPan(&m_wndWatchSplitter);
Reshape(wrect.right-wrect.left,wrect.bottom-wrect.top);
// Read splitter window locations from registry
DWORD dwVal;
cTReg.ReadNumber("Software\\Tiny\\LuaDebugger\\", "MainHorzSplitter", dwVal, 150);
m_wndMainHorzSplitter.SetSplitterPos(dwVal);
m_wndMainHorzSplitter.Reshape();
cTReg.ReadNumber("Software\\Tiny\\LuaDebugger\\", "SrcEditSplitter", dwVal, 190);
m_wndSrcEditSplitter.SetSplitterPos(dwVal);
m_wndSrcEditSplitter.Reshape();
cTReg.ReadNumber("Software\\Tiny\\LuaDebugger\\", "WatchSplitter", dwVal, wrect.right / 3 * 2);
m_wndWatchSplitter.SetSplitterPos(dwVal);
m_wndWatchSplitter.Reshape();
cTReg.ReadNumber("Software\\Tiny\\LuaDebugger\\", "WatchCallstackSplitter", dwVal, wrect.right / 3);
m_wndWatchCallstackSplitter.SetSplitterPos(dwVal);
m_wndWatchCallstackSplitter.Reshape();
m_wCallstack.InsertColumn(0, "Function", 108, 0);
m_wCallstack.InsertColumn(1, "Line", 40, 1);
m_wCallstack.InsertColumn(2, "File", 108, 2);
//_TinyVerify(LoadFile("C:\\MASTERCD\\SCRIPTS\\Default\\Entities\\PLAYER\\BasicPlayer.lua"));
//_TinyVerify(LoadFile("C:\\MASTERCD\\SCRIPTS\\Default\\Entities\\PLAYER\\player.lua"));
// _TINY_CHECK_LAST_ERROR
return 0;
}
bool CLUADbg::LoadFile(const char *pszFile, bool bForceReload)
{
FILE *hFile = NULL;
char *pszScript = NULL, *pszFormattedScript = NULL;
UINT iLength, iCmpBufPos, iSrcBufPos, iDestBufPos, iNumChars, iStrStartPos, iCurKWrd, i;
char szCmpBuf[2048];
bool bIsKeyWord;
string strLuaFormatFileName = "@";
char szMasterCD[_MAX_PATH];
// Create lua specific filename and check if we already have that file loaded
_getcwd(szMasterCD, _MAX_PATH);
if (strncmp(szMasterCD, pszFile, strlen(szMasterCD) - 1) == 0)
{
strLuaFormatFileName += &pszFile[strlen(szMasterCD) + 1];
for (i=0; i<strLuaFormatFileName.length(); i++)
if (strLuaFormatFileName[i] == '\\')
strLuaFormatFileName[i] = '/';
std::transform(strLuaFormatFileName.begin(), strLuaFormatFileName.end(),
strLuaFormatFileName.begin(), (int (*) (int)) tolower);
}
else
strLuaFormatFileName += pszFile;
if (bForceReload == false && m_wScriptWindow.GetSourceFile() == strLuaFormatFileName)
return true;
m_wScriptWindow.SetSourceFile(strLuaFormatFileName.c_str());
// hFile = fopen(pszFile, "rb");
hFile = m_pIPak->FOpen(pszFile, "rb");
if (!hFile)
return false;
// set filename in window title
{
char str[_MAX_PATH];
sprintf(str,"Lua Debugger [%s]",pszFile);
SetWindowText(str);
}
// Get file size
// fseek(hFile, 0, SEEK_END);
m_pIPak->FSeek(hFile, 0, SEEK_END);
// iLength = ftell(hFile);
iLength = m_pIPak->FTell(hFile);
// fseek(hFile, 0, SEEK_SET);
m_pIPak->FSeek(hFile, 0, SEEK_SET);
pszScript = new char [iLength + 1];
pszFormattedScript = new char [512 + iLength * 3];
// _TinyVerify(fread(pszScript, iLength, 1, hFile) == 1);
_TinyVerify(m_pIPak->FRead(pszScript, iLength, 1, hFile) == 1);
pszScript[iLength] = '\0';
_TinyAssert(strlen(pszScript) == iLength);
// RTF text, font Courier, green comments and blue keyword
strcpy(pszFormattedScript, "{\\rtf1\\ansi\\ansicpg1252\\deff0\\deflang1033" \
"{\\fonttbl{\\f0\\fmodern\\fprq1\\fcharset0 Courier(PS);}{\\f1\\fswiss\\fcharset0 Arial;}}" \
"{\\colortbl ;\\red0\\green0\\blue255;\\red0\\green128\\blue0;\\red160\\green160\\blue160;}\\f0\\fs20");
const char szKeywords[][32] =
{
"function",
"do",
"for",
"end",
"and",
"or",
"not",
"while",
"return",
"if",
"then",
"else",
"elseif",
"self",
"local",
"in",
"nil",
"repeat",
"until",
"break",
};
// Format text with syntax coloring
iDestBufPos = strlen(pszFormattedScript);
iSrcBufPos = 0;
while (pszScript[iSrcBufPos] != '\0')
{
// Scan next token
iNumChars = 1;
iStrStartPos = iSrcBufPos;
while (pszScript[iSrcBufPos] != ' ' &&
pszScript[iSrcBufPos] != '\n' &&
pszScript[iSrcBufPos] != '\r' &&
pszScript[iSrcBufPos] != '\t' &&
pszScript[iSrcBufPos] != '\0' &&
pszScript[iSrcBufPos] != '(' &&
pszScript[iSrcBufPos] != ')' &&
pszScript[iSrcBufPos] != '[' &&
pszScript[iSrcBufPos] != ']' &&
pszScript[iSrcBufPos] != '{' &&
pszScript[iSrcBufPos] != '}' &&
pszScript[iSrcBufPos] != ',' &&
pszScript[iSrcBufPos] != '.' &&
pszScript[iSrcBufPos] != ';' &&
pszScript[iSrcBufPos] != ':' &&
pszScript[iSrcBufPos] != '=' &&
pszScript[iSrcBufPos] != '==' &&
pszScript[iSrcBufPos] != '*' &&
pszScript[iSrcBufPos] != '+' &&
pszScript[iSrcBufPos] != '/' &&
pszScript[iSrcBufPos] != '~' &&
pszScript[iSrcBufPos] != '"')
{
iSrcBufPos++;
iNumChars++;
// Special treatment of '-' to allow parsing of '--'
if (pszScript[iSrcBufPos - 1] == '-' && pszScript[iSrcBufPos] != '-')
break;
}
if (iNumChars == 1)
iSrcBufPos++;
else
iNumChars--;
// Copy token and add escapes
iCmpBufPos = 0;
for (i=iStrStartPos; i<iStrStartPos + iNumChars; i++)
{
_TinyAssert(i - iStrStartPos < sizeof(szCmpBuf));
if (pszScript[i] == '{' || pszScript[i] == '}' || pszScript[i] == '\\')
{
// Add \ to mark it as non-escape character
szCmpBuf[iCmpBufPos++] = '\\';
szCmpBuf[iCmpBufPos++] = pszScript[i];
szCmpBuf[iCmpBufPos] = '\0';
}
else
{
szCmpBuf[iCmpBufPos++] = pszScript[i];
szCmpBuf[iCmpBufPos] = '\0';
}
}
// Comment
if (strncmp(szCmpBuf, "--", 2) == 0)
{
// Green
strcat(pszFormattedScript, "\\cf2 ");
iDestBufPos += 5;
strcpy(&pszFormattedScript[iDestBufPos], szCmpBuf);
iDestBufPos += strlen(szCmpBuf);
// Parse until newline
while (pszScript[iSrcBufPos] != '\n' && pszScript[iSrcBufPos] != '\0')
{
pszFormattedScript[iDestBufPos++] = pszScript[iSrcBufPos++];
}
iSrcBufPos++;
pszFormattedScript[iDestBufPos] = '\0';
// Add newline and restore color
strcat(pszFormattedScript, "\\par\n");
iDestBufPos += 5;
strcat(pszFormattedScript, "\\cf0 ");
iDestBufPos += 5;
continue;
}
// String
if (strncmp(szCmpBuf, "\"", 2) == 0)
{
// Gray
strcat(pszFormattedScript, "\\cf3 ");
iDestBufPos += 5;
strcpy(&pszFormattedScript[iDestBufPos], szCmpBuf);
iDestBufPos += strlen(szCmpBuf);
// Parse until end string / newline
while (pszScript[iSrcBufPos] != '\n' && pszScript[iSrcBufPos] != '\0' && pszScript[iSrcBufPos] != '"')
{
pszFormattedScript[iDestBufPos++] = pszScript[iSrcBufPos++];
}
iSrcBufPos++;
pszFormattedScript[iDestBufPos] = '\0';
// Add literal
strcat(pszFormattedScript, "\"");
iDestBufPos += 1;
// Restore color
strcat(pszFormattedScript, "\\cf0 ");
iDestBufPos += 5;
continue;
}
// Have we parsed a keyword ?
bIsKeyWord = false;
for (iCurKWrd=0; iCurKWrd<sizeof(szKeywords) / sizeof(szKeywords[0]); iCurKWrd++)
{
if (strcmp(szKeywords[iCurKWrd], szCmpBuf) == 0)
{
strcat(pszFormattedScript, "\\cf1 ");
strcat(pszFormattedScript, szKeywords[iCurKWrd]);
strcat(pszFormattedScript, "\\cf0 ");
iDestBufPos += 5 + 5 + strlen(szKeywords[iCurKWrd]);
bIsKeyWord = true;
}
}
if (bIsKeyWord)
continue;
if (strcmp(szCmpBuf, "\n") == 0)
{
// Newline
strcat(pszFormattedScript, "\\par ");
iDestBufPos += 5;
}
else
{
// Anything else, just append
iDestBufPos += strlen(szCmpBuf);
strcat(pszFormattedScript, szCmpBuf);
}
}
if (hFile)
// fclose(hFile);
m_pIPak->FClose(hFile);
if (pszScript)
{
delete [] pszScript;
pszScript = NULL;
}
/*
hFile = fopen("C:\\Debug.txt", "w");
fwrite(pszFormattedScript, 1, strlen(pszFormattedScript), hFile);
fclose(hFile);
*/
m_wScriptWindow.SetText(pszFormattedScript);
if (pszFormattedScript)
{
delete [] pszFormattedScript;
pszFormattedScript = NULL;
}
return true;
}
LRESULT CLUADbg::OnEraseBkGnd(HWND hWnd,UINT message, WPARAM wParam, LPARAM lParam)
{
return 1;
}
extern bool g_bDone; // From LuaDbgInterface.cpp
LRESULT CLUADbg::OnClose(HWND hWnd,UINT message, WPARAM wParam, LPARAM lParam)
{
// Quit();
WINDOWINFO wi;
if(::GetWindowInfo(m_hWnd,&wi))
{
_TinyRegistry cTReg;
_TinyVerify(cTReg.WriteNumber("Software\\Tiny\\LuaDebugger\\", "XOrigin", wi.rcWindow.left));
_TinyVerify(cTReg.WriteNumber("Software\\Tiny\\LuaDebugger\\", "YOrigin", wi.rcWindow.top));
_TinyVerify(cTReg.WriteNumber("Software\\Tiny\\LuaDebugger\\", "XSize", wi.rcWindow.right-wi.rcWindow.left));
_TinyVerify(cTReg.WriteNumber("Software\\Tiny\\LuaDebugger\\", "YSize", wi.rcWindow.bottom-wi.rcWindow.top));
}
g_bDone=true;
return 0;
}
LRESULT CLUADbg::OnSize(HWND hWnd,UINT message, WPARAM wParam, LPARAM lParam)
{
int w=LOWORD(lParam);
int h=HIWORD(lParam);
Reshape(w,h);
return 0;
}
LRESULT CLUADbg::OnAbout(HWND hWnd,UINT message, WPARAM wParam, LPARAM lParam)
{
CAboutWnd wndAbout;
wndAbout.DoModal(this);
return 0;
}
LRESULT CLUADbg::OnToggleBreakpoint(HWND hWnd,UINT message, WPARAM wParam, LPARAM lParam)
{
m_wScriptWindow.AddBreakpoint();
return 0;
}
#define TOOLBAR_HEIGHT 28
#define STATUS_BAR_HEIGHT 20
bool CLUADbg::Reshape(int w,int h)
{
/*
int nWatchHeight=(((float)h)*WATCH_HEIGHT_MULTIPLIER);
int nFilesWidth=(((float)h)*FILES_WIDTH_MULTIPLIER);
m_wScriptWindow.SetWindowPos(nFilesWidth,TOOLBAR_HEIGHT,w-nFilesWidth,h-TOOLBAR_HEIGHT-nWatchHeight,SWP_DRAWFRAME);
m_wLocals.SetWindowPos(0,h-nWatchHeight,w/2,nWatchHeight,SWP_DRAWFRAME);
m_wFilesTree.SetWindowPos(nFilesWidth,TOOLBAR_HEIGHT,nFilesWidth,h-TOOLBAR_HEIGHT-nWatchHeight,SWP_DRAWFRAME);
m_wWatch.SetWindowPos(w/2,h-nWatchHeight,w/2,nWatchHeight,SWP_DRAWFRAME);
*/
m_wndClient.Reshape(w, h - TOOLBAR_HEIGHT - STATUS_BAR_HEIGHT);
m_wndClient.SetWindowPos(0, TOOLBAR_HEIGHT, 0, 0, SWP_NOZORDER | SWP_NOSIZE);
m_wndMainHorzSplitter.Reshape(w, h - TOOLBAR_HEIGHT - STATUS_BAR_HEIGHT);
m_wToolbar.SetWindowPos(0,0,w,TOOLBAR_HEIGHT,0);
m_wndStatus.SetWindowPos(0, h - STATUS_BAR_HEIGHT, w, STATUS_BAR_HEIGHT, NULL);
return true;
}
void CLUADbg::PlaceLineMarker(UINT iLine)
{
m_wScriptWindow.SetLineMarker(iLine);
m_wScriptWindow.ScrollToLine(iLine);
}
void CLUADbg::SetStatusBarText(const char *pszText)
{
// TODO: Find out why setting the panel text using the
// dedicated message doesn't work. For some reason the
// text gets drawn once but never again.
// m_wndStatus.SetPanelText(pszText);
m_wndStatus.SetWindowText(pszText);
}
void CLUADbg::GetStackAndLocals()
{
///////////
// Stack //
///////////
{
IScriptObject *pICallstack = m_pIScriptSystem->GetCallsStack();
_SmartScriptObject pIEntry(m_pIScriptSystem, true);
const char *pszText = NULL;
int iItem=0;
m_wCallstack.Clear();
int i;
for (i=pICallstack->Count() - 1; i>=1; i--)
{
pICallstack->GetAt(i, pIEntry);
pIEntry->GetValue("description", pszText);
iItem = m_wCallstack.InsertItem(0, pszText, 0);
pIEntry->GetValue("line", pszText);
m_wCallstack.SetItemText(iItem, 1, pszText);
if (pIEntry->GetValue("sourcefile", pszText))
{
if (_stricmp(pszText, "=C") == 0)
m_wCallstack.SetItemText(iItem, 2, "Native C Function");
else
m_wCallstack.SetItemText(iItem, 2, &pszText[1]);
}
else
m_wCallstack.SetItemText(iItem, 2, "No Source");
}
if (pICallstack->Count() == 0)
iItem = m_wCallstack.InsertItem(0, "No Callstack Available", 0);
pICallstack->Release();
pICallstack = NULL;
}
////////////
// Locals //
////////////
m_wLocals.Clear();
m_pIVariable = m_pIScriptSystem->GetLocalVariables(1);
m_pTreeToAdd = &m_wLocals;
if (m_pIVariable)
{
m_hRoot = NULL;
m_iRecursionLevel = 0;
m_pIVariable->Dump((IScriptObjectDumpSink *) this);
m_pIVariable->Release();
m_pIVariable = NULL;
}
else
m_wLocals.AddItemToTree("No Locals Available");
m_pTreeToAdd = NULL;
///////////
// Watch //
///////////
const char *pszText = NULL;
m_wWatch.Clear();
IScriptObject *pIScriptObj = m_pIScriptSystem->GetLocalVariables(1);
string strWatchVar = "self";
bool bVarFound = false;
pIScriptObj->BeginIteration();
while (pIScriptObj->MoveNext())
{
if (pIScriptObj->GetCurrentKey(pszText))
{
if (strWatchVar == pszText)
{
_SmartScriptObject pIEntry(m_pIScriptSystem, true);
pIScriptObj->GetCurrent(pIEntry);
m_pIVariable = pIEntry;
m_pTreeToAdd = &m_wWatch;
if (m_pIVariable)
{
bVarFound = true;
m_hRoot = NULL;
m_iRecursionLevel = 0;
// Dump only works for tables, in case of values call the sink directly
if (m_pIVariable->GetCurrentType() == svtObject)
m_pIVariable->Dump((IScriptObjectDumpSink *) this);
else
{
m_pIVariable = pIScriptObj; // Value needs to be retrieved from parent table
OnElementFound(pszText, m_pIVariable->GetCurrentType());
}
// No AddRef() !
// m_pIVariable->Release();
m_pIVariable = NULL;
}
m_pTreeToAdd = NULL;
}
}
}
pIScriptObj->EndIteration();
if (!bVarFound)
m_wWatch.AddItemToTree(const_cast<LPSTR>((strWatchVar + " = ?").c_str())); // TODO: Cast...
}
HTREEITEM CLUADbg::AddVariableToTree(const char *sName, ScriptVarType type, HTREEITEM hParent)
{
char szBuf[2048];
char szType[32];
const char *pszContent = NULL;
bool bRetrieved = false;
int iIdx;
if (m_pTreeToAdd == NULL)
{
_TinyAssert(m_pTreeToAdd != NULL);
return 0;
}
switch (type)
{
case svtNull:
strcpy(szType, "[nil]");
break;
case svtString:
strcpy(szType, "[string]");
break;
case svtNumber:
strcpy(szType, "[numeric]");
break;
case svtFunction:
strcpy(szType, "[function]");
break;
case svtObject:
strcpy(szType, "[table]");
break;
case svtUserData:
strcpy(szType, "[user data]");
break;
default:
strcpy(szType, "[unknown]");
break;
}
if (type == svtString || type == svtNumber)
{
if (sName[0] == '[')
{
strcpy(szBuf, &sName[1]);
szBuf[strlen(szBuf) - 1] = '\0';
iIdx = atoi(szBuf);
bRetrieved = m_pIVariable->GetAt(iIdx, pszContent);
}
else
bRetrieved = m_pIVariable->GetValue(sName, pszContent);
if (bRetrieved)
sprintf(szBuf, "%s %s = %s", szType, sName, pszContent);
else
sprintf(szBuf, "%s %s = (Unknown)", szType, sName);
}
else
sprintf(szBuf, "%s %s", szType, sName);
HTREEITEM hNewItem = m_pTreeToAdd->AddItemToTree(szBuf, NULL, hParent);
TreeView_SortChildren(m_pTreeToAdd->m_hWnd, hNewItem, FALSE);
return hNewItem;
}
void CLUADbg::OnElementFound(const char *sName, ScriptVarType type)
{
HTREEITEM hRoot = NULL;
UINT iRecursionLevel = 0;
_SmartScriptObject pTable(m_pIScriptSystem, true);
IScriptObject *pIOldTbl = NULL;
HTREEITEM hOldRoot = NULL;
if(!sName)sName="[table idx]";
hRoot = AddVariableToTree(sName, type, m_hRoot);
if (type == svtObject && m_iRecursionLevel < 5)
{
if (m_pIVariable->GetValue(sName, pTable))
{
pIOldTbl = m_pIVariable;
hOldRoot = m_hRoot;
m_pIVariable = pTable;
m_hRoot = hRoot;
m_iRecursionLevel++;
pTable->Dump((IScriptObjectDumpSink *) this);
m_iRecursionLevel--;
m_pIVariable = pIOldTbl;
m_hRoot = hOldRoot;
}
}
}
void CLUADbg::OnElementFound(int nIdx,ScriptVarType type)
{
char szBuf[32];
sprintf(szBuf, "[%i]", nIdx);
OnElementFound(szBuf, type);
}