AddHook

BlitzMax Forums/BlitzMax Beginners Area/AddHook

Naughty Alien(Posted 2009) [#1]
..what this command is used for?? I couldnt find it in help file, but I saw it in few examples..what it does? Can someone explain it and eventually post some simple example just to get it on correct way..thanks..


Jesse(Posted 2009) [#2]
http://www.2dgamecreators.com/maxgui/T15-Eventhooks.html
it can be used for other things too, not just GUI.


SebHoll(Posted 2009) [#3]
Hooks are basically a BlitzMax system for managing callbacks. In short, callbacks provide a mechanism for getting your own project-specific functions called at key points in a program. A 'callback' is a name used to refer to any function that is called from an otherwise separate part of a program. They are extrememly useful when we are coding programs that use modal loops or wanting to handle situations where we need to run code immediately *as it happens*.

There are two types of hooks, which are available out-of-the-box (although more can be added, by third party modules etc.):

1. EmitEventHook
This hook allows you to set-up a callback whenever the EmitEvent() function is called (i.e. whenever a BlitzMax event is generated, whether it be a mouse move event by a Max2D graphics window, or a MaxGUI gadget event generated when a button is clicked). This allows you to receive and respond to events exactly as they happen, instead of you picking them out the event queue at a later point, typically once your event loop has finished its current cycle.

2. FlipEventHook
This hook allows you to set-up a callback for whenever the Flip() command is used to flip the buffers of your graphics context. I'm not really a game programmer, but I would imagine that this is very useful if ever you want to measure things like frames-per-second as the calculations can be calculated whenever the Flip command is called.

Ok, so let's say you would like a function we coded to be called whenever the mouse moves or a key is pressed. This is done using the AddHook() command. If you look at the docs, the AddHook() command takes four parameters - two of which are compulsary:

AddHook( id,func:Object( id,data:Object,context:Object ),context:Object=Null,priority=0 )
id: This is the constant that represents the type of hook we want (either FlipEventHook or EmitEventHook). In this case we want a function to be called whenever an event is emitted, so we will use the latter.

func:Object( id,data:Object,context:Object ): This tells us that AddHook is also expecting us to pass to it the function that we want to be called. It must accept the three parameters (id, data:Object, context:object) and return an Object. Bearing this in mind, let's code a suitable function now...

Function myEventHookFunction:Object( pID:Int, pData:Object, pContext:Object)
    '...
    Print "An event has been emitted."
    '...
    Return pData
    '...
EndFunction
As you can see, this function conforms to the specification required by AddHook. Now we have our function, we register it with EmitEventHook by calling:

AddHook EmitEventHook, myEventHookFunction
Now, whenever an event is emitted from anywhere in our program, the function myEventHookFunction() will be called (i.e. text will be printed to standard output). It is up to the specific hook type we are using to decide what it passes to the function as pData, but pID will be the constant of the hook type (in this case EmitEventHook) and pContext will point to the object that can be optionally specified as the third parameter in the AddHook call. As we didn't explicitly specify a context in our AddHook call, this will default to Null.

Hooks really are quite a big subject, but I've tried to give a brief general explanation of the concept of a hook. A fantastic tutorial concerning the use of hooks with MaxGUI events (including a full example) can be found here:

Tutorial 15: EventHooks (Edit: This is the same one Jesse has posted.)

I hope this helps.


Mark Tiffany(Posted 2009) [#4]
we really ought to get those maxgui tutorials added to the official maxgui package...


AdamRedwoods(Posted 2009) [#5]
Is it possible to extend EmitEventHook, so that you can create a new AddHook for exclusive id's, such as, MouseEventHook for mouse only events, or KeyEventHook for keyboard only events?

This way the function passed to AddHook doesn't need to check the id everytime? Or is it just good practice to check the ID all the time?


Naughty Alien(Posted 2009) [#6]
@SebHoll

Thank you A LOT..it was really useful post for me and I hope many other bmaxers...very nice...thanks guys..beautiful..i see use for this A LOT in my game..


degac(Posted 2009) [#7]
My stupidest example to understand (for me...) AddHookId, RunHooks ...

The (stupid) idea is: when you move the mouse Bmax creates an 'event' intercepeted by hook and run a specific function (myhook).
Of course in this example I could print mouse coordinates immediately in the MouseMoved() function...
Any better implementation?

I was thinking to different 'events' that can be useful to have out-of-the-box with BlitzMax, but at the moment I can think only to 'file-stream reading/writing/closing or copy/move a file events - Tprocess running/stopping...' (I don't know if these events can be useful or not...)


TaskMaster(Posted 2009) [#8]
Careful hooking the MouseMove event. The mouse can generate a crazy number of events in a very short time.


RustumScammell(Posted 2009) [#9]
@degac
Nice example! I think I finally understand hooks because of it! Yes!! I'd like to contribute a small correction though. The line:
If MouseX()<>oldx And MouseY()<>oldy

in the function MouseMoved() should read:
If MouseX()<>oldx Or MouseY()<>oldy 

to allow for any movement along either the x-axis OR the y-axis. Once I changed this it worked like a charm! I'm on my way to making my own hook functions. Awesome!