diff options
Diffstat (limited to 'DTCallback.c')
| -rw-r--r-- | DTCallback.c | 116 |
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 |
