Files
FC1/CrySystem/ScriptSink.cpp
romkazvo 34d6c5d489 123
2023-08-07 19:29:24 +08:00

336 lines
9.4 KiB
C++

////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2002.
// -------------------------------------------------------------------------
// File name: scriptsink.cpp
// Version: v1.00
// Created: 30/9/2002 by Timur.
// Compilers: Visual Studio.NET
// Description:
// -------------------------------------------------------------------------
// History:
//
////////////////////////////////////////////////////////////////////////////
#include "StdAfx.h"
#include "ScriptSink.h"
#include "System.h"
#include <IRenderer.h>
#include <I3DEngine.h>
#include <ISound.h>
#include <ILog.h>
#include <IConsole.h>
#include <ITimer.h>
#include <IGame.h>
#include <IAISystem.h> // AISystem
#include "XConsole.h"
//////////////////////////////////////////////////////////////////////////
CScriptSink::CScriptSink( CSystem *pSystem,CXConsole *pConsole)
{
assert( pSystem );
m_pSystem = pSystem;
m_pConsole = pConsole;
m_lastGCTime = 0;
m_fGCFreq = 10;
}
//////////////////////////////////////////////////////////////////////////
void CScriptSink::Init()
{
IScriptSystem *pScriptSystem = m_pSystem->GetIScriptSystem();
if (pScriptSystem)
{
// Set global time variable into the script.
pScriptSystem->SetGlobalValue( "_time", 0 );
pScriptSystem->SetGlobalValue( "_frametime",0 );
pScriptSystem->SetGlobalValue( "_aitick",0 );
m_nLastGCCount=pScriptSystem->GetCGCount();
}
else
m_nLastGCCount=0;
}
//////////////////////////////////////////////////////////////////////////
void CScriptSink::OnLoadSource(const char *sSourceName,unsigned char *sSource,long nSourceSize)
{
}
//////////////////////////////////////////////////////////////////////
void CScriptSink::OnScriptError(const char *sSourceFile,const char *sFuncName,int nLineNum,const char *sErrorDesc)
{
string sTemp;
int n=0;
if(nLineNum!=-1) // line no info?
{
m_pSystem->Warning( VALIDATOR_MODULE_SCRIPTSYSTEM,VALIDATOR_ERROR,VALIDATOR_FLAG_SCRIPT,sSourceFile,
"$3#SCRIPT ERROR File: %s, Line [%03d], Function: %s,\n%s",sSourceFile,nLineNum,sFuncName,sErrorDesc );
}
else
{
m_pSystem->Warning( VALIDATOR_MODULE_SCRIPTSYSTEM,VALIDATOR_ERROR,VALIDATOR_FLAG_SCRIPT,sSourceFile,
"$3#SCRIPT ERROR File: %s, Function: %s,\n%s",sSourceFile,sFuncName,sErrorDesc );
}
m_pSystem->GetILog()->Log("\001$6#Function %s ",sFuncName);
while(sErrorDesc[n]!=0)
{
if(sErrorDesc[n]=='\n')
{
m_pSystem->GetILog()->Log("\001$6# %s",sTemp.c_str());
sTemp="";
while(sErrorDesc[n]=='\n')n++;
}else{
sTemp+=sErrorDesc[n];
n++;
}
}
if(!sTemp.empty())
m_pSystem->GetILog()->LogError("\001$6# %s ",sTemp.c_str());
if (m_pSystem->GetLuaDebugger())
{
if (sSourceFile != NULL &&
_stricmp(sSourceFile, "__script_buffer__") != 0 &&
_stricmp(sSourceFile, "=C") != 0 &&
_stricmp(sSourceFile, "undefined") != 0 &&
nLineNum!=-1 &&
sSourceFile[0] != '\0')
{
// char szMessage[2048];
// sprintf(szMessage, "Lua runtime error found in '%s' line %03d function '%s' - open debugger ?",
// sSourceFile, nLineNum, sFuncName);
// if (MessageBox(NULL, szMessage, "Lua Runtime Error", MB_YESNO | MB_ICONERROR) == IDYES)
m_pSystem->ShowDebugger(sSourceFile, nLineNum, sErrorDesc);
}
}
}
void CScriptSink::OnLoadedScriptDump(const char *sScriptPath)
{
m_pSystem->GetILog()->Log(sScriptPath);
}
//////////////////////////////////////////////////////////////////////
bool CScriptSink::CanSetGlobal(const char *sVarName)
{
if (!m_pConsole)
{
m_pSystem->GetILog()->LogWarning("\001Attempt to change variable %s denied: no console system found", sVarName);
return false; // we can't change globals unless we have console
}
IGame*pGame = m_pSystem->GetIGame();
if (!pGame)
return true; // we may change whatever we want until we're not in the game
ICVar* pVar = m_pConsole->GetCVar(sVarName);
if (!pVar)
{
m_pSystem->GetILog()->Log("\001Attempt to change variable %s denied: no such variable found", sVarName);
return false; // we aren't allowed to change global that doesn't exist
}
int nFlags = pVar->GetFlags();
if((nFlags & VF_REQUIRE_NET_SYNC) && !pGame->GetModuleState(EGameServer) && pGame->GetModuleState(EGameClient))
{
m_pSystem->GetILog()->Log("\001Attempt to change variable %s on client denied:", sVarName);
m_pSystem->GetILog()->Log("\001The variable is Server-synchronized and the game is not server.");
return false;
}
if ((nFlags & VF_CHEAT) && (!m_pSystem->IsDevMode()))
{
// No Cheat Log. m_pSystem->GetILog()->Log("\001Variable %s is cheat protected.", sVarName);
return false;
}
if (nFlags & VF_READONLY)
{
m_pSystem->GetILog()->Log("\001Variable %s is read only.", sVarName);
return false;
}
return true;
}
//////////////////////////////////////////////////////////////////////
void CScriptSink::OnSetGlobal(const char *sVarName)
{
if (m_pConsole)
m_pConsole->RefreshVariable(sVarName);
}
//////////////////////////////////////////////////////////////////////
void CScriptSink::OnCollectUserData(INT_PTR nValue,int nCookie)
{
//m_Log.Log("OnCollectUserData %d", nValue);
switch(nCookie)
{
case USER_DATA_SOUND:
{
ISound *m_pISound;
m_pISound=(ISound *)nValue;
//m_pSystem->GetILog()->Log("collecting %s",m_pISound->GetName());
//::OutputDebugString(m_pISound->GetName());
//::OutputDebugString(" OnCollect USER_DATA_SOUND\n");
if(m_pISound)
m_pISound->Release();
}
break;
case USER_DATA_TEXTURE:
{
//::OutputDebugString("OnCollect USER_DATA_TEXTURE\n");
INT_PTR nTid=nValue;
IRenderer *pRenderer = m_pSystem->GetIRenderer();
if (pRenderer)
pRenderer->RemoveTexture(nTid);
}
break;
case USER_DATA_OBJECT:
{
//::OutputDebugString("OnCollect USER_DATA_OBJECT\n");
I3DEngine *p3DEngine = m_pSystem->GetI3DEngine();
IStatObj *pObj=(IStatObj *)nValue;
// if you have crash here - pObj is invalid pointer
// ( maybe attempt to use IStatObj pointer after I3DEngine::ClearRenderResources() )
// char chTest = pObj->GetFileName()[0];
if (p3DEngine)
p3DEngine->ReleaseObject(pObj);
}
break;
case USER_DATA_LIGHT:
{
//::OutputDebugString("OnCollect USER_DATA_LIGHT\n");
INT_PTR nLightId=nValue;
I3DEngine *p3DEngine = m_pSystem->GetI3DEngine();
if (p3DEngine)
p3DEngine->DeleteStaticLightSource(nLightId);
}
break;
default:
{
//m_Log.Log("OnCollectUserData WARINING unknown user data type %d [cookie=%d]", nValue,nCookie);
//if(m_pSystem->m_pGame)
// m_pSystem->m_pGame->OnCollectUserData(nValue,nCookie);
}
}
}
/////////////////////////////////////////////////////////////
//LUA DEBUGGER
/////////////////////////////////////////////////////////////
class ___Temp : public IScriptObjectDumpSink
{
void OnElementFound(int nIdx,ScriptVarType type){}
void OnElementFound(const char *sName,ScriptVarType type)
{
switch(type)
{
case svtNull:
//GetILog()->LogToConsole("<<NULL>> %s",sName);
break;
case svtString:
//GetILog()->LogToConsole("<<STRING>> %s",sName);
break;
case svtNumber:
//GetILog()->LogToConsole("<<NUMBER>> %s",sName);
break;
case svtFunction:
//GetILog()->LogToConsole("<<FUNCTION>> %s",sName);
break;
case svtObject:
//GetILog()->LogToConsole("<<OBJECT>> %s",sName);
break;
case svtUserData:
//GetILog()->LogToConsole("<<USERDATA>> %s",sName);
break;
}
}
};
//////////////////////////////////////////////////////////////////////////
void CScriptSink::OnExecuteLine(ScriptDebugInfo &sdiDebugInfo)
{
/*
___Temp temp;
IScriptObject *pLocals = m_pSystem->GetIScriptSystem()->GetLocalVariables();
m_pSystem->GetILog()->LogToConsole("START DUMP");
pLocals->Dump(&temp);
pLocals->Release();
*/
if (m_pSystem->GetLuaDebugger())
{
m_pSystem->ShowDebugger(sdiDebugInfo.sSourceName,
sdiDebugInfo.nCurrentLine, "Breakpoint Hit");
}
}
//////////////////////////////////////////////////////////////////////////
void CScriptSink::Update( bool bNoLuaGC )
{
ITimer *pTimer=m_pSystem->GetITimer();
float currTime=pTimer->GetCurrTime();
float frameTime=pTimer->GetFrameTime();
IScriptSystem *pScriptSystem = m_pSystem->GetIScriptSystem();
// Set global time variable into the script.
pScriptSystem->SetGlobalValue( "_time", currTime );
pScriptSystem->SetGlobalValue( "_frametime",frameTime );
{
int aiTicks = 0;
IAISystem *pAISystem=m_pSystem->GetAISystem();
if(pAISystem)
aiTicks = pAISystem->GetAITickCount();
pScriptSystem->SetGlobalValue( "_aitick",aiTicks );
}
// garbage-collect script-variables
pTimer->MeasureTime("PreLuaGC");
//TRACE("GC DELTA %d",m_pScriptSystem->GetCGCount()-nStartGC);
//int nStartGC = pScriptSystem->GetCGCount();
bool bKickIn=false; // Invoke Gargabe Collector
if(currTime-m_lastGCTime>m_fGCFreq) // g_GC_Frequence->GetIVal())
bKickIn=true;
int nGCCount=pScriptSystem->GetCGCount();
if(nGCCount-m_nLastGCCount>2000 && !bNoLuaGC) //
bKickIn=true;
if(bKickIn)
{
FRAME_PROFILER( "Lua GC",m_pSystem,PROFILE_SCRIPT );
//float fTimeBefore=pTimer->GetAsyncCurTime()*1000;
pScriptSystem->ForceGarbageCollection();
m_nLastGCCount=pScriptSystem->GetCGCount();
m_lastGCTime = currTime;
//float fTimeAfter=pTimer->GetAsyncCurTime()*1000;
//CryLog("--[after coll]GC DELTA %d ",pScriptSystem->GetCGCount()-nGCCount);
//TRACE("--[after coll]GC DELTA %d [time =%f]",m_pScriptSystem->GetCGCount()-nStartGC,fTimeAfter-fTimeBefore);
}
pTimer->MeasureTime("LuaGC");
}