/*----------------------------------------------------------------------------- * timer.cpp * Copyright (C) 2004, 2005 Akito Nozaki * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #include "sys/time.h" #include #include NAMESPACE_TANOSHI { Timer::Timer(Object *parent) : Object(parent) { _autodel = false; _started = false; _millisec = false; _runonce = false; } Timer::~Timer() { removeFromEvent(); } bool Timer::event(Event *e) { if(e->id() != id()) return false; if(!_started) return true; if(!_calcTimer() && _timeout != 0) return true; if(_autodel) { timeout(); delete this; return true; } reset(); if(_runonce) { _started = false; stop(); } timeout(); return true; } void Timer::setTimeOut(int t, bool millisec) { _millisec = millisec; _timeout = t; setSleep(-1); } void Timer::setRunOnce(bool runonce) { _runonce = (int)runonce; } void Timer::setAutoDelete(bool autodel) { _autodel = autodel; } void Timer::start() { _started = true; reset(); addToEvent(); } void Timer::stop() { setSleep(-1); _counter.tv_sec = 0; _counter.tv_usec = 0; removeFromEvent(); _started = false; } void Timer::reset() { _counter = _getCurTime(); _endcounter = _counter; if(_millisec) { _endcounter.tv_usec += _timeout * 1000; _endcounter.tv_sec += _endcounter.tv_usec / 1000000; _endcounter.tv_usec %= 1000000; } else _endcounter.tv_sec += _timeout; setSleep( _calcSleep() ); } Timer *Timer::runOnce(int time, Object *parent) { Timer *ttemp; ttemp = new Timer(parent); ttemp->setAutoDelete(true); ttemp->setTimeOut(time, true); ttemp->setRunOnce(true); ttemp->start(); return ttemp; } bool Timer::_calcTimer() { if(_started == false) { setSleep(_calcSleep()); return false; } if(_counter.tv_sec == 0 && _counter.tv_usec == 0) { setSleep(_calcSleep()); return false; } struct timeval temp; temp = _getCurTime(); if(temp.tv_sec > _endcounter.tv_sec) return true; if(temp.tv_sec == _endcounter.tv_sec && temp.tv_usec >= _endcounter.tv_usec) return true; setSleep(_calcSleep()); return false; } int Timer::_calcSleep() { if(_started == false) return -1; struct timeval temp = _getCurTime(); if(temp.tv_sec == _endcounter.tv_sec && temp.tv_usec >= _endcounter.tv_usec) return 0; if(temp.tv_sec > _endcounter.tv_sec) return 0; int millisec = 0; if(_endcounter.tv_usec > temp.tv_usec) { millisec += (_endcounter.tv_usec - temp.tv_usec) / 1000; millisec += (_endcounter.tv_sec - temp.tv_sec) * 1000; } else { millisec += (1000000 + _endcounter.tv_usec - temp.tv_usec) / 1000; millisec += (_endcounter.tv_sec - temp.tv_sec - 1) * 1000; } return millisec; } struct timeval Timer::_getCurTime() { struct timeval tv; gettimeofday(&tv, NULL); return tv; } }