00001 /* 00002 * Worldvisions Weaver Software: 00003 * Copyright (C) 1997-2002 Net Integration Technologies, Inc. 00004 * 00005 * See wvtimestream.h. 00006 */ 00007 #include "wvtimestream.h" 00008 00009 WvTimeStream::WvTimeStream() 00010 { 00011 struct timezone tz; 00012 00013 ms_per_tick = max_backlog = 0; 00014 gettimeofday(&last_tv, &tz); 00015 } 00016 00017 00018 void WvTimeStream::set_timer(int msec, int _max_backlog) 00019 { 00020 struct timezone tz; 00021 00022 ms_per_tick = msec; 00023 max_backlog = _max_backlog; 00024 00025 gettimeofday(&last_tv, &tz); 00026 } 00027 00028 00029 bool WvTimeStream::isok() const 00030 { 00031 return true; 00032 } 00033 00034 00035 bool WvTimeStream::pre_select(SelectInfo &si) 00036 { 00037 struct timeval tv; 00038 struct timezone tz; 00039 time_t tdiff, tinc; 00040 00041 if (gettimeofday(&tv, &tz) || !ms_per_tick) 00042 return false; 00043 00044 // compensate for "time warps" (someone sets the clock backwards) 00045 if (tv.tv_sec < last_tv.tv_sec) 00046 { 00047 last_tv.tv_sec = tv.tv_sec; 00048 last_tv.tv_usec = tv.tv_usec; 00049 } 00050 00051 tdiff = (tv.tv_sec - last_tv.tv_sec) * 1000 00052 + (tv.tv_usec - last_tv.tv_usec) / 1000; 00053 00054 if (tdiff / ms_per_tick > max_backlog) 00055 { 00056 tinc = tdiff - max_backlog*ms_per_tick; 00057 last_tv.tv_sec += tdiff / 1000; 00058 last_tv.tv_usec += tdiff % 1000; 00059 } 00060 00061 return (tdiff > ms_per_tick); 00062 } 00063 00064 00065 bool WvTimeStream::post_select(SelectInfo &si) 00066 { 00067 return false; // if you have to ask, then just forget it. 00068 } 00069 00070 00071 void WvTimeStream::tick() 00072 { 00073 // it seems obvious to do a last_tv = tv; here -- but that results 00074 // in a lot of inaccuracy, since the _exact_ delay between ticks 00075 // is not guaranteed. Instead, we add ms_per_tick milliseconds onto 00076 // the last tick time, so we always average out to ms_per_tick. 00077 last_tv.tv_usec += ms_per_tick * 1000; 00078 last_tv.tv_sec += last_tv.tv_usec / 1000000; 00079 last_tv.tv_usec %= 1000000; 00080 } 00081 00082 00083 void WvTimeStream::execute() 00084 { 00085 WvStream::execute(); 00086 00087 // inform the stream that the clock has officially "ticked" 00088 tick(); 00089 }