Chapter Listing
< 1 2 3 4 5 6 7 8 9 >
8) States
Have you ever heard of a
finite state machine? Well, it's just a fancy way to say that programs can behave differently depending on what state they're in, and that there's a limited number of states that a program can be in. Never mind the fancy terminology, it's really quite simple.
Let's take a real-world example again. A human can be said to have two main states -- awake, and asleep (or unconscious). When awake, a human will react to various stimuli in a particular way. When asleep, the very same stimuli might produce a different reaction. Yes, you guessed it -- the stimuli can be thought of as
events, and the reactions as
event handlers.
In LSL, there is a
default state, and then you can define your own additional states. When a script is saved, it always resets to the
default state. When a state is entered or exited, the
state_entry and
state_exit event handlers, respectively, are called. States are named, then followed by a code block. To change states, you just use the
state keyword, followed by the name of the new state.
Here is how a simple human might be programmed in LSL, supposing we could make up our own additional events/event handlers: (This example won't compile, as we can't create our own event handlers, but it illustrates the point nicely.)
default // the "birth" state :-)
{
state_entry()
{
llWhisper(0, "I'm alive!");
state awake; // change to the "awake" state
}
}
state awake
{
state_entry()
{
open_eyes();
}
on_hunger_pangs(integer starving)
{ // called when stomach growls (not a real LSL event)
eat();
}
on_getting_sleepy(float energyLeftPercentage)
{ // called periodically (not a real LSL event)
llWhisper(0, "*yawn*");
if (energyLeftPercentage <= 0.10)
{
state sleep;
}
}
}
state sleep
{
state_entry()
{
close_eyes();
llSetTimerEvent(60*60*7); // set timer for 7 hours
}
on_hunger_pangs(integer starving)
{
if (starving == TRUE)
{
state awake;
}
}
timer()
{ // when the timer expires...
state awake; // ...we wake up
}
}
Notice that our fake event "
on_hunger_pangs(integer starving)" behaves differently depending on our state. If awake, we eat whenever we are hungry. If asleep, we wait until we are starving before waking up. (I've left out the "
llSetTimer(0);" to keep it simple -- hardcore scripters can argue about this one endlessly if they like). You'll notice that we don't have to implement a handler in each state; we can ignore an event if we like by simply not implementing a handler for it.
Many scripts won't need anything other than the
default state, and you can make your own global state-indicating variable as an alternative, (For instance, by defining a variable named "
ON"", then checking to see if
ON is set to
TRUE or
FALSE when needed) but this can be both complicated and unnecessary. The support for states is already there, so if you need it, why not use it?
Previous |
Next
Homepage |
Tutorial |
CrashCourse |
Glossary