mirror of
https://github.com/mapbase-source/source-sdk-2013.git
synced 2024-12-28 07:45:29 +03:00
Added experimental static/global VScript hooks not tied to any particular class, starting with the integration of OnSave/OnRestore
This commit is contained in:
parent
ea7d1afa08
commit
29075a2c90
@ -835,6 +835,9 @@ static void FireGameEventLocal( const char* szEvent, HSCRIPT hTable )
|
|||||||
}
|
}
|
||||||
#endif // !CLIENT_DLL
|
#endif // !CLIENT_DLL
|
||||||
|
|
||||||
|
static ScriptHook_t g_Hook_OnSave;
|
||||||
|
static ScriptHook_t g_Hook_OnRestore;
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
// Save/Restore Utility
|
// Save/Restore Utility
|
||||||
// Based on L4D2 API
|
// Based on L4D2 API
|
||||||
@ -852,6 +855,9 @@ public: // IGameSystem
|
|||||||
{
|
{
|
||||||
if ( g_pScriptVM )
|
if ( g_pScriptVM )
|
||||||
{
|
{
|
||||||
|
g_Hook_OnSave.Call( NULL, NULL, NULL );
|
||||||
|
|
||||||
|
// Legacy hook
|
||||||
HSCRIPT hFunc = g_pScriptVM->LookupFunction( "OnSave" );
|
HSCRIPT hFunc = g_pScriptVM->LookupFunction( "OnSave" );
|
||||||
if ( hFunc )
|
if ( hFunc )
|
||||||
{
|
{
|
||||||
@ -870,6 +876,9 @@ public: // IGameSystem
|
|||||||
{
|
{
|
||||||
if ( g_pScriptVM )
|
if ( g_pScriptVM )
|
||||||
{
|
{
|
||||||
|
g_Hook_OnRestore.Call( NULL, NULL, NULL );
|
||||||
|
|
||||||
|
// Legacy hook
|
||||||
HSCRIPT hFunc = g_pScriptVM->LookupFunction( "OnRestore" );
|
HSCRIPT hFunc = g_pScriptVM->LookupFunction( "OnRestore" );
|
||||||
if ( hFunc )
|
if ( hFunc )
|
||||||
{
|
{
|
||||||
@ -3033,6 +3042,8 @@ void RegisterScriptSingletons()
|
|||||||
ScriptRegisterFunctionNamed( g_pScriptVM, CScriptSaveRestoreUtil::SaveTable, "SaveTable", "Store a table with primitive values that will persist across level transitions and save loads." );
|
ScriptRegisterFunctionNamed( g_pScriptVM, CScriptSaveRestoreUtil::SaveTable, "SaveTable", "Store a table with primitive values that will persist across level transitions and save loads." );
|
||||||
ScriptRegisterFunctionNamed( g_pScriptVM, CScriptSaveRestoreUtil::RestoreTable, "RestoreTable", "Retrieves a table from storage. Write into input table." );
|
ScriptRegisterFunctionNamed( g_pScriptVM, CScriptSaveRestoreUtil::RestoreTable, "RestoreTable", "Retrieves a table from storage. Write into input table." );
|
||||||
ScriptRegisterFunctionNamed( g_pScriptVM, CScriptSaveRestoreUtil::ClearSavedTable, "ClearSavedTable", "Removes the table with the given context." );
|
ScriptRegisterFunctionNamed( g_pScriptVM, CScriptSaveRestoreUtil::ClearSavedTable, "ClearSavedTable", "Removes the table with the given context." );
|
||||||
|
ScriptRegisterSimpleHook( g_pScriptVM, g_Hook_OnSave, "OnSave", FIELD_VOID, "Called when the game is saved." );
|
||||||
|
ScriptRegisterSimpleHook( g_pScriptVM, g_Hook_OnRestore, "OnRestore", FIELD_VOID, "Called when the game is restored." );
|
||||||
ScriptRegisterFunctionNamed( g_pScriptVM, CScriptReadWriteFile::FileWrite, "StringToFile", "Stores the string into the file" );
|
ScriptRegisterFunctionNamed( g_pScriptVM, CScriptReadWriteFile::FileWrite, "StringToFile", "Stores the string into the file" );
|
||||||
ScriptRegisterFunctionNamed( g_pScriptVM, CScriptReadWriteFile::FileRead, "FileToString", "Returns the string from the file, null if no file or file is too big." );
|
ScriptRegisterFunctionNamed( g_pScriptVM, CScriptReadWriteFile::FileRead, "FileToString", "Returns the string from the file, null if no file or file is too big." );
|
||||||
ScriptRegisterFunctionNamed( g_pScriptVM, CScriptReadWriteFile::KeyValuesWrite, "KeyValuesToFile", "Stores the CScriptKeyValues into the file" );
|
ScriptRegisterFunctionNamed( g_pScriptVM, CScriptReadWriteFile::KeyValuesWrite, "KeyValuesToFile", "Stores the CScriptKeyValues into the file" );
|
||||||
|
@ -755,6 +755,23 @@ static inline int ToConstantVariant(int value)
|
|||||||
pDesc->m_Hooks.AddToTail(pHook); \
|
pDesc->m_Hooks.AddToTail(pHook); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Static hooks (or "global" hooks) are not tied to specific classes
|
||||||
|
#define END_SCRIPTHOOK_STATIC( pVM ) \
|
||||||
|
pVM->RegisterHook( pHook ); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ScriptRegisterSimpleHook( pVM, hook, hookName, returnType, description ) \
|
||||||
|
if (!hook.m_bDefined) \
|
||||||
|
{ \
|
||||||
|
ScriptHook_t *pHook = &hook; \
|
||||||
|
pHook->m_desc.m_pszScriptName = hookName; pHook->m_desc.m_pszFunction = #hook; pHook->m_desc.m_ReturnType = returnType; pHook->m_desc.m_pszDescription = description; \
|
||||||
|
pVM->RegisterHook( pHook ); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ScriptRegisterConstant( pVM, constant, description ) ScriptRegisterConstantNamed( pVM, constant, #constant, description )
|
||||||
|
#define ScriptRegisterConstantNamed( pVM, constant, scriptName, description ) do { static ScriptConstantBinding_t binding; binding.m_pszScriptName = scriptName; binding.m_pszDescription = description; binding.m_data = ToConstantVariant(constant); pVM->RegisterConstant( &binding ); } while (0)
|
||||||
|
|
||||||
|
|
||||||
#define DEFINE_MEMBERVAR( varName, returnType, description ) \
|
#define DEFINE_MEMBERVAR( varName, returnType, description ) \
|
||||||
do { ScriptMemberDesc_t *pBinding = &((pDesc)->m_Members[(pDesc)->m_Members.AddToTail()]); pBinding->m_pszScriptName = varName; pBinding->m_pszDescription = description; pBinding->m_ReturnType = returnType; } while (0);
|
do { ScriptMemberDesc_t *pBinding = &((pDesc)->m_Members[(pDesc)->m_Members.AddToTail()]); pBinding->m_pszScriptName = varName; pBinding->m_pszDescription = description; pBinding->m_ReturnType = returnType; } while (0);
|
||||||
#endif
|
#endif
|
||||||
|
@ -43,6 +43,9 @@ extern ScriptClassDesc_t * GetScriptDesc( CBaseEntity * );
|
|||||||
extern int vscript_token;
|
extern int vscript_token;
|
||||||
int vscript_token_hack = vscript_token;
|
int vscript_token_hack = vscript_token;
|
||||||
|
|
||||||
|
// HACKHACK: VScript library relies on developer convar existing
|
||||||
|
ConVar developer( "developer", "1", 0, "Set developer message level." ); // developer mode
|
||||||
|
|
||||||
HSCRIPT VScriptCompileScript( const char *pszScriptName, bool bWarnMissing )
|
HSCRIPT VScriptCompileScript( const char *pszScriptName, bool bWarnMissing )
|
||||||
{
|
{
|
||||||
if ( !g_pScriptVM )
|
if ( !g_pScriptVM )
|
||||||
|
@ -2350,7 +2350,11 @@ ScriptStatus_t SquirrelVM::ExecuteFunction(HSCRIPT hFunction, ScriptVariant_t* p
|
|||||||
|
|
||||||
bool SquirrelVM::ScopeIsHooked( HSCRIPT hScope, const char *pszEventName )
|
bool SquirrelVM::ScopeIsHooked( HSCRIPT hScope, const char *pszEventName )
|
||||||
{
|
{
|
||||||
Assert( hScope && hScope != INVALID_HSCRIPT );
|
// For now, assume null scope (which is used for global hooks) is always hooked
|
||||||
|
if (!hScope)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
Assert(hScope != INVALID_HSCRIPT);
|
||||||
|
|
||||||
sq_pushroottable(vm_);
|
sq_pushroottable(vm_);
|
||||||
sq_pushstring(vm_, "Hooks", -1);
|
sq_pushstring(vm_, "Hooks", -1);
|
||||||
@ -2375,7 +2379,7 @@ bool SquirrelVM::ScopeIsHooked( HSCRIPT hScope, const char *pszEventName )
|
|||||||
|
|
||||||
HSCRIPT SquirrelVM::LookupHookFunction(const char *pszEventName, HSCRIPT hScope, bool &bLegacy)
|
HSCRIPT SquirrelVM::LookupHookFunction(const char *pszEventName, HSCRIPT hScope, bool &bLegacy)
|
||||||
{
|
{
|
||||||
HSCRIPT hFunc = LookupFunction( pszEventName, hScope );
|
HSCRIPT hFunc = hScope ? LookupFunction( pszEventName, hScope ) : nullptr;
|
||||||
if (hFunc)
|
if (hFunc)
|
||||||
{
|
{
|
||||||
bLegacy = true;
|
bLegacy = true;
|
||||||
@ -2421,7 +2425,11 @@ ScriptStatus_t SquirrelVM::ExecuteHookFunction(const char *pszEventName, HSCRIPT
|
|||||||
// TODO: Run in hook scope
|
// TODO: Run in hook scope
|
||||||
sq_pushroottable(vm_);
|
sq_pushroottable(vm_);
|
||||||
|
|
||||||
|
if (hScope)
|
||||||
sq_pushobject(vm_, *((HSQOBJECT*)hScope));
|
sq_pushobject(vm_, *((HSQOBJECT*)hScope));
|
||||||
|
else
|
||||||
|
sq_pushnull(vm_); // global hook
|
||||||
|
|
||||||
sq_pushstring(vm_, pszEventName, -1);
|
sq_pushstring(vm_, pszEventName, -1);
|
||||||
|
|
||||||
for (int i = 0; i < nArgs; ++i)
|
for (int i = 0; i < nArgs; ++i)
|
||||||
|
@ -122,8 +122,6 @@ class CSimpleCallChainer
|
|||||||
chain = null;
|
chain = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
local developer = (delete developer)()
|
|
||||||
|
|
||||||
//---------------------------------------------------------
|
//---------------------------------------------------------
|
||||||
// Hook handler
|
// Hook handler
|
||||||
//---------------------------------------------------------
|
//---------------------------------------------------------
|
||||||
@ -199,7 +197,26 @@ Hooks <-
|
|||||||
{
|
{
|
||||||
local firstReturn = null
|
local firstReturn = null
|
||||||
|
|
||||||
if ( scope in s_List )
|
if ( scope == null )
|
||||||
|
{
|
||||||
|
// null scope = global hook; call all scopes
|
||||||
|
vargv.insert(0,this)
|
||||||
|
foreach ( t in s_List )
|
||||||
|
{
|
||||||
|
if ( event in t )
|
||||||
|
{
|
||||||
|
foreach( context, callback in t[event] )
|
||||||
|
{
|
||||||
|
//printf( "(%.4f) Calling hook '%s' of context '%s' in static iteration\n", Time(), event, context )
|
||||||
|
|
||||||
|
local curReturn = callback.acall(vargv)
|
||||||
|
if (firstReturn == null)
|
||||||
|
firstReturn = curReturn
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( scope in s_List )
|
||||||
{
|
{
|
||||||
local t = s_List[scope]
|
local t = s_List[scope]
|
||||||
if ( event in t )
|
if ( event in t )
|
||||||
@ -236,22 +253,16 @@ Hooks <-
|
|||||||
//---------------------------------------------------------
|
//---------------------------------------------------------
|
||||||
__Documentation <- {}
|
__Documentation <- {}
|
||||||
|
|
||||||
local DocumentedFuncs
|
local developer = (delete developer)()
|
||||||
local DocumentedClasses
|
|
||||||
local DocumentedEnums
|
|
||||||
local DocumentedConsts
|
|
||||||
local DocumentedHooks
|
|
||||||
local DocumentedMembers
|
|
||||||
|
|
||||||
if (developer)
|
if (developer)
|
||||||
{
|
{
|
||||||
DocumentedFuncs = {}
|
local DocumentedFuncs = {}
|
||||||
DocumentedClasses = {}
|
local DocumentedClasses = {}
|
||||||
DocumentedEnums = {}
|
local DocumentedEnums = {}
|
||||||
DocumentedConsts = {}
|
local DocumentedConsts = {}
|
||||||
DocumentedHooks = {}
|
local DocumentedHooks = {}
|
||||||
DocumentedMembers = {}
|
local DocumentedMembers = {}
|
||||||
}
|
|
||||||
|
|
||||||
local function AddAliasedToTable(name, signature, description, table)
|
local function AddAliasedToTable(name, signature, description, table)
|
||||||
{
|
{
|
||||||
@ -271,9 +282,6 @@ local function AddAliasedToTable(name, signature, description, table)
|
|||||||
|
|
||||||
function __Documentation::RegisterHelp(name, signature, description)
|
function __Documentation::RegisterHelp(name, signature, description)
|
||||||
{
|
{
|
||||||
if ( !developer )
|
|
||||||
return
|
|
||||||
|
|
||||||
if (description.len() && description[0] == '#')
|
if (description.len() && description[0] == '#')
|
||||||
{
|
{
|
||||||
AddAliasedToTable(name, signature, description, DocumentedFuncs)
|
AddAliasedToTable(name, signature, description, DocumentedFuncs)
|
||||||
@ -286,25 +294,16 @@ function __Documentation::RegisterHelp(name, signature, description)
|
|||||||
|
|
||||||
function __Documentation::RegisterClassHelp(name, baseclass, description)
|
function __Documentation::RegisterClassHelp(name, baseclass, description)
|
||||||
{
|
{
|
||||||
if ( !developer )
|
|
||||||
return
|
|
||||||
|
|
||||||
DocumentedClasses[name] <- [baseclass, description];
|
DocumentedClasses[name] <- [baseclass, description];
|
||||||
}
|
}
|
||||||
|
|
||||||
function __Documentation::RegisterEnumHelp(name, num_elements, description)
|
function __Documentation::RegisterEnumHelp(name, num_elements, description)
|
||||||
{
|
{
|
||||||
if ( !developer )
|
|
||||||
return
|
|
||||||
|
|
||||||
DocumentedEnums[name] <- [num_elements, description];
|
DocumentedEnums[name] <- [num_elements, description];
|
||||||
}
|
}
|
||||||
|
|
||||||
function __Documentation::RegisterConstHelp(name, signature, description)
|
function __Documentation::RegisterConstHelp(name, signature, description)
|
||||||
{
|
{
|
||||||
if ( !developer )
|
|
||||||
return
|
|
||||||
|
|
||||||
if (description.len() && description[0] == '#')
|
if (description.len() && description[0] == '#')
|
||||||
{
|
{
|
||||||
AddAliasedToTable(name, signature, description, DocumentedConsts)
|
AddAliasedToTable(name, signature, description, DocumentedConsts)
|
||||||
@ -317,17 +316,11 @@ function __Documentation::RegisterConstHelp(name, signature, description)
|
|||||||
|
|
||||||
function __Documentation::RegisterHookHelp(name, signature, description)
|
function __Documentation::RegisterHookHelp(name, signature, description)
|
||||||
{
|
{
|
||||||
if ( !developer )
|
|
||||||
return
|
|
||||||
|
|
||||||
DocumentedHooks[name] <- [signature, description];
|
DocumentedHooks[name] <- [signature, description];
|
||||||
}
|
}
|
||||||
|
|
||||||
function __Documentation::RegisterMemberHelp(name, signature, description)
|
function __Documentation::RegisterMemberHelp(name, signature, description)
|
||||||
{
|
{
|
||||||
if ( !developer )
|
|
||||||
return
|
|
||||||
|
|
||||||
DocumentedMembers[name] <- [signature, description];
|
DocumentedMembers[name] <- [signature, description];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -457,12 +450,6 @@ local function PrintMatchesInDocList(pattern, list, printfunc)
|
|||||||
|
|
||||||
function __Documentation::PrintHelp(pattern = "*")
|
function __Documentation::PrintHelp(pattern = "*")
|
||||||
{
|
{
|
||||||
if ( !developer )
|
|
||||||
{
|
|
||||||
printdocl("Documentation is not enabled. To enable documentation, restart the server with the 'developer' cvar set to 1 or higher.");
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
local patternLower = pattern.tolower();
|
local patternLower = pattern.tolower();
|
||||||
|
|
||||||
// Have a specific order
|
// Have a specific order
|
||||||
@ -478,6 +465,21 @@ function __Documentation::PrintHelp(pattern = "*")
|
|||||||
printdocl("Pattern " + pattern + " not found");
|
printdocl("Pattern " + pattern + " not found");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
__Documentation.RegisterHelp <-
|
||||||
|
__Documentation.RegisterClassHelp <-
|
||||||
|
__Documentation.RegisterEnumHelp <-
|
||||||
|
__Documentation.RegisterConstHelp <-
|
||||||
|
__Documentation.RegisterHookHelp <-
|
||||||
|
__Documentation.RegisterMemberHelp <- dummy
|
||||||
|
|
||||||
|
function __Documentation::PrintHelp( pattern = null )
|
||||||
|
{
|
||||||
|
printcl(200, 224, 255, "Documentation is not enabled. To enable documentation, restart the server with the 'developer' cvar set to 1 or higher.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Vector documentation
|
// Vector documentation
|
||||||
__Documentation.RegisterClassHelp( "Vector", "", "Basic 3-float Vector class." );
|
__Documentation.RegisterClassHelp( "Vector", "", "Basic 3-float Vector class." );
|
||||||
|
Loading…
Reference in New Issue
Block a user