Difference between revisions of "Timeout-Scheduler"

From Second Life Wiki
Jump to navigation Jump to search
m (doesn't work that way in LSO)
Line 28: Line 28:


<lsl>
<lsl>
sched(2, ["Some other timeout"]);
sched(2, ["Some Other Timeout"]);
sched(3, ["Yet", "Another", "Timeout", "Event"]);
sched(3, ["Yet", "Another", "Timeout"]);
sched(1, ["First timeout"]);
sched(1, ["First", "Timeout"]);
</lsl>
</lsl>


Line 40: Line 40:
////////// NOTES ///////////////////////
////////// NOTES ///////////////////////


// Timeout-Scheduler v0.1.4-Dev (2010-12-04) by Ochi Wolfe
// Timeout-Scheduler v0.1.5-Dev (2010-12-06) by Ochi Wolfe


// You may use, change and distribute this code as you wish.
// You may use, change and distribute this code as you wish.
Line 53: Line 53:


list sched(integer time, list data) {
list sched(integer time, list data) {
     integer LEN = 4;              // Max data length
     integer LEN = 3;              // Max data length
     integer idx = -1;              // Selected timeout
     integer idx = -1;              // Selected timeout
     integer now = llGetUnixTime(); // The current time
     integer now = llGetUnixTime(); // The current time
Line 60: Line 60:
     // If data is given, select first matching timeout.
     // If data is given, select first matching timeout.
     // If data is empty, select next timeout that is due.
     // If data is empty, select next timeout that is due.
     if (data != []) {
     if (data) {
         idx = llListFindList(schedule, data);
         idx = llListFindList(schedule, [0] + data);
     } else {
     } else {
         integer til = llList2Integer(schedule, 0);
         integer til = llList2Integer(schedule, 0);
Line 70: Line 70:
     // If time == 0, delete it afterwards.
     // If time == 0, delete it afterwards.
     if (~idx) {
     if (~idx) {
         res = llList2List(schedule, idx, idx+LEN-1);
         res = llList2List(schedule, idx+1, idx+LEN);
         if (!time) schedule = llDeleteSubList(schedule, idx-1, idx+LEN-1);
         if (!time) schedule = llDeleteSubList(schedule, idx-1, idx+LEN);
     }
     }


Line 78: Line 78:
     if (time > 0) {
     if (time > 0) {
         integer len = LEN+1-llGetListLength(data); while (--len) data += [0];
         integer len = LEN+1-llGetListLength(data); while (--len) data += [0];
         schedule = llListSort([now+time] + data + schedule, LEN+1, TRUE);
         schedule = llListSort([now+time, 0] + data + schedule, LEN+2, TRUE);
     }
     }



Revision as of 15:05, 6 December 2010

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(2, ["Some Other Timeout"]); sched(3, ["Yet", "Another", "Timeout"]); sched(1, ["First", "Timeout"]); </lsl>

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

Implementation

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

// Timeout-Scheduler v0.1.5-Dev (2010-12-06) 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(integer time, list data) {

   integer LEN = 3;               // Max data length
   integer idx = -1;              // Selected timeout
   integer now = llGetUnixTime(); // 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, [0] + data);
   } else {
       integer til = llList2Integer(schedule, 0);
       if (til && (til <= now)) idx = 1;
   }
   // If a timeout was selected, fetch its data.
   // If time == 0, delete it afterwards.
   if (~idx) {
       res = llList2List(schedule, idx+1, idx+LEN);
       if (!time) schedule = llDeleteSubList(schedule, idx-1, idx+LEN);
   }
   // If time > 0, insert a new timeout event.
   // Fill data list to make its length consistent.
   if (time > 0) {
       integer len = LEN+1-llGetListLength(data); while (--len) data += [0];
       schedule = llListSort([now+time, 0] + data + schedule, LEN+2, 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.
   integer til = llList2Integer(schedule, 0);
   if (til > now) llSetTimerEvent(til-now);
   else if (!til) 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>