12.3 Callback functions

Several Hollywood commands allow you to specify callback functions. Callback functions are normal Hollywood functions with the difference that they are not called by the script but by Hollywood commands. They are an integral part of Hollywood and make your program much more flexible. The whole button and event handler system in Hollywood relies heavily on callback functions. For example, if the user presses your button, then Hollywood will run the callback function you provided for that specific event. Callback functions are simply passed as normal arguments to the corresponding Hollywood commands.

An example of a Hollywood command that uses callback functions is the MakeButton() command. This command expects a table in the seventh parameter, which defines callback functions for the different events that can occur. Possible events for a button are OnMouseOver, OnMouseOut, OnMouseDown, OnMouseUp, OnRightMouseDown and OnRightMouseUp. If you simply want to react on a button press, use the OnMouseUp event. This event will be triggered when the user releases the left mouse button while the mouse pointer is still over the button. Here is an example:

 
MakeButton(1, #SIMPLEBUTTON, 0, 0, 100, 100, {OnMouseUp = p_MyFunc})

This command creates a new button with the identifier 1 and defines that the function p_MyFunc() shall be called, when the user presses this button. In this case, p_MyFunc() is a callback function. It will not be called by you but by Hollywood when the user presses the button. This works automatically. More precisely, the callback functions are actually called by the Hollywood command WaitEvent() which you should use in every script. The callback function itself could look like this now:

 
Function p_MyFunc()
    DebugPrint("Button 1 pressed!")
EndFunction

You could also place this function directly in the argument list of MakeButton(). This would look like this then:

 
MakeButton(1, #SIMPLEBUTTON, 0, 0, 100, 100, {OnMouseUp =
    Function() DebugPrint("Button 1 pressed!") EndFunction})

You see that Hollywood is very flexible. Remember that if you declare functions within an argument list of a call, you must not provide a function name because those functions are anonymous. So the following code would be invalid:

 
; invalid code!
MakeButton(1, #SIMPLEBUTTON, 0, 0, 100, 100, {OnMouseUp =
    Function p_MyFunc() DebugPrint("Button 1 pressed!") EndFunction})

Callback functions usually receive a message table in parameter 1. In the above example we did not fetch this message because we declared the function without any arguments. For the above code this is fine but imagine the following example:

 
MakeButton(1, #SIMPLEBUTTON, 0, 0, 100, 100, {OnMouseUp = p_MyFunc})
MakeButton(2, #SIMPLEBUTTON, 200, 0, 100, 100, {OnMouseUp = p_MyFunc})

Now we have declared two buttons but they both call the same function when the user presses them. The function p_MyFunc() needs to know now which button was pressed when it gets called. p_MyFunc() can find this out by looking at the message it receives in argument 1:

 
Function p_MyFunc(msg)
    If msg.id = 1
            DebugPrint("Button 1 pressed!")
    ElseIf msg.id = 2
            DebugPrint("Button 2 pressed!")
    EndIf
EndFunction

You see that p_MyFunc() checks the id-field of the message it got in argument 1 and so it can distinguish between button 1 and 2. Of course, you could extend that to any number of buttons. But there is more to look at. Consider the following situation:

 
evttable = {OnMouseUp = p_MyFunc, OnRightMouseUp = p_MyFunc}
MakeButton(1, #SIMPLEBUTTON, 0, 0, 100, 100, evttable)
MakeButton(2, #SIMPLEBUTTON, 200, 0, 100, 100, evttable)
MakeButton(3, #SIMPLEBUTTON, 400, 0, 100, 100, evttable)

Now we have declared three buttons and they all use the same event table. Thus Hollywood will call the same function for all of them. Furthermore, these buttons react on another event, namely OnRightMouseUp. Now p_MyFunc() needs to be able to distinguish not only between several buttons but also between different events. But that is no problem at all because the message passed to p_MyFunc() has another field from which you can read the event which caused the function call. Our p_MyFunc() function would look like this now:

 
Function p_MyFunc(msg)
    Switch msg.action
    Case "OnMouseUp":
            DebugPrint("Left mouse button pressed:", msg.id)
    Case "OnRightMouseUp":
            DebugPrint("Right mouse button pressed:", msg.id)
    EndSwitch
EndFunction

So you see that it is no problem to handle multiple buttons and events with the very same callback function. This increases the readability of your program a lot! There is much more to be discovered, so make sure you read the documentation about MakeButton() too.

If you want to be notified when the user closes or moves the window, you can install a callback function for that using InstallEventHandler(). The function you pass to this Hollywood command will then be called every time the user presses the window's close box or moves the window. But InstallEventHandler() supports more event types: You can also install a callback function that will be invoked if the user presses or releases a key and much more.

The Hollywood command SetInterval() also uses callback functions. The function passed to SetInterval() will be called again and again at the specified interval. This is useful if you want to make sure that your script runs at the same speed on every system. To realise this, simply use SetInterval() to tell Hollywood that it should run your callback function 25 times a second. So you can make sure that it does not run faster on faster machines. See SetInterval() for a good overview of the interval technique.

SetTimeout() is another example of a Hollywood command that works with callback function. You pass a function as well as a timeout value to SetTimeout(). Your callback function will then be called exactly after the specified time has elapsed. This is very useful for correct timing of your script, e.g. timing of your script with the music.

Last but not least, the Hollywood command CopyFile() accepts a function in the fourth parameter. This function will be called from time to time while CopyFile() is copying files. This is a difference to the callback functions of MakeButton(), SetInterval(), SetTimeout() etc. These are always called by WaitEvent() and not by the Hollywood command itself. CopyFile(), however, will call the specified function while it is running. So you could delete your callback function after CopyFile() is done (you can delete function by setting them to Nil). This is not possible with MakeButton() or SetInterval() because those functions just install the callbacks but they do not invoke them. This task is left to WaitEvent(). The callback function of CopyFile() is usually used to update a progress bar or abort the copy operation at any time. See CopyFile() for details.


Show TOC