Generic callbacks
This guide will show you how you can declare a generic callback thanks to Codeware's reflection.
Requirements
You need Codeware (Nexus | Wiki) to use the following classes. It provides a Reflection module which is exactly what we need to make our callback in a generic way.
How to
We will declare two classes: Callback to use with methods of a class, and StaticCallback to use with static methods of a class.
Callback
Declaration
public class Callback extends DelayCallback {
private let m_target: wref<IScriptable>;
private let m_fn: CName;
private let m_data: array<Variant>;
public static func Create(target: wref<IScriptable>,
fn: CName,
opt data: array<Variant>) -> ref<Callback> {
let self = new Callback();
self.m_target = target;
self.m_fn = fn;
self.m_data = data;
return self;
}
public func Call() -> Variant {
if !IsDefined(this.m_target) {
return null;
}
return Reflection.GetClassOf(ToVariant(this.m_target))
.GetFunction(this.m_fn)
.Call(this.m_target, this.m_data);
}
public func Call(data: array<Variant>) -> Variant {
if !IsDefined(this.m_target) {
return null;
}
let args = this.m_data;
for item in data {
ArrayPush(args, item);
}
return Reflection.GetClassOf(ToVariant(this.m_target))
.GetFunction(this.m_fn)
.Call(this.m_target, args);
}
}We declare Callback which inherits DelayCallback. This way we can use Callback if we need it as-is, and we can also use it with DelaySystem.
We implement the method Call() which is expected by DelaySystem / DelayCallback. If we want to use it without DelaySystem, we simply need to call Call() when we want to execute a callback by ourself.
We return the result of the callback method as a Variant. User can convert the value by knowing the return type in advance, using FromVariant.
Example
StaticCallback
Declaration
This looks like Callback, we still inherits DelayCallback to be compatible with DelaySystem. But this time we only need a function's name.
Static methods of a class are registered as global functions. You'll need to use this syntax: n"ModuleName.ClassName::MethodName". Method must be declared with keyword cb. ModuleName is optional.
Example
This shows how it looks like when declaring in a custom module MyModule. It is not mandatory and you can declare it in the global scope.
Last updated
Was this helpful?