Events
LSL is an event-driven language. Literally,
scripts are divided into
blocks of code that are triggered when a certain
event happens. Scripts can provide
event handlers, like
moving_end or
touch_start. If a script provides an event handler, and an event of this type occurs, the
simulator will add this event to the script's event
queue.
The script's event handlers will then be
called in the order the events are queued in (
FIFO). According to
Cory Linden, the event queue can hold up to 64 events. If the event queue is filled, it will silently drop any new events. Remember: LSL is not multi-threaded. Only one event will be run at a time; events cannot interupt each other. There is no way to interact with the event queue directly.
Changing
states clears the event queue. Different states can have different event handlers. Be wary of
bugs though. For instance, when an event handler is called, all of the arguments for that event handler are passed by value, and thus placed on the script's stack. If a script has insufficient memory to hold all of the arguments, the script is halted with a "stack/heap collision" error and no code in the event handler will run.
Unlike
functions, it's not possible for scripters to create our own custom event handlers. If you need to check whether or not something has occurred, and it's not covered by an existing event handler, you'll need to use the
timer() event.
The
function llMinEventDelay may be of some use in coordinating events.
Q: Wait, what's a "task"?
A: In LSL parlance, a task is an avatar/agent or an object. Both can collide with an object, though only objects can contain scripts. In the above list, you can generally take "task" to mean "the object containing the script".
Q: How do I get input from one event and act on that in another?
A: Use a global variable to store and recall the data. Global variables can be accessed and redefined from any event or state.
Q: How do I know which event is going to be triggered, and in what order? This is complicated!
A: It is, but you can get the hang of it pretty quickly. Say you have state_entry, on_rez and attach events in a script, and you attach the object from inventory. What's going to happen? Well, state_entry will already have triggered when the script first ran, so it's not that. on_rez always executes first, even if you attach it, so that's what will happen first. attach will happen afterwards, unless on_rez contains a state change, or something else to interrupt the state, such as llResetScript or llDie. See:
Example Event Order.
Q: Okay, but what about other events? How do I know when they'll be triggered?
A: As soon as something happens to trigger them, in the order that the event occurs in. So if you click on an object, you'll see touch_start, touch and touch_end, in that order. If the listen event is triggered while you're still touching the object, you'll get that after touch. It can be difficult to structure a script, if you need some input from a listen event, and some from touch_start, but you can use global variables to hold data between events.
Q: What's the different between an "event" and an "event handler"? I've seen both terms used, but they seem to both apply to the same thing.
A: Properly, an "event" is the thing that happens and an "event handler" is the thing that handles it. In practice, most scripters use the terms interchangably, or favour "event" over "event handler". This is technically incorrect, but is very common usage.
Q: Can events interrupt each other?
A: No, events are run to their completion, in the order that they were received. For example, if you have a while(TRUE); statement (a statement that never finishes executing) in your state_entry event, and someone touches the object (triggering a touch_start event) the touch_start event will never run, because the state_entry event never finishes.
Q: Why is there no event handler for "Release Keys" button?
A: Scratch what I said a moment ago. You meant the "Release Keys" button. I think the run_time_permissions event is triggered when permissions change, so just check the "perm" against PERMISSION_TAKE_CONTROLS to make sure if you still have it or not. - Aak
A2: That isn't quite correct, run_time_permissions is not called when permissions are released. If you want to know if permissions have been released you need to call the llGetPermissions - BW
Functions |
Constants