summaryrefslogtreecommitdiffstats
path: root/DTCallback.c
diff options
context:
space:
mode:
Diffstat (limited to 'DTCallback.c')
-rw-r--r--DTCallback.c116
1 files changed, 93 insertions, 23 deletions
diff --git a/DTCallback.c b/DTCallback.c
index 6e026b7..5e6fb3f 100644
--- a/DTCallback.c
+++ b/DTCallback.c
@@ -5,10 +5,12 @@ static const CallbackTarget_Bind = -1;
static const CallbackTarget_Global = -2;
static const CallbackTarget_Scenario = -3;
+// NOTE: fast callbacks (fast = true for ObjectCallback or DefinitionCallback) use ObjectCall/DefinitionCall directly for greater performance if possible (refs = 0 and GetLength(args) <= 8 for CallA()) and thus must be real functions of the desired object/definition. safe mode is ignored for fast callbacks
+
global func GlobalCallback(string name) { return [CallbackTarget_Global, name]; }
global func ScenarioCallback(string name) { return [CallbackTarget_Scenario, name]; }
-global func ObjectCallback(string name, object target) { return [target || this || FatalError("ObjectCallback without target object"), name]; }
-global func DefinitionCallback(string name, id target) { return [target || GetID() || FatalError("DefinitionCallback without target definition"), name]; }
+global func ObjectCallback(string name, object target, bool fast) { return [target || this || FatalError("ObjectCallback without target object"), name, fast]; }
+global func DefinitionCallback(string name, id target, bool fast) { return [target || GetID() || FatalError("DefinitionCallback without target definition"), name, fast]; }
global func Callback(string name, target) { return [target || this || GetID() || CallbackTarget_Global, name]; }
global func BindCallback(callback, array binding) { return [CallbackTarget_Bind, callback, binding]; }
@@ -50,19 +52,44 @@ global func CallA(callback, args, bool safe, array refs)
{
callback = [this, callback];
}
+
if(GetType(callback) != C4V_Array)
{
return _inherited(callback, args, ...);
}
- else
+
+ var target = callback[0], function = callback[1];
+
+ if((GetType(target) == C4V_C4Object || GetType(target) == C4V_C4ID) && GetLength(callback) == 3 && callback[2] && !refs && GetLength(args) <= 8) // fast callback
+ {
+ if(GetType(target) == C4V_C4Object)
+ {
+ return ObjectCall(target, function, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7]);
+ }
+ else if(GetType(target) == C4V_C4ID)
+ {
+ return DefinitionCall(target, function, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7]);
+ }
+ }
+
+ refs = refs || [];
+
+ if(target == CallbackTarget_Scenario)
+ {
+ return GameCall(function, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8]);
+ }
+ else if(target == CallbackTarget_Bind)
+ {
+ return CallA(function, BindArgs(callback[2], args, safe, refs), safe, refs);
+ }
+
+ if(GetType(target) == C4V_C4Object || GetType(target) == C4V_C4ID || target == CallbackTarget_Global)
{
- refs = refs || [];
var safeModifier = "";
if(safe)
{
safeModifier = "~";
}
- var target = callback[0], function = callback[1];
var argsStr = "", pos = 0;
for(var arg in args)
{
@@ -80,32 +107,35 @@ global func CallA(callback, args, bool safe, array refs)
}
++pos;
}
+
if(target == CallbackTarget_Global)
{
return GlobalEval(Format("%s(%s)", function, argsStr));
}
- else if(target == CallbackTarget_Scenario)
+ else if(GetType(target) == C4V_C4Object || GetType(target) == C4V_C4ID)
{
- return GameCall(function, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8]);
+ return eval(Format("%s->%s%s(%s)", Serialize(target), safeModifier, function, argsStr));
}
- else if(target == CallbackTarget_Bind)
+ }
+ else
+ {
+ if(this)
+ {
+ return this->~CallCustom(callback, args, ...);
+ }
+ else if(GetID())
{
- return CallA(callback[1], BindArgs(callback[2], args, safe, refs), safe, refs);
+ return GetID()->~CallCustom(callback, args, ...);
}
else
{
- if(GetType(target) == C4V_C4Object || GetType(target) == C4V_C4ID)
- {
- return eval(Format("%s->%s%s(%s)", Serialize(target), safeModifier, function, argsStr));
- }
- else
- {
- return (this && this->~CallCustom(callback, args, ...)) || ROCK->~CallCustom(callback, args, ...);
- }
+ return CallCustom(callback, args, ...);
}
}
}
+global func CallCustom() { return _inherited(...); }
+
global func BindArgs_ArgumentArrayPart(array binding, array args, bool safe)
{
var ret = args[binding[0]];
@@ -164,7 +194,18 @@ global func BindArgs(array binding, array args, bool safe, array& refs)
}
else if(GetType(bind[0]) == C4V_Int && bind[0] < 0)
{
- ret[pos] = BindCustomArgs(bind, args, safe);
+ if(this)
+ {
+ ret[pos] = this->~BindCustomArgs(bind, args, safe);
+ }
+ else if(GetID())
+ {
+ ret[pos] = GetID()->~BindCustomArgs(bind, args, safe);
+ }
+ else
+ {
+ ret[pos] = BindCustomArgs(bind, args, safe);
+ }
}
else
{
@@ -230,16 +271,32 @@ global func CheckCallback(callback)
}
else if(GetType(callback[0]) == C4V_C4ID || GetType(callback[0]) == C4V_C4Object)
{
- if(GetLength(callback) == 2 && GetType(callback[1]) == C4V_String && callback[1] != "")
+ if(GetLength(callback) == 2 || (GetLength(callback) == 3 && (!callback[2] || GetType(callback[2]) == C4V_Bool))) // length 2 for callbacks created by Callback() or Object/DefinitionCallback() before fast was introduced
{
- return true;
+ if(GetType(callback[1]) == C4V_String && callback[1] != "")
+ {
+ return true;
+ }
}
}
}
- return (this && this->~CheckCustomCallback(callback, ...)) || ROCK->~CheckCustomCallback(callback, ...);
+ if(this)
+ {
+ return this->~CheckCustomCallback(callback, ...);
+ }
+ else if(GetID())
+ {
+ return GetID()->~CheckCustomCallback(callback, ...);
+ }
+ else
+ {
+ return CheckCustomCallback(callback, ...);
+ }
}
+global func CheckCustomCallback() { return _inherited(...); }
+
global func CheckBindCallbackBinding(array binding)
{
for(var b in binding)
@@ -295,7 +352,20 @@ global func CheckBindCallbackBinding(array binding)
}
else if(GetType(b[0]) == C4V_Int && b[0] < 0)
{
- if(!CheckBindCallbackCustomBinding(b))
+ var ret;
+ if(this)
+ {
+ ret = this->~CheckBindCallbackCustomBinding(b);
+ }
+ else if(GetID())
+ {
+ ret = GetID()->~CheckBindCallbackCustomBinding(b);
+ }
+ else
+ {
+ ret = CheckBindCallbackCustomBinding(b);
+ }
+ if(!ret)
{
return false;
}
@@ -321,4 +391,4 @@ global func CheckBindCallbackBinding(array binding)
return true;
}
-global func CheckBindCallbackCustomBinding() { return _inherited(...); }
+global func CheckBindCallbackCustomBinding() { return _inherited(...); } \ No newline at end of file