Jump to content
Sign in to follow this  
ItHadToComeToThis

Floating point multi timer

Recommended Posts

I needed to write myself a multi timer so thought I would post it here for you fine people. Chances are it can probably be improved, if so, post your improvements in the comments.

 

float timerA=2.0;
float timerB=3.3;
float timerC=7.0;

float decimalPlace(float d, integer p){
    string s=(string)d;
    s=llDeleteSubString(s,llSubStringIndex(s,".")+p,-1);
    return ((float)s);
}

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

integer checkTimer(float mTimer){
    if(div(decimalPlace(llGetTime(),2),mTimer)==0.0){
        return 1;
    }
    return 0;
}

default{
    state_entry(){
        llResetTime();
        llSetTimerEvent(0.1);
    }
    timer(){
        //Timer A
        if(checkTimer(timerA)){
            llOwnerSay("TIMER A : "+(string)decimalPlace(llGetTime(),2));
        }
        //Timer B
        if(checkTimer(timerB)){
            llOwnerSay("TIMER B : "+(string)decimalPlace(llGetTime(),2));
        }
        //Timer C
        if(checkTimer(timerC)){
            llOwnerSay("TIMER C : "+(string)decimalPlace(llGetTime(),2));
        }
    }
}
/* RETURNS
[13:16] Object: TIMER A : 2.000000
[13:16] Object: TIMER B : 3.300000
[13:16] Object: TIMER A : 4.000000
[13:16] Object: TIMER A : 6.000000
[13:16] Object: TIMER B : 6.600000
[13:16] Object: TIMER C : 7.000000
[13:16] Object: TIMER A : 8.000000
[13:16] Object: TIMER A : 10.000000
[13:16] Object: TIMER A : 12.000000
[13:16] Object: TIMER B : 13.200000
[13:16] Object: TIMER A : 14.000000
[13:16] Object: TIMER C : 14.000000
[13:16] Object: TIMER A : 16.000000
[13:16] Object: TIMER A : 18.000000
[13:16] Object: TIMER A : 20.000000
[13:16] Object: TIMER C : 21.000000
[13:16] Object: TIMER A : 22.000000
*/

 

Share this post


Link to post
Share on other sites

some thoughts

casting float to string always results in 6 chars following the decimal point. For an efficiency gain we can remove the llSubStringIndex() function call and get the same result

float decimalPlace(float d, integer p)
{
   return (float)llDeleteSubString((string)d, p-6, -1);
}


checkTimer() evaluates to TRUE or FALSE so we can do an inline evaluation for a tiny gain:

integer checkTimer(float mTimer)
{
    return (div(decimalPlace(llGetTime(), 2), mTimer) == 0.0);
}

 

and a different way to do this. A multi-timer that uses a ticker

float TICK_PERIOD = 0.1;  // tick the timer every 0.1 seconds
integer TimerA = 20;    // fire timerA every 20 * TICK_PERIOD = 2.0 seconds
integer TimerB = 33;    // fire timerB every 33 * TICK_PERIOD = 3.3 seconds
integer TimerC = 70;    // fire timerC every 70 * TICK_PERIOD = 7.0 seconds

integer ticker;   // add 1 to ticker every TICK_PERIOD
integer range;    // prevent the ticker from overflowing 

default
{
    state_entry()
    {
        llResetTime();
        range = TimerA * TimerB * TimerC;
        llSetTimerEvent(TICK_PERIOD);
    }

    timer()
    {
        ticker = (++ticker) % range; 
        if (!(ticker % TimerA)) // fire TimerA
        {
            llOwnerSay("TimerA: " + (string)llGetTime());
        }
        if (!(ticker % TimerB)) // fire TimerB
        {
            llOwnerSay("TimerB: " +  (string)llGetTime());
        }
        if (!(ticker % TimerC)) // fire TimerC
        {
            llOwnerSay("TimerC: " +  (string)llGetTime());
        }
    }
}

 

 

 

 

 

 

  • Like 1

Share this post


Link to post
Share on other sites
7 hours ago, Mollymews said:

 

That’s an interesting way to do it and thanks for the comments, il make changes to my one. One thing I realised I never added a way to stop the timers on mine so thinking I may add that later. Debating whether to use lists or if I can use a bit wise switch to keep track of the timer numbers. Or maybe I am over thinking it

Share this post


Link to post
Share on other sites
5 hours ago, ItHadToComeToThis said:

One thing I realised I never added a way to stop the timers on mine so thinking I may add that later

Debating whether to use lists or if I can use a bit wise switch to keep track of the timer numbers. Or maybe I am over thinking it

some thoughts on these

with floats then we have to guard against precision errors. Example this:

div(decimalPlace(llGetTime(), 2), mTimer) == 0.0;

llGetTime() cannot be exactly 9.9. It is 9.913491. Which after casting and trimming returns as 9.91

9.91 modulus 3.3 is 0.01

0.01 != 0.0 so the function returns FALSE when for the purposes of the timer it should return TRUE

we can fix this by bounding the precision deviation to some range. Example:

div(decimalPlace(llGetTime(), 2), mTimer) <= 0.05; // where 0.05 is the deviation we have chosen


with managing the timers

a way it can be done is to set the timer values to 0.0 when not used. Checking for this in checkTimer() which also prevents a division by zero error in the div() function. Example:

integer checkTimer(float mTimer)
{
   if (mTimer <= 0.0)
      return FALSE;
   return div(decimalPlace(llGetTime(), 2), mTimer) <= 0.05;
}

to start/stop the timer event then a way is to use the sum total of the individual timers. Example:

llSetTimerEvent( 0.1 * (float)(TimerA + TimerB + TimerC > 0.0));
// when any of the timers are greater than 0.0 then
// 0.1 * (float)TRUE = 0.1
// when they are all 0.0 then
// 0.1 * (float)FALSE = 0.0

 

on using a list for the timers rather than named variables then this is the way I prefer also

as with a list we can add/remove timers dynamically at runtime, which we often need to do when making multi-player and/or multi-level games

 

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this  

×
×
  • Create New...