MultiTimer: Difference between revisions

From Second Life Wiki
Jump to navigation Jump to search
Small library to simplify the use of multiple timers in a script
 
No edit summary
 
(8 intermediate revisions by 2 users not shown)
Line 3: Line 3:
Small library to simplify the use of multiple timers in a script.
Small library to simplify the use of multiple timers in a script.


<lsl>
<source lang="lsl2">


/* *** ------------------------------------------- *** */
/* *** ------------------------------------------- *** */
Line 10: Line 10:
/* *** http://creativecommons.org/licenses/by/3.0/ *** */
/* *** http://creativecommons.org/licenses/by/3.0/ *** */
/* *** ------------------------------------------- *** */
/* *** ------------------------------------------- *** */
integer s_running_timers=0;
float  c_check_interval=0.5;
list s_timers_nexts=[];
integer s_running_timers=0;
list s_timers_intervals=[];
list   s_timers_nexts=[];
list   s_timers_intervals=[];
startTimer(integer x_id,float x_interval){
startTimer(integer x_id,float x_interval){
integer shift=1<<x_id;
    integer shift=1<<x_id;
if(s_running_timers==0)llSetTimerEvent(0.5);
    if(s_running_timers==0)llSetTimerEvent(c_check_interval);
if(!(s_running_timers&shift)){
    if(!(s_running_timers&shift)){
while(llGetListLength(s_timers_nexts)<=x_id){s_timers_nexts+=0.0;s_timers_intervals+=60.0;}
        while(llGetListLength(s_timers_nexts)<=x_id){s_timers_nexts+=0.0;s_timers_intervals+=60.0;}
s_timers_nexts=llListReplaceList(s_timers_nexts,[llGetTime()+x_interval],x_id,x_id);
        s_timers_nexts=llListReplaceList(s_timers_nexts,[llGetTime()+x_interval],x_id,x_id);
s_timers_intervals=llListReplaceList(s_timers_intervals,[x_interval],x_id,x_id);
        s_timers_intervals=llListReplaceList(s_timers_intervals,[x_interval],x_id,x_id);
s_running_timers=s_running_timers|shift;
        s_running_timers=s_running_timers|shift;
} }
    }
}
stopTimer(integer x){
stopTimer(integer x){
integer shift=1<<x;
    integer shift=1<<x;
if(s_running_timers&shift)s_running_timers=s_running_timers&(~shift);
    if(s_running_timers&shift)s_running_timers=s_running_timers&(~shift);
if(s_running_timers==0)llSetTimerEvent(0);
    if(s_running_timers==0)llSetTimerEvent(0);
}
}
quickTimer(integer x){
quickTimer(integer x){
s_timers_nexts=llListReplaceList(s_timers_nexts,[llGetTime()],x,x);
    s_timers_nexts=llListReplaceList(s_timers_nexts,[llGetTime()],x,x);
}
}
restartTimer(integer x){
restartTimer(integer x){
if(s_running_timers&(1<<x)){
    if(s_running_timers&(1<<x)){
stopTimer(x);
        stopTimer(x);
startTimer(x,llList2Float(s_timers_intervals,x));
        startTimer(x,llList2Float(s_timers_intervals,x));
}
    }
}
}
integer checkTimer(integer x_timer){
integer checkTimer(integer x_timer){
if(s_running_timers&(1<<x_timer)){
    if(s_running_timers&(1<<x_timer)){
float now=llGetTime();
        float now=llGetTime();
float next=llList2Float(s_timers_nexts,x_timer);
        float next=llList2Float(s_timers_nexts,x_timer);
if(now>next){
        if(now>next){
float interval=llList2Float(s_timers_intervals,x_timer);
            float interval=llList2Float(s_timers_intervals,x_timer);
next=next+interval;
            next=next+interval;
if(now>next+interval)next=now+interval;
            if(now>next+interval)next=now+interval;
s_timers_nexts=llListReplaceList(s_timers_nexts,[next],x_timer,x_timer);
            s_timers_nexts=llListReplaceList(s_timers_nexts,[next],x_timer,x_timer);
return 1;
            return 1;
} }
        }
return 0;
    }
    return 0;
}
}
/* *** ------------------------------------------- *** */
/* *** ------------------------------------------- *** */


// Timers can be set from 0 to 31
//   Timers can be set from 0 to 31


default{
default
state_entry(){
{
startTimer(0,10.0); //Set timer 0 to happen every 10 seconds
    state_entry()
startTimer(1,5.0); //Set timer 1 to happen every 5 seconds
    {
quickTimer(1); //Tell timer 1 to happen right away
        startTimer(0, 10.0); //Set timer 0 to happen every 10 seconds
}
        startTimer(1, 5.0); //Set timer 1 to happen every 5 seconds
timer(){
        quickTimer(1); //Tell timer 1 to happen right away
if(checkTimer(0)){ //Check if timer 0 is ready to go off
    }
llOwnerSay("10!");
    timer()
stopTimer(0); //Stop timer 0
    {
}
        if(checkTimer(0)) //Check if timer 0 is ready to go off
if(checkTimer(1)){ //Check if timer 1 is ready to go off
        {
llOwnerSay("5!");
            llOwnerSay("10!");
}
            stopTimer(0); //Stop timer 0
}
        }
touch_end(integer x){
        if(checkTimer(1)) //Check if timer 1 is ready to go off
restartTimer(1); //Restart timer 1
        {
}
            llOwnerSay("5!");
        }
    }
    touch_end(integer x)
    {
        restartTimer(1); //Restart timer 1
    }
}
}


/* Output:
/*   Output:
5! (Because we told timer 1 to go off right away)
5! (Because we told timer 1 to go off right away)
[pause for 5 seconds]
[pause for 5 seconds]
Line 86: Line 95:
*/
*/


</lsl>
</source>
 
Alternate simplified version of the same idea. Scripted by Ravenmists Resident. This version is not as accurate as the above version but will work for timers set to 0.5, 1.0, 1.5, 2.0 etc
 
<source lang="lsl2">
list timers=[];
integer rTimers=0;
float time;
integer index;
float tCheck=0.5; //How often to run the overall timer
float tAdd=0.5; //How much to add to the time variable with each loop of the overall timer
 
startTimer(integer n, float l){
    index=llListFindList(timers,[n]);
    if(index==-1){
        timers+=[n]+[l];
    }
    if(rTimers==0){
        llSetTimerEvent(tCheck);
    }
    rTimers++;
}
 
integer checkTimer(integer n){
    index=llListFindList(timers,[n]);
    if(index!=-1){
        float test=div(time,llList2Float(timers,index+1));
        if(test==0){
            return 1;
        }
    }
    return 0;
}
 
stopTimer(integer n){
    index=llListFindList(timers,[n]);
    timers=llListReplaceList(timers,[-1],index+1,index+1);
}
 
restartTimer(integer n, float l){
    index=llListFindList(timers,[n]);
    timers=llListReplaceList(timers,[l],index+1,index+1);
}
 
float div(float a, float b){
    return a-b*llFloor(a/b);
}
 
integer a=0;
default{
    touch_start(integer x){
        if(a){
            stopTimer(0);
        }else{
            startTimer(0,10.0);
        }
        a= !a;
        startTimer(1,5.0);
    }
    timer(){
        time+=tAdd;
        if(checkTimer(0)){
            llOwnerSay("Timer 0");
        }
        if(checkTimer(1)){
            llOwnerSay("Timer 1");
        }
    }
}
</source>

Latest revision as of 17:12, 20 September 2015

Small library to simplify the use of multiple timers in a script.

/* *** ------------------------------------------- *** */
/* ***   Copyright (c) 2013 by Craftish Resident   *** */
/* ***    Attribution 3.0 Unported (CC BY 3.0)     *** */
/* *** http://creativecommons.org/licenses/by/3.0/ *** */
/* *** ------------------------------------------- *** */
float   c_check_interval=0.5;
integer s_running_timers=0;
list    s_timers_nexts=[];
list    s_timers_intervals=[];
startTimer(integer x_id,float x_interval){
    integer shift=1<<x_id;
    if(s_running_timers==0)llSetTimerEvent(c_check_interval);
    if(!(s_running_timers&shift)){
        while(llGetListLength(s_timers_nexts)<=x_id){s_timers_nexts+=0.0;s_timers_intervals+=60.0;}
        s_timers_nexts=llListReplaceList(s_timers_nexts,[llGetTime()+x_interval],x_id,x_id);
        s_timers_intervals=llListReplaceList(s_timers_intervals,[x_interval],x_id,x_id);
        s_running_timers=s_running_timers|shift;
    }
}
stopTimer(integer x){
    integer shift=1<<x;
    if(s_running_timers&shift)s_running_timers=s_running_timers&(~shift);
    if(s_running_timers==0)llSetTimerEvent(0);
}
quickTimer(integer x){
    s_timers_nexts=llListReplaceList(s_timers_nexts,[llGetTime()],x,x);
}
restartTimer(integer x){
    if(s_running_timers&(1<<x)){
        stopTimer(x);
        startTimer(x,llList2Float(s_timers_intervals,x));
    }
}
integer checkTimer(integer x_timer){
    if(s_running_timers&(1<<x_timer)){
        float now=llGetTime();
        float next=llList2Float(s_timers_nexts,x_timer);
        if(now>next){
            float interval=llList2Float(s_timers_intervals,x_timer);
            next=next+interval;
            if(now>next+interval)next=now+interval;
            s_timers_nexts=llListReplaceList(s_timers_nexts,[next],x_timer,x_timer);
            return 1;
        }
    }
    return 0;
}
/* *** ------------------------------------------- *** */

//    Timers can be set from 0 to 31

default
{
    state_entry()
    {
        startTimer(0, 10.0);	//Set timer 0 to happen every 10 seconds
        startTimer(1, 5.0);	//Set timer 1 to happen every 5 seconds
        quickTimer(1);		//Tell timer 1 to happen right away
    }
    timer()
    {
        if(checkTimer(0))	//Check if timer 0 is ready to go off
        {
            llOwnerSay("10!");
            stopTimer(0);	//Stop timer 0
        }
        if(checkTimer(1))	//Check if timer 1 is ready to go off
        {
            llOwnerSay("5!");
        }
    }
    touch_end(integer x)
    {
        restartTimer(1);	//Restart timer 1
    }
}

/*    Output:
5! (Because we told timer 1 to go off right away)
[pause for 5 seconds]
5!
[pause for 5 seconds]
10! (Only happens once because the timer is stopped here)
5!
[pause for 5 seconds]
5!
[pause for 5 seconds]
...
*/

Alternate simplified version of the same idea. Scripted by Ravenmists Resident. This version is not as accurate as the above version but will work for timers set to 0.5, 1.0, 1.5, 2.0 etc

list timers=[];
integer rTimers=0;
float time;
integer index;
float tCheck=0.5; //How often to run the overall timer
float tAdd=0.5; //How much to add to the time variable with each loop of the overall timer

startTimer(integer n, float l){
    index=llListFindList(timers,[n]);
    if(index==-1){
        timers+=[n]+[l];
    }
    if(rTimers==0){
        llSetTimerEvent(tCheck); 
    }
    rTimers++;
}

integer checkTimer(integer n){
    index=llListFindList(timers,[n]);
    if(index!=-1){
        float test=div(time,llList2Float(timers,index+1));
        if(test==0){
            return 1;
        }
    }
    return 0;
}

stopTimer(integer n){
    index=llListFindList(timers,[n]);
    timers=llListReplaceList(timers,[-1],index+1,index+1);
}

restartTimer(integer n, float l){
    index=llListFindList(timers,[n]);
    timers=llListReplaceList(timers,[l],index+1,index+1);
}

float div(float a, float b){
    return a-b*llFloor(a/b);
}

integer a=0;
default{
    touch_start(integer x){
        if(a){
            stopTimer(0);
        }else{
            startTimer(0,10.0);
        }
        a= !a;
        startTimer(1,5.0);
    }
    timer(){
        time+=tAdd;
        if(checkTimer(0)){
            llOwnerSay("Timer 0");
        }
        if(checkTimer(1)){
            llOwnerSay("Timer 1");
        }
    }
}