Thanks for your answer,
I do understand the process in more detail now, but there is still one point left that makes me uncertain. I quess its rather due to my design that a general AngelScript-issue, but I'll ask anyway, maybe you know an answer.
So In the registered SigClicked.Connect-method... thats where the problem lies really, SigClicked is just an instance of the variadic templates Signal-type (core::Signal<> SigClicked), I quess that would be ok for registration, but how am I supposed to store the asIScriptFunction for execution? I quess I could make it a free function instead:
void connectSigClicked(core::Signal<>& signal, asIScriptFunction* pFunction)
{
}
but the problem is, I have to prepare and execute as you said. Its not so much a problem how to get the script-engine (I'd store it as a namespace-nested "global" in the CPP-file where I register all those messages), but rather how to call those methods. signal would take a normal and a function pointer, that have to be called, thats not enough for executing the script function. Unfortunately it is not practical for me to modify any of eigther the signals, controller or widget classes - they should work independant of scripts as well, and I have about 30 widgets just now so e.g. giving a modified widget parent class is out of the question. The only thing I can think about now is to use my
method-wrapper-class:
Method* connectSigClicked(core::Signal<>& signal, asIScriptObject* pObject, asIScriptFunction* pFunction)
{
Method* pMethod = new script::Method(*pContext, *pObject, *pFunction);
signal.Connect(pMethod, &Method::Execute<>);
return pMethod;
}
Execute of the method-wrapper does just what you described, it prepares, sets the objects and parameters and then executes. Since the signal stores a pointer, I have to create it with dynamic allocation though, and therefore probably have to return it for the script to store and eigther manually release or using AngelScripts reference counting:
class Scene1 : IScene
{
Scene1()
{
@controller = loadController("Menu/HUD.axm");
Widget@ widget = controller.GetWidget("Overhead");
// Create a delegate object and connect it to the signal handler
@clickedMethod = widget.SigClicked.Connect(OnClickCallback(this.OnClick));
}
void OnClick()
{
}
GuiController@ controller;
Method@ clickedMethod;
}
Otherwise I'd have a nice big memory-leak, but having to create & store (and potentially manually destroy) such a useless pointer nevertheless for every signal is pretty inconvenient and prone to error. Do you see any easier solution?