On Tue, Oct 09, 2001 at 12:21:03PM -0400, Glenn Maynard wrote:
> It was a little more direct, originally, storing the interval with its
> constructor; I removed that as the interval can change with each call.
> I might put it back and update the interval with Reconfig, which would
> make it more straightforward.

Did this.  Also:
added ms constructor for time; this gives us a free cast from int to
Time, which means all of the ms operations can away (they're implicit.)

Defined negative time values more clearly (in comments).  This usually
doesn't matter.

Fixed Time.h indentation.

Fixed a race condition; this came up in debugging and could (rarely)
happen in practice: don't Timeout(negative);

Added min() and max() to misc.h.  I don't know if <algorithm> (which
provides a generic templatized min and max) is available on all target
systems.  (Does anyone know?)

-- 
Glenn Maynard
Index: StatusLine.cc
===================================================================
RCS file: /home/lav/cvsroot/lftp/src/StatusLine.cc,v
retrieving revision 1.12
diff -u -r1.12 StatusLine.cc
--- StatusLine.cc       2001/10/09 12:48:16     1.12
+++ StatusLine.cc       2001/10/09 23:40:44
@@ -66,6 +66,7 @@
    strcpy(def_title,"");
    not_term=!isatty(fd);
    LastWidth=GetWidth();
+   Reconfig();
 }
 
 StatusLine::~StatusLine()
@@ -107,18 +108,23 @@
 
    if(!strcmp(to_be_shown,newstr)) return;
 
-   int res = timer.go(status_interval.Query(0));
-   if(!res)
-   {
+   if(timer.go()) {
       update(newstr);
       update_delayed=false;
-   }
-   else
-   {
-      strcpy(to_be_shown,newstr);
-      update_delayed=true;
-      Timeout(res);
+      return;
    }
+   /* not yet */
+   strcpy(to_be_shown,newstr);
+   update_delayed=true;
+   Timeout(max(timer.remaining(), 0));
+}
+
+void StatusLine::Reconfig(const char *name)
+{
+   if(name && strcmp(name, "cmd:status-interval"))
+      return;
+      
+   timer.set_interval((int) status_interval.Query(0));
 }
 
 void StatusLine::WriteTitle(const char *s, int fd) const
@@ -232,13 +238,12 @@
 {
    if(!update_delayed)
       return STALL;
-   int res = timer.go(status_interval.Query(0));
-   if(!res)
+   if(timer.go())
    {
       update(to_be_shown);
       update_delayed=false;
       return STALL;
    }
-   Timeout(res);
+   Timeout(max(timer.remaining(), 0));
    return STALL;
 }
Index: StatusLine.h
===================================================================
RCS file: /home/lav/cvsroot/lftp/src/StatusLine.h,v
retrieving revision 1.7
diff -u -r1.7 StatusLine.h
--- StatusLine.h        2001/10/09 12:48:16     1.7
+++ StatusLine.h        2001/10/09 23:40:44
@@ -56,6 +56,7 @@
    void Show(const char *f,...) PRINTF_LIKE(2,3);
    void WriteLine(const char *f,...) PRINTF_LIKE(2,3);
    void Clear();
+   void Reconfig(const char *name=0);
 
    int getfd() { return fd; }
 
Index: Time.cc
===================================================================
RCS file: /home/lav/cvsroot/lftp/src/Time.cc,v
retrieving revision 1.2
diff -u -r1.2 Time.cc
--- Time.cc     2001/10/09 12:48:16     1.2
+++ Time.cc     2001/10/09 23:40:44
@@ -2,16 +2,57 @@
 #include "misc.h"
 #include "Time.h"
 
+/* Note for negative intervals:
+ *
+ * The formula for getting the value of a Time or timeval in seconds is:
+ * sec + (ms * 0.001)
+ * 
+ * This means -5.25 is { -6, 750 }.
+ *
+ * This almost never matters.  Negative intervals are almost never
+ * displayed; they usually only exist as a result of math.  If you actually
+ * need to do that, do:
+ * printf("%-3.3f", tm.ms() / 1000.);
+ */
 void Time::set_now()
 {
    xgettimeofday(&tsec, &tms);
    tms /= 1000; /* us -> ms */
 }
 
-Time Time::operator - (Time rhs) const
+void Time::set(int sec, int ms)
+{
+   tsec = sec;
+   tms = ms;
+
+   /* normalize to -1000 < tms < 1000 */
+   if(tms < 0 || tms >= 1000) {
+      tsec += tms / 1000;
+      tms %= 1000;
+   }
+   /* 0 < tms < 1000 */
+   if(tms < 0) {
+      tms += 1000;
+      tsec--;
+   }
+}
+
+Time &Time::operator += (Time rhs)
+{
+   tsec += rhs.tsec;
+   tms += rhs.tms;
+   if (tms >= 1000) {
+        ++tsec;
+        tms -= 1000;
+   }
+
+   return *this;
+}
+
+Time Time::operator + (Time rhs) const
 {
    Time ret(*this);
-   ret -= rhs;
+   ret += rhs;
    return ret;
 }
 
@@ -27,22 +68,13 @@
    return *this;
 }
 
-Time Time::operator + (int ms) const
+Time Time::operator - (Time rhs) const
 {
    Time ret(*this);
-   ret += ms;
+   ret -= rhs;
    return ret;
 }
 
-Time &Time::operator += (int ms)
-{
-   tms += ms;
-   tsec += tms / 1000;
-   tms %= 1000;
-
-   return *this;
-}
-
 bool Time::operator < (Time cmp) const
 {
    if(tsec == cmp.tsec) return tms < cmp.tms;
@@ -65,19 +97,24 @@
    force();
 }
 
-int Timer::go(int ms)
+int Timer::remaining() const
 {
    Time now;
    now.set_now();
 
-   Time next = last + ms;
+   Time next = last + interval;
 
-   if(now < next) {
-      Time left = next - now;
-      return left.ms();
-   }
+   Time left = next - now;
+   return left.ms();
+}
 
-   reset();
+bool Timer::go()
+{
+   int rem = remaining();
 
-   return 0;
+   if(rem <= 0) {
+      reset();
+      return true;
+   }
+   return false;
 }
Index: Time.h
===================================================================
RCS file: /home/lav/cvsroot/lftp/src/Time.h,v
retrieving revision 1.1
diff -u -r1.1 Time.h
--- Time.h      2001/10/09 08:27:21     1.1
+++ Time.h      2001/10/09 23:40:44
@@ -2,49 +2,59 @@
 #define TIME_CLASSES_H
 
 class Time {
-       time_t tsec;
-       int tms;
+   time_t tsec;
+   int tms;
 
-public:
-       Time() { clear(); }
+   public:
+   Time() { clear(); }
+   Time(int ms) { set(0, ms); }
+
+   /* set the time to now */
+   void set_now();
+
+   /* set time to sec,ms */
+   void set(int sec, int ms);
+
+   /* clear to the beginning of time */
+   void clear() { set(0,0); }
 
-       /* set the time to now */
-       void set_now();
+   int sec() const { return tsec; }
+   int ms() const { return (tsec * 1000) + tms; }
 
-       /* clear to the beginning of time */
-       void clear() { tsec = tms = 0; }
+   Time operator + (Time rhs) const;
+   Time &operator += (Time rhs);
+   Time operator - (Time rhs) const;
+   Time &operator -= (Time rhs);
 
-       int sec() const { return tsec; }
-       /* int usec() const { return ms; } */
-       int ms() const { return (tsec * 1000) + tms; }
-
-       /* all integer operations are in milliseconds */
-       /* these are mostly operators which are in use; add others as needed */
-       Time operator + (int ms) const;
-       Time &operator += (int ms);
-
-       Time operator - (Time rhs) const;
-       Time &operator -= (Time rhs);
-               
-       bool operator < (Time cmp) const;
-       bool operator >= (Time cmp) const { return !(*this < cmp); }
+   bool operator < (Time cmp) const;
+   bool operator >= (Time cmp) const { return !(*this < cmp); }
 };
 
 class Timer {
-       Time last;
+   /* last time this timer occured */
+   Time last;
 
+   /* interval between calls */
+   Time interval;
+
 public:
-       Timer();
+   Timer();
+
+   void set_interval(Time new_interval) { interval = new_interval; }
+
+   /* return the number of ms until next interval; this will be <= 0 if
+    * this event has already occured and not received */
+   int remaining() const;
 
-       /* return 0 if ms have elapsed since last 0 return or instantiation;
-        * otherwise return the number of ms left */
-       int go(int ms);
+   /* return true if the interval has elapsed, false otherwise;
+    * reset the interval if it's elapsed */
+   bool go();
 
-       /* reset timer */
-       void reset();
+   /* reset timer */
+   void reset();
 
-       /* force timer to go on next call */
-       void force();
+   /* force timer to go on next call */
+   void force();
 };
 
 #endif
Index: complete.cc
===================================================================
RCS file: /home/lav/cvsroot/lftp/src/complete.cc,v
retrieving revision 1.45
diff -u -r1.45 complete.cc
--- complete.cc 2001/10/09 12:48:16     1.45
+++ complete.cc 2001/10/09 23:40:44
@@ -657,7 +657,7 @@
         if(type==REMOTE_DIR)
            rg->glob->DirectoriesOnly();
         Timer timer;
-        int interval = ResMgr::Query("cmd:status-interval", 0);
+        timer.set_interval((int) ResMgr::Query("cmd:status-interval", 0));
 
         for(;;)
         {
@@ -672,7 +672,7 @@
               return 0;
            }
 
-           if(!fso.quiet && !timer.go(interval)) {
+           if(!fso.quiet && timer.go()) {
               /* don't set blank status; if we're operating from cache,
                * that's all we'll get and it'll look ugly: */
               const char *ret = rg->Status();
Index: misc.h
===================================================================
RCS file: /home/lav/cvsroot/lftp/src/misc.h,v
retrieving revision 1.21
diff -u -r1.21 misc.h
--- misc.h      2001/10/09 12:48:17     1.21
+++ misc.h      2001/10/09 23:40:44
@@ -100,4 +100,6 @@
 /* uses gettimeofday if available */
 void xgettimeofday(time_t *sec, int *usec);
 
+static inline int min(int a, int b) { return a < b? a:b; }
+static inline int max(int a, int b) { return a > b? a:b; }
 #endif // MISC_H

Reply via email to