Events and Callbacks
From OrbEdit Wiki
Events Overview
The bulk of Orb's scripts are driven by a system of Events and Callbacks. An Event is nothing more than a unique ID associated with a function (the Callback). There are 2 types of events within Orb:
- Static Event: Every Element has a set of static events it fires at certain times during its life. For example, all Elements have an OnLoad event that fires when the Element is first placed in the World.
- Dynamic Event: Certain methods in Orb take multiple frames to complete. When they do complete, they have the option to fire an Event ID, to indicate that they are done. For example, the
:moveto()method, which incrementally moves an Element to a specified location, can span many frames. One of the parameters to:moveto()is an Event ID to fire when the operation completes. This allows functions to be chained together in sequence. Consult the API Reference for details on these methods.
Static Events and Event Handlers
As mentioned above, every Element has a set of static events it can fire:
All Elements
- OnLoad: Fired when the Element is first added to the World.
- OnUnload: Fired when the Element is removed from the World.
- OnResize: Fired when the Element's size changes.
Shapes
- OnCollide: Fired whenever the Shape collides with another Shape. Any given collision will result in 2 OnCollide events being fired, since each collision involves 2 Shapes.
All Elements have a method named setEventHandler(name, handler) which is used to set their static events. This method takes 2 parameters: the name of the event to register, such as "OnLoad", and the Event Handler to run when it fires. An Event Handler is simply a script file that returns a function. Depending on the type of event being handled, that function must take a different set of parameters. For example, an Event Handler for the OnCollide event looks like this:
-- Events/NewOnCollide.lua return function(sender, collidee, contacts) -- OnCollide content goes here print("A collision!"); return true; end
The fact that this script returns a function allows parameters to be passed in to that function. In the case of OnCollide, sender is the Shape that collided, collidee is the Shape that was collided into, and contacts is a table with some information about the collision, such as where it happened and what direction the Shapes were going in.
Now, if you wish to set the above script as a Handler for an event, you would do something like:
-- Create a new Circle local myCircle = Circle:new(); -- Set a script to call when the Circle collides myCircle:setEventScript(orb.EVENT_TYPE.COLLIDE, "Events/NewOnCollide.lua");
OrbEdit takes care of this code whenever you set an Element's Event Handler from the Properties View. Just remember that Event Handlers must return a function in order to work correctly!
Dynamic Events and Event IDs
Event IDs are the glue that bind events to scripts. Let's start with a code example and work backwards. This example creates a Sprite and moves it to the right 500 pixels. When the move operation completes, it fires a dynamic Event ID, which calls a function to print "Sprite is done moving!".
-- First create a new Sprite local mover = Sprite:new(); -- Now we need to generate a unique Event ID with the orb.gueid() function. -- "gueid" stands for "generate unique event ID" and always returns a unique numerical ID local id = orb.gueid(); -- Now associate that ID with a function to call when the ID is fired. -- orb_set() takes 2 parameters: a function and an Event ID with which to associate that function orb_set(function(sender) print(sender:getName() .. " is done moving!"); return -1; end, id); -- Now move the Sprite 500 pixels to the right at the speed of 100 pixels/second. Pass in the Event ID from above -- to be fired when the move is complete mover:move(500, 0, 100, id);
This example is fundamental to how Orb scripting works so let's go over it again. To make a mapping from Event ID to a function, you must first have an Event ID, which can be gotten by calling orb.gueid(). The next step is to declare a function, which can be done anywhere. Now all you need to do is call orb_set() with your function and Event ID. Finally, pass your Event ID into one of Orb's many incremental methods and when that method completes, your function will be called. This type of event is called a dynamic event, since they can be dynamically created and destroyed.
- When an Element fires a dynamic Event ID it always passes itself along as a parameter. Thus, the function you register can know who called it.
Orb has a handful of functions that deal with Event IDs:
-
orb.gueid()Returns a unique Event ID to be fired later when an event occurs. -
orb_set(func, id)Associate the Lua function func with the event ID id. This association must be made before id is fired, otherwise no function will be called. -
orb_call(id, ...)Call the function associated with id with an arbitrary set of parameters. If no function is associated with id, nothing happens. -
orb_run(func, id, ...)Associate the Lua function func with the event ID id and call func immediately with an arbitrary set of parameters. No different than callingorb_set(func, id)andorb_call(id, ...). -
orb_cancel(id)Remove the association between id and all functions it may be associated with. If no such functions exist, nothing happens. -
orb_cancel_all()Remove all associations between all Event IDs and functions.
