############################################################################ # # File: decay.icn # # Subject: Procedures for decaying-displays for windows # # Author: Gregg M. Townsend # # Date: August 14, 1996 # ############################################################################ # # This file is in the public domain. # ############################################################################ # # These procedures provide a way to draw objects and then have them # automatically redrawn (say, in a lighter color) n steps later. # A user routine is called to do the actual drawing. If a second # call to draw an object comes before its time has expired, the # object's counter is reset and the drawing routine is not called. # # dpipe() initializes a decay pipeline and returns a pipeline object. # # decay() marks an object, unmarks another, and advances the clock. # ############################################################################ # # dpipe(proc, length, gc1, gc2) -- create a decay pipeline # # dpipe() initializes a decay pipeline and returns a pipeline object. # # proc user marking procedure: proc(gc, i) marks entry i using gc # length length of the delay pipeline (number of steps) # gc1 gc to mark an entry when it becomes active # gc2 gc to mark an entry when it decays (becomes inactive) # # decay(dp, i) -- mark entry i with later decay # # decay() marks an object, unmarks another, and advances the clock. # # Using decay pipe dp, entry i (anything but &null) is drawn in an # active state, and the oldest entry in the pipe is drawn in an # inactive state. # # Records are kept, though, so that an already-active entry is not # redrawn, and a decayed entry reaching the end of the pipe is not # drawn as inactive if it was more recently renewed. # # The decay pipe can be flushed by a sufficient number of # decay(dp, &null) calls. # ############################################################################ # # Requires: Version 9 graphics # ############################################################################ record Decay_Rec( # decay pipe record pipe, # queue of active indices tab, # table of activity for each index proc, # marking procedure gc1, # gc to use to turn on gc2) # gc to use to turn off ## dpipe(proc, length, gc1, gc2) -- create a decay pipeline procedure dpipe(proc, length, gc1, gc2) #: create a decay pipeline return Decay_Rec(list(length), table(0), proc, gc1, gc2) end ## decay(dp, i) -- mark entry i with later decay procedure decay(dp, i) #: mark entry for later decay local j j := get(dp.pipe) if (dp.tab[\i] +:= 1) = 1 then dp.proc(dp.gc1, i) if (dp.tab[\j] -:= 1) = 0 then dp.proc(dp.gc2, j) put(dp.pipe, i) end