Вобщем... столкнулся с такой вот незадачей... нужен таймер, который бы работал на порядок точнее родного... Т.е. по тех характеристикам в течение 45 секунд должен тикать каждые 33 миллисекунды с погрешностью не более 6 миллисекунд (и при этом, желательно не сильно нагружать процессор)... Даже, не, скорее не так: нужно добиться, чтобы функция вызывалась точно по истечении 33 миллисекунд (само по себе выполнение функции примерно укладывается в это же время).
Что я уже попробовал:
- запускать таймер с минимальным интервалом. (эмпирическим путем выяснилось, что разницы между 1-6..8 миллисекунд практически нету. При вызове раз в 10 миллисекунд погрешность составляет примерно 6-15 миллисекунд (почти в 3 раза... млин =( ). Т.е. можно высчитывать дельту между ожидаемым временем тика и реальным, и немного постаравшись результаты примерно укладываются в +-6 мс, но тестится все в "тепличных условиях", боюсь, что на практике окажеться хуже...
- просто в цикле проверять текущее время, конечно, работает, но во время цикла все равно ничего не сделаешь %)
ЗЫ. сравнительные тесты сетИнтервала/сетТаймаута и Таймера - примерно одинаково, особой разницы не заметил.
ЗЫЫ. просто интересны варианты решения, мб есть что-нибудь, о чем не подумал.
ЗЫЫЫ. ессно, не нужно думать, что этим кто-то собирается пользоваться, но нужно добиться примерно похожих результатов...
Код:
package
{
/**
* ...
* @author wvxvw
*/
import flash.utils.getTimer;
import flash.utils.setTimeout;
public class PTimer
{
private static var _pi:int = 0;
private static var _s:int = 0;
private static var _b:Boolean = true;
private static var _d:int = 0;
private static var _t:PTimer;
public function PTimer()
{
_t = this;
}
public static function start(interval:int, d:int = 0):void
{
if (!_pi) _pi = interval;
_s = getTimer();
if (!_d) _d = _s;
var dt:int = _pi - (_s - _d) % _pi;
pulse(dt);
}
public static function stop():void
{
_b = false;
_pi = 0;
_d = 0;
}
private static function pulse(dt:int):void
{
if (!_b) return;
var i:int;
var t:int = dt;
for (i = 0; i >= 0; i++)
{
if (getTimer() - _s >= t) {
//trace('timer: ' + getTimer());
setTimeout(start, 1, t);
break;
}
}
}
}
}