mirror of
https://github.com/mapbase-source/source-sdk-2013.git
synced 2024-12-27 15:25:30 +03:00
Revisited hook handler based on suggestions and new information
This commit is contained in:
parent
38be2ca932
commit
c37f8eefb7
@ -889,6 +889,11 @@ public:
|
|||||||
// External enums
|
// External enums
|
||||||
//--------------------------------------------------------
|
//--------------------------------------------------------
|
||||||
virtual void RegisterEnum( ScriptEnumDesc_t *pEnumDesc ) = 0;
|
virtual void RegisterEnum( ScriptEnumDesc_t *pEnumDesc ) = 0;
|
||||||
|
|
||||||
|
//--------------------------------------------------------
|
||||||
|
// External hooks
|
||||||
|
//--------------------------------------------------------
|
||||||
|
virtual void RegisterHook( ScriptHook_t *pHookDesc ) = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//--------------------------------------------------------
|
//--------------------------------------------------------
|
||||||
|
@ -187,6 +187,11 @@ public:
|
|||||||
// External enums
|
// External enums
|
||||||
//--------------------------------------------------------
|
//--------------------------------------------------------
|
||||||
virtual void RegisterEnum(ScriptEnumDesc_t *pEnumDesc) override;
|
virtual void RegisterEnum(ScriptEnumDesc_t *pEnumDesc) override;
|
||||||
|
|
||||||
|
//--------------------------------------------------------
|
||||||
|
// External hooks
|
||||||
|
//--------------------------------------------------------
|
||||||
|
virtual void RegisterHook(ScriptHook_t *pHookDesc) override;
|
||||||
|
|
||||||
//--------------------------------------------------------
|
//--------------------------------------------------------
|
||||||
// External instances. Note class will be auto-registered.
|
// External instances. Note class will be auto-registered.
|
||||||
@ -2299,7 +2304,7 @@ HSCRIPT SquirrelVM::LookupHookFunction(const char *pszEventName, HSCRIPT hScope,
|
|||||||
sq_pushroottable(vm_);
|
sq_pushroottable(vm_);
|
||||||
sq_pushstring(vm_, "Hooks", -1);
|
sq_pushstring(vm_, "Hooks", -1);
|
||||||
sq_get(vm_, -2);
|
sq_get(vm_, -2);
|
||||||
sq_pushstring(vm_, "CallHooks", -1);
|
sq_pushstring(vm_, "Call", -1);
|
||||||
sq_get(vm_, -2);
|
sq_get(vm_, -2);
|
||||||
|
|
||||||
HSQOBJECT obj;
|
HSQOBJECT obj;
|
||||||
@ -2328,8 +2333,8 @@ ScriptStatus_t SquirrelVM::ExecuteHookFunction(const char *pszEventName, HSCRIPT
|
|||||||
// TODO: Run in hook scope
|
// TODO: Run in hook scope
|
||||||
sq_pushroottable(vm_);
|
sq_pushroottable(vm_);
|
||||||
|
|
||||||
sq_pushstring(vm_, pszEventName, -1);
|
|
||||||
sq_pushobject(vm_, *((HSQOBJECT*)hScope));
|
sq_pushobject(vm_, *((HSQOBJECT*)hScope));
|
||||||
|
sq_pushstring(vm_, pszEventName, -1);
|
||||||
|
|
||||||
for (int i = 0; i < nArgs; ++i)
|
for (int i = 0; i < nArgs; ++i)
|
||||||
{
|
{
|
||||||
@ -2602,6 +2607,17 @@ void SquirrelVM::RegisterEnum(ScriptEnumDesc_t* pEnumDesc)
|
|||||||
RegisterEnumDocumentation(vm_, pEnumDesc);
|
RegisterEnumDocumentation(vm_, pEnumDesc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SquirrelVM::RegisterHook(ScriptHook_t* pHookDesc)
|
||||||
|
{
|
||||||
|
SquirrelSafeCheck safeCheck(vm_);
|
||||||
|
Assert(pHookDesc);
|
||||||
|
|
||||||
|
if (!pHookDesc)
|
||||||
|
return;
|
||||||
|
|
||||||
|
RegisterHookDocumentation(vm_, pHookDesc, pHookDesc->m_desc, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
HSCRIPT SquirrelVM::RegisterInstance(ScriptClassDesc_t* pDesc, void* pInstance, bool bAllowDestruct)
|
HSCRIPT SquirrelVM::RegisterInstance(ScriptClassDesc_t* pDesc, void* pInstance, bool bAllowDestruct)
|
||||||
{
|
{
|
||||||
SquirrelSafeCheck safeCheck(vm_);
|
SquirrelSafeCheck safeCheck(vm_);
|
||||||
|
@ -125,89 +125,107 @@ class CSimpleCallChainer
|
|||||||
//---------------------------------------------------------
|
//---------------------------------------------------------
|
||||||
// Hook handler
|
// Hook handler
|
||||||
//---------------------------------------------------------
|
//---------------------------------------------------------
|
||||||
Hooks <- { Registered = {} }
|
local s_List = {}
|
||||||
|
|
||||||
function Hooks::Add( scope, event, func, name )
|
Hooks <-
|
||||||
{
|
{
|
||||||
Hooks.Registered[name] <- [event, scope, func];
|
// table, string, closure, string
|
||||||
}
|
function Add( scope, event, callback, context )
|
||||||
|
|
||||||
function Hooks::Remove( name )
|
|
||||||
{
|
|
||||||
Hooks.Registered.rawdelete(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
function Hooks::ScopeHookedToEvent( scope, event )
|
|
||||||
{
|
|
||||||
//printl("Running ScopeHookedToEvent()")
|
|
||||||
foreach (elem in Hooks.Registered)
|
|
||||||
{
|
{
|
||||||
if (elem[1] == scope && elem[0] == event)
|
if ( typeof callback != "function" )
|
||||||
return true
|
throw "invalid callback param"
|
||||||
|
|
||||||
|
if ( !(scope in s_List) )
|
||||||
|
s_List[scope] <- {}
|
||||||
|
|
||||||
|
local t = s_List[scope]
|
||||||
|
|
||||||
|
if ( !(event in t) )
|
||||||
|
t[event] <- {}
|
||||||
|
|
||||||
|
t[event][context] <- callback
|
||||||
}
|
}
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
function Hooks::CallHooks(event, scope, ...)
|
function Remove( context, event = null )
|
||||||
{
|
|
||||||
//printl("vargv.len() = " + vargv.len())
|
|
||||||
switch (vargv.len())
|
|
||||||
{
|
{
|
||||||
case 0:
|
if ( event )
|
||||||
foreach (elem in Hooks.Registered)
|
{
|
||||||
|
foreach( k,scope in s_List )
|
||||||
{
|
{
|
||||||
if (elem[0] == event && elem[1] == scope)
|
if ( event in scope )
|
||||||
return elem[2]()
|
{
|
||||||
}
|
local t = scope[event]
|
||||||
break;
|
if ( context in t )
|
||||||
|
{
|
||||||
|
delete t[context]
|
||||||
|
}
|
||||||
|
|
||||||
case 1:
|
// cleanup?
|
||||||
foreach (elem in Hooks.Registered)
|
if ( !t.len() )
|
||||||
{
|
delete scope[event]
|
||||||
if (elem[0] == event && elem[1] == scope)
|
}
|
||||||
return elem[2](vargv[0])
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 2:
|
// cleanup?
|
||||||
foreach (elem in Hooks.Registered)
|
if ( !scope.len() )
|
||||||
{
|
delete s_List[k]
|
||||||
if (elem[0] == event && elem[1] == scope)
|
|
||||||
return elem[2](vargv[0], vargv[1])
|
|
||||||
}
|
}
|
||||||
break;
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
foreach( k,scope in s_List )
|
||||||
|
{
|
||||||
|
foreach( kk,ev in scope )
|
||||||
|
{
|
||||||
|
if ( context in ev )
|
||||||
|
{
|
||||||
|
delete ev[context]
|
||||||
|
}
|
||||||
|
|
||||||
case 3:
|
// cleanup?
|
||||||
foreach (elem in Hooks.Registered)
|
if ( !ev.len() )
|
||||||
{
|
delete scope[kk]
|
||||||
if (elem[0] == event && elem[1] == scope)
|
}
|
||||||
return elem[2](vargv[0], vargv[1], vargv[2])
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 4:
|
// cleanup?
|
||||||
foreach (elem in Hooks.Registered)
|
if ( !scope.len() )
|
||||||
{
|
delete s_List[k]
|
||||||
if (elem[0] == event && elem[1] == scope)
|
|
||||||
return elem[2](vargv[0], vargv[1], vargv[2], vargv[3])
|
|
||||||
}
|
}
|
||||||
break;
|
}
|
||||||
|
}
|
||||||
|
|
||||||
case 5:
|
function Call( scope, event, ... )
|
||||||
foreach (elem in Hooks.Registered)
|
{
|
||||||
{
|
local firstReturn = null
|
||||||
if (elem[0] == event && elem[1] == scope)
|
|
||||||
return elem[2](vargv[0], vargv[1], vargv[2], vargv[3], vargv[4])
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 6:
|
if ( scope in s_List )
|
||||||
foreach (elem in Hooks.Registered)
|
{
|
||||||
|
local t = s_List[scope]
|
||||||
|
if ( event in t )
|
||||||
{
|
{
|
||||||
if (elem[0] == event && elem[1] == scope)
|
foreach( context, callback in t[event] )
|
||||||
return elem[2](vargv[0], vargv[1], vargv[2], vargv[3], vargv[4], vargv[5])
|
{
|
||||||
|
printf( "(%.4f) Calling hook '%s' of context '%s'\n", Time(), event, context )
|
||||||
|
vargv.insert(0,scope)
|
||||||
|
|
||||||
|
local curReturn = callback.acall(vargv)
|
||||||
|
if (firstReturn == null)
|
||||||
|
firstReturn = curReturn
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
}
|
||||||
|
|
||||||
|
return firstReturn
|
||||||
|
}
|
||||||
|
|
||||||
|
function ScopeHookedToEvent( scope, event )
|
||||||
|
{
|
||||||
|
if ( scope in s_List )
|
||||||
|
{
|
||||||
|
if (event in s_List[scope])
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user