(* Copyright (C) 1992, Digital Equipment Corporation *) (* All rights reserved. *) (* See the file COPYRIGHT for a full description. *) (* *) (* Last modified on Mon Jan 4 09:36:51 PST 1993 by mhb *) (* modified on Tue Aug 11 21:07:58 PDT 1992 by meehan *) (* modified on Tue Jun 16 12:54:53 PDT 1992 by muller *) (* modified on Tue Feb 12 13:44:21 PST 1991 by chan *) (* modified on Wed Dec 26 11:03:59 PST 1990 by brooks *) (* The "AutoRepeat" interface provides support for calling a procedure repetitively. Auto-repeating typically takes place while a key or mouse button is held down, although there is no direct relation between "AutoRepeat" and "VBT"s. When an auto-repeat object "ar" is activated, it forks a {\it timer thread\/} that calls "ar.repeat()" after "firstWait" milliseconds, and every "period" milliseconds thereafter. However, there is a flow control mechanism: if the call to "ar.repeat()" has not returned by the time the next repetition should take place, the timer thread will wait. That is, repetitions cannot queue up more than one deep. An auto-repeat object "ar" is activated by a call to "Start(ar)", terminated by a call to "Stop(ar)", and resumed by a call to "Continue(ar)". All locking is handled within "AutoRepeat"; calls to "Start(ar)", "Stop(ar)", and "Continue(ar)" are serialized on a per-"ar" basis. These procedures may be called by a "repeat" method. Clients must not call the "repeat" method directly; it is called by the timer thread subject to client-calls to "Start", "Stop", and "Continue". The "AutoRepeat" interface will never call a "repeat" method re-entrantly. *) INTERFACE AutoRepeat; TYPE Milliseconds = CARDINAL; CONST DefaultFirstWait: Milliseconds = 500; DefaultPeriod : Milliseconds = 66; TYPE T <: Public; Public = Private OBJECT METHODS init (firstWait: Milliseconds := DefaultFirstWait; period : Milliseconds := DefaultPeriod): T; repeat (); END; Private <: ROOT; (* The call "ar.init(firstWait, period)" initializes "ar" as an "AutoRepeat.T", and it returns "ar". The "firstWait" and "period" parameters are stored internally for use by the "Start" and "Continue" procedures. An auto-repeat object "ar" does not have a default "repeat" method; it must be supplied by the client. *) PROCEDURE Start (ar: T); (* Initiate auto-repeating for "ar". *) (* "Start(ar)" forks a timer thread that will wait "ar.firstWait" milliseconds before calling "ar.repeat()" the first time, then "ar.period" milliseconds between subsequent calls to "ar.repeat()". This procedure is a no-op if "ar" is already running. *) PROCEDURE Stop (ar: T); (* Stop auto-repeating as soon as possible. *) (* After calling "Stop(ar)", "AutoRepeat" will not call "ar.repeat()" again until a call to "Start(ar)" or "Continue(ar)" restarts auto-repeating. This procedure is a no-op if "ar" is already running. It is possible (but unlikely) that "ar.repeat()" is called one more time after a call to "Stop(ar)" returns. This can happen because the call to "ar.repeat" is not serialized with repect to the call to "Stop(ar)". They are not serialized in order to allow a "repeat" method to call "Stop".*) PROCEDURE Continue (ar: T); (* Resume auto-repeating immediately. *) (* "Continue(ar)" is like "Start(ar)", except rather than waiting "ar.firstWait" milliseconds as in the call to "Start(ar)", the timer thread calls "ar.repeat" without waiting at all. Subsequent calls to "ar.repeat()" happen every "period" milliseconds, as usual. This procedure is a no-op if "ar" is already running. *) END AutoRepeat.