LibraryPrecisionTime

De DigiWiki.

(Différences entre les versions)
(Page créée avec « This is a chunk of code to show you two things. 1) llSetTimerEvent's precision is ridiculously low. 2) You can easily improve the precision by setting the timer a bit short … »)
 
Ligne 2 : Ligne 2 :
1) llSetTimerEvent's precision is ridiculously low.
1) llSetTimerEvent's precision is ridiculously low.
 +
2) You can easily improve the precision by setting the timer a bit short and then waiting until your target time.
2) You can easily improve the precision by setting the timer a bit short and then waiting until your target time.
==== How do you use this script? ====
==== How do you use this script? ====
1) If you cut and paste this code into a script and put it into a box, it will send periodic messages displaying how far off llSetTimerEvent is from where it should be, in seconds.
1) If you cut and paste this code into a script and put it into a box, it will send periodic messages displaying how far off llSetTimerEvent is from where it should be, in seconds.
 +
2) If you change the first line to "integer useprectimer = 1;" it will send periodic messages displaying how close a precision timer can get.
2) If you change the first line to "integer useprectimer = 1;" it will send periodic messages displaying how close a precision timer can get.
 +
3) If you read the timer event at the bottom, and precTimer() function at the top, they demonstrate the precision timer.
3) If you read the timer event at the bottom, and precTimer() function at the top, they demonstrate the precision timer.

Version actuelle en date du 22 mars 2012 à 13:49

This is a chunk of code to show you two things.

1) llSetTimerEvent's precision is ridiculously low.

2) You can easily improve the precision by setting the timer a bit short and then waiting until your target time.

How do you use this script?

1) If you cut and paste this code into a script and put it into a box, it will send periodic messages displaying how far off llSetTimerEvent is from where it should be, in seconds.

2) If you change the first line to "integer useprectimer = 1;" it will send periodic messages displaying how close a precision timer can get.

3) If you read the timer event at the bottom, and precTimer() function at the top, they demonstrate the precision timer.

//--------------------------
// precision timer
//--------------------------
 
integer useprectimer = 0; // 0 for settimerevent, 1 for precision timer
float timetotest = 0.2; // how fast should the timer run?
 
 
// these two functions set timers with and without precision, and mark the desired time target
vector timeTarget;
precTimer( float secdiff )
{
    timeTarget = vecTime();
    timeTarget.z += secdiff;
    llSetTimerEvent(secdiff - 0.05);
}
nonprecTimer( float secdiff )
{
    timeTarget = vecTime();
    timeTarget.z += secdiff;
    llSetTimerEvent(secdiff);
}
 
 
// run a report of how well the timer is doing
runReport()
{
        float min;
        float max;
        float avg;
        float total;
        float cur;
        integer i;
        integer len;
 
        llSetTimerEvent(0.0); // try to clear the event queue up a bit, altho reset should do it
        if( useprectimer == 1 ) {
            llOwnerSay("Precision timer stats:");
        } else {
            llOwnerSay("llSetTimerEvent stats:");
        }
 
        len = llGetListLength(lDiffs);
        total = 0.0;
        min = 1.0;
        max = 0.0;
        for( i = 0; i < len; i++ ) {
            cur = llList2Float(lDiffs, i);
            total += cur;
            if( cur < min ) {
                min = cur;
            }
            if( cur > max ) {
                max = cur;
            }
        }
        avg = total/(float)len;
        llOwnerSay("Total drift: " + (string)total + ", timers run: " + (string)len);
        llOwnerSay("Avg   drift: " + (string)avg);
        llOwnerSay("Min   drift: " + (string)min);
        llOwnerSay("Max   drift: " + (string)max);
        llOwnerSay("Starting another run.");
        llResetScript();
}
 
//--------------------------
// time utility functions
//--------------------------
vector vecTime()
{
    vector tsp;
    list tsv;
 
    tsv = llParseString2List( llGetTimestamp(), ["T", ":", "Z"], [] );
 
    tsp.x = llList2Integer(tsv, 1) - 8;
    if( tsp.x < 0 ) {
        tsp.x += 24;
    }
    tsp.y = llList2Integer(tsv, 2);
    tsp.z = llList2Float(tsv, 3);
 
    return tsp;
}
 
vector fixTime( vector inTime )
{
    vector oTime = inTime;
 
    while( oTime.z >= 60.0 ) {
        oTime.z -= 60.0;
        oTime.y++;
    }
    while( oTime.y >= 60.0 ) {
        oTime.y -= 60.0;
        oTime.z++;
    }
    return oTime;
}
 
float timeDiffNow( vector vTarget )
{
    vector vTime = vecTime();
    return (vTarget.x - vTime.x)*3600.0 + (vTarget.y - vTime.y) * 60.0 + (vTarget.z - vTime.z);
}
 
// included for reference:
float timeDiff( vector vMore, vector vLess )
{
    float hours = vMore.x - vLess.x;
    float minutes = vMore.y - vLess.y;
    float seconds = vMore.z - vLess.z;
 
    float tics = hours * 3600.0 + minutes * 60.0 + seconds;
 
//    llOwnerSay("Diff between " + (string)vMore + " and " + (string)vLess );  
//    llOwnerSay("Diff returned approx. " + (string)( (integer)tics ) + " seconds.");
    return tics;
}
 
 
//--------------------------
// PrecTimer script: report the drift in llSetTimerEvent, and show an easy way to fix it:
//--------------------------
list lDiffs; // used to store statistics
 
default
{
    state_entry()
    {
        lDiffs = [];
        if( useprectimer == 1 ) {
            precTimer(timetotest);
        } else {
            nonprecTimer(timetotest);
        }
    }
 
    timer()
    {
        float timeleft = timeDiffNow(timeTarget);   // ETA to target time
 
        if( useprectimer == 1 ) {
            //Begin very simple precision countdown:
            llResetTime();
            while( (timeleft -= llGetAndResetTime()) > 0.01 );
            //Reset the target of the precision timer:
            precTimer(timetotest);
        } else {
            //Reset the target of the nonprecision timer:
            timeTarget.z += timetotest;
        }
        lDiffs = (lDiffs=[]) + lDiffs + [llFabs(timeleft)];
        if( llGetListLength(lDiffs) > 100 ) {
            runReport();
        }
    }
 
    touch_start(integer nd)
    {
        runReport();
    }
}

Example output:

[15:57] Object: Precision timer stats:
[15:57] Object: Total drift: 0.110259, timers run: 101
[15:57] Object: Avg drift: 0.001092
[15:57] Object: Min drift: 0.000000
[15:57] Object: Max drift: 0.080150

[15:59] Object: llSetTimerEvent stats:
[15:59] Object: Total drift: 2.131889, timers run: 101
[15:59] Object: Avg drift: 0.021108
[15:59] Object: Min drift: 0.000084
[15:59] Object: Max drift: 0.101887

That's right... which do you want, a drift of 1/50th of a second, or of 1/1000th of a second? Yes. Use a precision timer.

Outils personnels
  • Cette page a été consultée 810 fois.
donate
Google Ads