Timeout-Scheduler

From Second Life Wiki
Revision as of 08:28, 4 December 2010 by Ochi Wolfe (talk | contribs)
Jump to navigation Jump to search
KBwarning.png Warning: This page and the script are currently under development and are not yet finished. Please use it with caution and check back later for updates.

What it is

Timeout-Scheduler is a function which provides a simple yet versatile tool for handling multiple independent timer events.

Some key ideas

  • Easy handling of multiple independent, asynchronous timeout events (for example dialog timeouts for multiple users).
  • One central function (in conjunction with a timer event) for getting, setting, modifying and removing timeout events.
  • The data associated with the timeout event can be fetched manually or when the timeout is due.
  • Hierarchical conditional selection of events, offering many possibilities to do things with very few function calls.

Short overview of the function

The sched() function takes two arguments:

  • time can take three different kinds of values with different meanings:
    • Positive values are used for setting new timeouts. The value is the time in seconds after which the timeout is triggered from within the timer event.
    • A value of 0 is used to remove an existing event (and fetching that event's data).
    • Any negative value may be used to retrieve the data associated with an existing event without deleting the event.
  • data is a list of data associated with the timeout event. It is used in two ways: Firstly, it is used to look up existing timeout events matching that data. Secondly, the given data is stored in the schedule when a new timeout event is created.

Creating simple timeout events

Try this to create a few simple timeout events:

<lsl> sched(1.8, ["Some other timeout"]); sched(2.5, ["Yet", "Another", "Timeout", "Event"]); sched(0.6, ["First timeout"]); </lsl>

This should trigger the three timeouts in the correct chronological order.

Implementation

<lsl> ////////// NOTES ///////////////////////

// Timeout-Scheduler v0.1.2-Dev (2010-12) by Ochi Wolfe

// You may use, change and distribute this code as you wish. // When distributing it in source form for others to use, please // include a note where it is from and what you have changed.

////////// VARIABLES ///////////////////

list schedule = [];

////////// FUNCTIONS ///////////////////

list sched(float time, list data) {

   integer LEN = 4;           // Max data length
   integer idx = -1;          // Selected timeout
   float   now = llGetTime(); // The current time
   list    res;               // Result data list
   // If data is given, select first matching timeout.
   // If data is empty, select next timeout that is due.
   if (data) {
       idx = llListFindList(schedule, data);
   } else {
       float til = llList2Float(schedule, 0);
       if ((til != 0.0) && (til <= now)) idx = 1;
   }
   // If a timeout was selected, fetch its data.
   // If time == 0.0, delete it afterwards.
   if (~idx) {
       res = llList2List(schedule, idx, idx+LEN-1);
       if (time == 0.0) schedule = llDeleteSubList(schedule, idx-1, idx+LEN-1);
   }
   // If time > 0.0, insert a new timeout event.
   // Fill data list to make its length consistent.
   if (time > 0.0) {
       integer len = llGetListLength(data); while (len++ < LEN) data += [0.0];
       schedule = llListSort([now+time] + data + schedule, LEN+1, TRUE);
   }
   // If next timeout is in the future, (re)start timer.
   // If there are no timeouts left, stop timer.
   // Otherwise, just leave the timer as it is.
   float til = llList2Float(schedule, 0);
   if      (til-now > 0.0) llSetTimerEvent(til-now);
   else if (til == 0.0)    llSetTimerEvent(0.0);
   return res;

}

////////// STATES //////////////////////

default {

   state_entry() {
   }
   timer() {
       list data;
       // Fetch and handle all timeouts that are due and delete them.
       while (data = sched(0, [])) {
           llOwnerSay("Timeout: " + llDumpList2String(data, ", "));
       }
   }

} </lsl>