From b7496f2c59e2765ffa641f66f274947793f4d133 Mon Sep 17 00:00:00 2001 From: Bill Spitzak <spitzak@gmail.com> Date: Sun, 21 Jan 2001 06:00:59 +0000 Subject: [PATCH] "accu-timer": some changes to repeat_timeout that seem to make it accurate on Unix and Win32 at speeds up to 500000 timeouts/second (and 700000 on Linux), and within about .001% as accurate as the system clock. Fix to Fl_Valuator::step() by Guillermo Andrade. git-svn-id: file:///fltk/svn/fltk/branches/branch-1.0@1354 ea41ed52-d2ee-0310-a9c1-e6b18d33e121 --- src/Fl.cxx | 21 +++++++++++++++------ src/Fl_Valuator.cxx | 8 ++++---- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/src/Fl.cxx b/src/Fl.cxx index b0275a939..2296e0c74 100644 --- a/src/Fl.cxx +++ b/src/Fl.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl.cxx,v 1.24.2.37 2001/01/15 23:51:37 spitzak Exp $" +// "$Id: Fl.cxx,v 1.24.2.38 2001/01/21 06:00:58 spitzak Exp $" // // Main event handling code for the Fast Light Tool Kit (FLTK). // @@ -57,13 +57,15 @@ int Fl::e_length; // int Fl::event_inside(int x,int y,int w,int h) /*const*/ { - int mx = event_x() - x; - int my = event_y() - y; + int mx = e_x - x; + int my = e_y - y; return (mx >= 0 && mx < w && my >= 0 && my < h); } int Fl::event_inside(const Fl_Widget *o) /*const*/ { - return event_inside(o->x(),o->y(),o->w(),o->h()); + int mx = e_x - o->x(); + int my = e_y - o->y(); + return (mx >= 0 && mx < o->w() && my >= 0 && my < o->h()); } //////////////////////////////////////////////////////////////// @@ -110,13 +112,19 @@ static void elapse_timeouts() { } } +// Continuously-adjusted error value, this is a number <= 0 for how late +// we were at calling the last timeout. This appears to make repeat_timeout +// very accurate even when processing takes a significant portion of the +// time interval: +static double missed_timeout_by; + void Fl::add_timeout(double time, Fl_Timeout_Handler cb, void *arg) { elapse_timeouts(); repeat_timeout(time, cb, arg); } void Fl::repeat_timeout(double time, Fl_Timeout_Handler cb, void *arg) { - elapse_timeouts(); + time += missed_timeout_by; if (time < -.05) time = 0; Timeout* t = free_timeout; if (t) free_timeout = t->next; else t = new Timeout; @@ -207,6 +215,7 @@ double Fl::wait(double time_to_wait) { while ((t = first_timeout)) { if (t->time > 0) break; // The first timeout in the array has expired. + missed_timeout_by = t->time; // We must remove timeout from array before doing the callback: void (*cb)(void*) = t->cb; void *arg = t->arg; @@ -772,5 +781,5 @@ void Fl_Window::flush() { } // -// End of "$Id: Fl.cxx,v 1.24.2.37 2001/01/15 23:51:37 spitzak Exp $". +// End of "$Id: Fl.cxx,v 1.24.2.38 2001/01/21 06:00:58 spitzak Exp $". // diff --git a/src/Fl_Valuator.cxx b/src/Fl_Valuator.cxx index b066514b4..eaea57c2a 100644 --- a/src/Fl_Valuator.cxx +++ b/src/Fl_Valuator.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_Valuator.cxx,v 1.5.2.2 2000/06/05 21:20:58 mike Exp $" +// "$Id: Fl_Valuator.cxx,v 1.5.2.3 2001/01/21 06:00:59 spitzak Exp $" // // Valuator widget for the Fast Light Tool Kit (FLTK). // @@ -41,13 +41,13 @@ Fl_Valuator::Fl_Valuator(int X, int Y, int W, int H, const char* L) B = 1; } -const double epsilon = 1e-12 ; +const double epsilon = 4.66e-10; void Fl_Valuator::step(double s) { if (s < 0) s = -s; A = rint(s); B = 1; - while (fabs(s-A/B) > epsilon) {B *= 10; A = rint(s*B);} + while (fabs(s-A/B) > epsilon && B<=(0x7fffffff/10)) {B *= 10; A = rint(s*B);} } void Fl_Valuator::precision(int p) { @@ -123,5 +123,5 @@ int Fl_Valuator::format(char* buffer) { } // -// End of "$Id: Fl_Valuator.cxx,v 1.5.2.2 2000/06/05 21:20:58 mike Exp $". +// End of "$Id: Fl_Valuator.cxx,v 1.5.2.3 2001/01/21 06:00:59 spitzak Exp $". // -- GitLab