############################################################################ # # File: alcscope.icn # # Subject: Program to visualize allocation as a kaleidoscopic display # # Author: Ralph E. Griswold # # Date: July 14, 1997 # ############################################################################ # # This file is in the public domain. # ############################################################################ # # This program displays kaleidoscopic images. The controls on the # user interface are relatively intuitive -- trying them will give # a better idea of what's possible than a prose description here. # # This program is based on an earlier one by Steve Wampler, which in # turn was based on a C program by Lorraine Callahan. # # This version is adapted to visualize storage management. # ############################################################################ # # Requires: Version 9 graphics # ############################################################################ # # Links: interact, random, vsetup # ############################################################################ link interact link vsetup link colormap link evinit # Interface globals global vidgets # table of vidgets global root # the root vidget global size # size of view area (width & height) global half # half size of view area global pane # graphics context for viewing # Parameters that can be set from the interface global delayval # delay between drawing circles global density # number of circles in steady state global draw_proc # drawing procedure global max_off # maximum offset of circle global min_off # minimum offset of circle global scale # scaling factor for sizes global color # color table # State information global draw_list # list of pending drawing parameters global reset # nonnull when view area needs resetting global state # nonnull when display paused $include "evdefs.icn" procedure main(args) init(args) kaleidoscope() end procedure init(args) color := colormap() vidgets := ui() root := vidgets["root"] size := vidgets["region"].uw if vidgets["region"].uh ~= size then stop("*** improper interface layout") # Set initial values. draw_proc := FillCircle state := &null # Initialize vidget values. density := VGetState(vidgets["density"]) delayval := VGetState(vidgets["speed"]) scale := VGetState(vidgets["scale"]) VSetState(vidgets["shape"], "rings") # Get graphics context for drawing. half := size / 2 pane := Clone("bg=black", "dx=" || (vidgets["region"].ux + half), "dy=" || (vidgets["region"].uy + half), "drawop=reverse") Clip(pane, -half, -half, size, size) EvInit(args) | ExitNotice("Cannot load SP.") every variable("write" | "writes", &eventsource) := -1 return end procedure kaleidoscope() # Each time through this loop, the display is cleared and a # new drawing is started. repeat { EraseArea(pane, -half, -half, size, size) # clear display draw_list := [] # new drawing list reset := &null # In this loop a new circle is drawn and an old one erased, once the # specified density has been reached. This maintains a steady state. repeat { while (*Pending() > 0) | \state do { ProcessEvent(root, , shortcuts) if \reset then break break next } putcircle() WDelay(delayval) # Don't start clearing circles until the specified density has # reached. (The drawing list has four elements for each circle.) if *draw_list > (4 * density) then clrcircle() } } end procedure putcircle() local off1, off2, radius, fg EvGet(AllocMask) | ExitNotice("SP terminated.") fg := color[&eventcode] radius := sqrt(&eventvalue * scale) # get a random center point and radius off1 := ?size % half off2 := ?size % half put(draw_list, off1, off2, radius, fg) outcircle(off1, off2, radius, fg) return end procedure clrcircle() outcircle( get(draw_list), # off1 get(draw_list), # off2 get(draw_list), # radius get(draw_list) # color ) return end procedure outcircle(off1, off2, radius, color) Fg(pane, color) # Draw in symmetric positions. draw_proc(pane, off1, off2, radius) draw_proc(pane, off1, -off2, radius) draw_proc(pane, -off1, off2, radius) draw_proc(pane, -off1,-off2, radius) draw_proc(pane, off2, off1, radius) draw_proc(pane, off2, -off1, radius) draw_proc(pane, -off2, off1, radius) draw_proc(pane, -off2,-off1, radius) return end procedure density_cb(vidget, value) density := value reset := 1 end procedure speed_cb(vidget, value) delayval := value return end procedure file_cb(vidget, value) case value[1] of { "snapshot @S": snapshot(pane, -half, -half, size, size) "quit @Q": exit() } return end procedure scale_cb(vidget, value) scale := value return end procedure pause_cb(vidget, value) state := value return end procedure reset_cb(vidget, value) reset := 1 return end procedure shape_cb(vidget, value) draw_proc := case value of { "discs": FillCircle "rings": DrawCircle } reset := 1 return end procedure shortcuts(e) if &meta then case map(e) of { # fold case "q": exit() "s": snapshot(pane, -half, -half, size, size) } return end #===<>=== modify using vib; do not remove this marker line procedure ui_atts() return ["size=600,455", "bg=gray-white", "label=kaleido"] end procedure ui(win, cbk) return vsetup(win, cbk, [":Sizer:::0,0,600,455:kaleido",], ["density:Slider:h:1:41,171,100,15:10,100,50",density_cb], ["file:Menu:pull::12,3,36,21:File",file_cb, ["snapshot @S","quit @Q"]], ["label07:Label:::7,120,28,13:slow",], ["label08:Label:::151,120,28,13:fast",], ["label10:Label:::64,270,7,13:1",], ["label11:Label:::124,270,7,13:5",], ["label12:Label:::47,200,14,13:10",], ["label13:Label:::116,200,21,13:100",], ["label14:Label:::78,200,14,13:50",], ["label9:Label:::43,270,14,13:.2",], ["lbl_density:Label:::67,151,49,13:density",], ["lbl_scale:Label:::74,220,35,13:scale",], ["lbl_speed:Label:::74,100,35,13:speed",], ["line:Line:::0,30,600,30:",], ["line1:Line:::68,256,68,266:",], ["line2:Line:::128,256,128,266:",], ["line3:Line:::54,256,54,266:",], ["line4:Line:::128,186,128,196:",], ["line5:Line:::55,186,55,196:",], ["line6:Line:::86,186,86,196:",], ["pause:Button:regular:1:33,55,45,20:pause",pause_cb], ["reset:Button:regular::111,55,45,20:reset",reset_cb], ["scale:Slider:h:1:42,240,100,15:0.1,5,1",scale_cb], ["shape:Choice::2:64,330,64,42:",shape_cb, ["discs","rings"]], ["speed:Slider:h:1:41,121,100,15:100,0,0",speed_cb], ["region:Rect:raised::187,42,400,400:",], ) end #===<>=== end of section maintained by vib