|
Página 3 de 9 LSL ESTADOS LSL proporciona el concepto de "estados" que los scripts pueden definir de muchas maneras. El principal estado es el default_state. Todos los scripts deben tener definido el defaul_state al comienzo, que es el primer estado que se ejecuta cuando el script comienza. Cuando un script es compilado, reseteado o cargado, entra al defaul_statet por defecto. Si se define otro estado antes del default_state, el compilador dará un error de sintaxis. Después de la definición del default_state , pueden definirse otros estados adicionales que determinan como se comportará el script en cada estado ante la llegada de eventos o entradas del exterior. Cada estado contendrá sus event-handlers que son activados por la máquina virtual LSL. Cada estado definido en el script debe contener por lo menos un event-handler -- en realidad no puede existir un state sin event-handlers. Si se declara un estado sin ningún event-handler el compilador dará un error de sintaxis. En LSL, los scripts están en standby hasta que reciben alguna entrada, o detectan algún cambio del exterior. En todo momento el script está en un estado determinado y reaccionará a los eventos o entradas de acuerdo con un esquema definido por el programador. Los estados se definen mediante la palabra clave state (ejemplo: state foo {...}) Como excepción el default state se declara mediante el uso de la palabra clave default a secas El cambio de estado dentro del script se hace mediante la directiva: state nombre-del-estado-nuevo (ejemplo: state default;). Cuando el intérprete llega a una declaración de cambio de estado (mediante la directiva state nombre-de-estado-nuevo): - el event-handler que contiene dicha declaración es inmediatamente finalizado
- se ejecuta el state_exit del estado que se abandona
- se abandona el estado actual
- se cambia al nuevo estado
- se ejecuta el state_entry del estado nuevo
Cuando hay un cambio de estado, todos los eventos que estaban pendientes en cola se borran, y todos los eventos que requieran de setup (a través de una función) son deshabilitados (timer, sensor y listen events). Nota: las versiones anteriores podían permitir que cuando un evento contenía un cambio de estado acabara hasta el final antes de cambiar al nuevo estado, pero ya no es así. State_entry El event-handler state_entry es llamado cada vez que se entra a un nuevo estado, y siempre es el primer event-handler tratado. No es posible pasar argumentos a este event-handler. Es un error común asumir que la state_entry se llama cuando un objeto es rezzed desde el inventario. Cuando un objeto se añade al inventario, el estado actual del script se guarda, así que no se llamará al state_entry durante el rez. Si se necesita el startup del codigo cada vez que se rezee un objeto, hay que crear una función global y llamarla desde state_entry y desde on_rez. integer listenHandle; // llListen() handle holder. // global initialization function. init() { // Remove the old listen callback: llListenRemove(listenHandle ); // Set up a listen callback for whoever owns this object. key owner = llGetOwner (); listenHandle = llListen( 0, "", owner, ""); } default { state_entry() { init(); } on_rez(integer start_param) { init(); } listen(integer channel, string name, key id, string message) { llSay(0, "Hi " + name + "! You own me."); } } State_exit El event-handler state_exit es llamado cada vez que se abandona un estado, y es el último event-handler tratado. Cada vez que se cambia de estado (mediante la directiva state nombre_de_estado_destino) sucede lo siguiente: - el event-handler que contiene dicha declaración es inmediatamente finalizado
- se ejecuta el state_exit del estado que se abandona
- se abandona el estado actual
- se cambia al nuevo estado
- se ejecuta el state_entry del estado nuevo
Es útil codificar un state_exit cuando se desee hacer cualquier trabajo de reseteo antes de abandonar el estado actual. // stupid stateful stopwatch default { // stopped touch_start( integer num_detected) { state start; // go, go, go! } } state start { state_entry() { llResetTime(); } touch_start( integer num_detected) { state default; // stop it } state_exit() { llSay(0, "Stopped after " + (string )llGetTime() + " seconds." ); } }
|