DIRECTORY D2Basic USING [Number, Pos, Rect]; CS: CEDAR DEFINITIONS = BEGIN Number: TYPE = D2Basic.Number; Pos: TYPE = D2Basic.Pos; Rect: TYPE = D2Basic.Rect; all: Rect = [Number.FIRST, Number.FIRST, Number.LAST, Number.LAST]; Tile: TYPE = REF --READONLY-- TileRec; TileRec: TYPE = RECORD [ --all fields readonly eN, sW: Tile _ NIL, nE, wS: LONG POINTER TO TileRec _ NIL, pos: Pos, value: REF _ NIL -- NIL for space tiles ]; Tesselation: TYPE = REF TesselationRec; TesselationRec: TYPE = RECORD [ state: State,--readonly immute: PRIVATE BOOL _ FALSE, current, southEast: PRIVATE Tile _, --readonly tileCount: PRIVATE INT _ 1, --readonly stopFlag: REF BOOL, data: REF ]; State: TYPE = RECORD [ --readonly r: Rect_all, yf: Number_LAST[Number], --fathers limitting y ys: Number_LAST[Number] --lowest sons lowest y ]; NewTesselation: PROC [data: REF _ NIL, stopFlag: REF BOOL _ NIL] RETURNS [Tesselation]; ResetTesselation: PROC [plane: Tesselation]; DumpCache: PROC; ChangeRect: PROC [plane: Tesselation, rect: Rect, new: REF _ NIL]; ChangeTile: PROC [plane: Tesselation, tile: Tile, new: REF _ NIL]; ChangeEnumerateArea: PROC [plane: Tesselation, rect: Rect, eachRect: RectProc, data: REF _ NIL, skip: REF]; RectProc: TYPE = PROC [plane: Tesselation, rect: Rect, oldValue: REF, data: REF]; FindTile: PROC [plane: Tesselation, pos: Pos] RETURNS [Tile]; TileProc: TYPE = PROC [tile: Tile, data: REF]; EnumerateArea: PROC [plane: Tesselation, rect: Rect, eachTile: TileProc, data: REF _ NIL, skip: REF _ NIL]; ListArea: PROC [plane: Tesselation, rect: Rect, skip: REF _ NIL] RETURNS [LIST OF REF Region]; Region: TYPE = RECORD [rect: Rect, value: REF]; -- value NIL for space tiles EN: PROC [tile: Tile] RETURNS [Tile] = INLINE { RETURN [tile.eN] }; NE: PROC [tile: Tile] RETURNS [Tile] = INLINE { TRUSTED { RETURN [LOOPHOLE[tile.nE]] } }; WS: PROC [tile: Tile] RETURNS [Tile] = INLINE { TRUSTED { RETURN [LOOPHOLE[tile.wS]] } }; SW: PROC [tile: Tile] RETURNS [Tile] = INLINE { RETURN [tile.sW] }; Area: PROC [t: Tile] RETURNS [Rect] = TRUSTED INLINE { RETURN [[x1: t.pos.x, y1: t.pos.y, x2: t.nE.pos.x, y2: t.eN.pos.y]] }; NEdge: PROC [t: Tile] RETURNS [Number] = INLINE {RETURN [t.eN.pos.y]}; EEdge: PROC [t: Tile] RETURNS [Number] = TRUSTED INLINE {RETURN [t.nE.pos.x]}; SEdge: PROC [t: Tile] RETURNS [Number] = INLINE {RETURN [t.pos.y]}; WEdge: PROC [t: Tile] RETURNS [Number] = INLINE {RETURN [t.pos.x]}; IsEmpty: PROC [plane: Tesselation, rect: Rect _ all, skip: REF _ NIL] RETURNS [BOOL]; BBox: PROC [plane: Tesselation, rect: Rect _ all, skip: REF _ NIL] RETURNS [bBox: Rect]; END. ζCS.mesa Copyright c 1983, 1986 by Xerox Corporation. All rights reserved. Written by Mark Shand, September 12, 1983 11:40 pm Last Edited by: McCreight, November 28, 1983 5:53 pm Last Edited by: Jacobi, January 22, 1986 10:27:05 am PST Re written by Christian Jacobi, January 18, 1986 11:33:07 am PST Last Edited by Christian Jacobi, January 22, 1986 11:59:13 am PST -- Types. --WARNING: Conventions are different from D2Basic and ChipNDale: --In CornerStitching, lower left border is inclusive; upper right border is exclusive. --(In original D2Basic all borders are inclusive). -- Tiles are recollected whenever they are not part of a tesselation! dont keep on to tiles. -- Corner stitching with ref's is too circular for the current Cedar safestorage, -- therefore two stitches are made pointers (idea of Mark Brown). --eN... eastern-most neighbour to the North; capitalization enlightens asymetry) --pos: lower left corner --use only NewTesselation to create Tesselations (Finalization!) --data: reserved for clients --stopFlag: reserved for clients --All procedures sharing a tesselation must be synchrounized by caller; --Cornerstitching itself does not monitor clients (even if using the same tesselation). --But synchrounization errors can propagate to unrelated tesselations. -- Worlds. --creates a new tesselation -- returns the tile memory; tesselation is ready for fresh usage --returns cached memory used global for tiles of all tesselations -- Modifying. --change the rect having new as tile value --beware: rect must lie completely in the changeable area (even for identity changes) --change a tile --beware: tile must lie completely in the changeable area (even for identity changes) -- For each rectangle in rect (with value # skip) call "eachRect"; (rect must be changeable) -- eachRect is must not change any point outside its rect area. -- outside eachRect's rect the maximal size properties dont hold while the enumeration. -- Enumerations. --finds the tile which contains the point at pos --enumerates all the tiles covering points of rect in plane. --while the enumeration the plane must not be changed --data: passed through to the eachTile procedure. --skip: tiles with value skip will be ignored and not enumerated. -- To get every tile, set skip to some value not existing value (e.g. NEW[INT]). --rect must must be changeable or the maximal size properties dont hold -- In EnumerateArea the order of enumeration is well defined. A tile appears in the enumeration immediately after the last of its children. Where tileA is defined to be a child of tileB iff its sW stitch points to tileB. Children are ordered such that the southernmost is the last. For tiles touching the western and southern borders these rules do not apply, these tiles are parent-less. Such tiles appear at some point after all the parent-less tiles touching touching a given parent-less tile's northern and western borders have been enumerated. --Returns a list of regions describing the area rect in the tesselation plane. --Regions with tile value skip are not returned. --rect must must be changeable or the maximal size properties dont hold -- Stepping from Tile to Tile. -- Coordinates increase from south to north, and west to east. All tile worlds are -- bordered by tiles at infinity so bounded searches wil never find NIL tiles. -- never need worry about tile = NIL. -- The tiles at infinity are not stitched to tiles in the Tesselation, rather they are -- stitched to each other in the manner of the bevelled edges of a picture frame. -- The meanings of the stepping routines are as follows ... -- EN  eastern most tile to the north -- NE  northern most tile to the east -- WS  western most tile to the south -- SW  southern most tile to the west -- Enquiries --rect of tile; (upper and right border exclusive) --returns whether rect in plane has only tiles with value skip. --rect must must be changeable --returns a minimal bounding box for non-skip tiles in rect --rect must must be changeable. ΚM˜code™Kšœ Οmœ7™BK™2K™4K™8K™@K™A—šΟk ˜ Kšœžœ˜"—K˜KšΡbklœžœž œ˜šž˜K˜—šœ ™ K˜Kšœžœ˜Kšœžœ˜šœžœ˜KšžΠbkœ7™@KšžœT™VKšžœ0™2—K˜š œžœ žœ žœ žœ˜CK˜—K˜Kšœžœžœž œ ˜&šœ žœžœΟc˜.Kšœžœ˜Kš œžœžœžœ žœ˜&Kšœ ˜ Kšœžœžœ‘˜'K˜K˜Kšœ]™]KšœR™RKšœC™CKšœΟbœ’œ)™PKšœ™K™—K˜Kšœ žœžœ˜'šœžœžœ˜Kšœ ‘ ˜Kšœžœžœžœ˜Kšœžœ ‘ ˜/Kšœ žœžœ‘ ˜&Kšœ žœžœ˜Kšœž˜ Kšœ˜Kšœ@™@Kšœ™Kšœ ™ —K™šœžœžœ‘ ˜!K˜ Kšœ žœ ‘˜.Kšœ žœ ‘˜.K˜—K™K™HK™YK™FK™K™—š‘ ™ K˜šΟnœžœžœžœ žœžœžœžœ˜WKšœ™—K˜š£œžœ˜,Kšœ@™@—K˜š£ œžœ˜K™A—K™K™—š‘ ™ K˜š£ œžœ'žœžœ˜BKšœ*™*KšœU™U—K˜š£ œžœ'žœžœ˜BKšœ™KšœV™V—K˜š £œžœ<žœžœžœ˜kKšœ\™\Kšœ?™?KšœW™W—K˜Kš œ žœžœ,žœžœ˜QK˜K™—š‘™K˜š£œžœ žœ˜=Kšœ0™0—K˜Kšœ žœžœžœ˜.K™š £ œžœ<žœžœžœžœ˜kKšœ?™?Kšœ5™5Kšœ2™2KšœD™DKšœT™TKšœG™GK™K™Kšœ©™©—K˜š£œžœ(žœžœžœžœžœžœ ˜^KšœN™NKšœ0™0KšœG™GK™K˜—Kš œžœžœžœ‘œ‘˜LK˜K™—š‘™K™KšœT™TKšœO™OKšœ'™'KšœW™WKšœS™Sšœ;™;Kšœ&™&Kšœ&™&Kšœ&™&Kšœ&™&—K˜š£œžœžœ žœ˜/Kšžœ ˜K˜—š£œžœžœ žœ˜/Kšžœžœžœ ˜&K˜—š£œžœžœ žœ˜/Kšžœžœžœ ˜&K˜—š£œžœžœ žœ˜/Kšžœ ˜K˜—K™K™—šœ ™ K˜š £œžœ žœ žœžœ˜6K™2Kšžœ=˜CK˜—K˜Kš £œžœ žœ žœžœ˜FKš £œžœ žœ žœžœ˜NKš £œžœ žœ žœžœ ˜CKš £œžœ žœ žœžœ ˜CK™š £œžœ.žœžœžœžœ˜UKšœ?™?Kšœ™K˜—š £œžœ.žœžœžœ˜XKšœ;™;Kšœ™K™—K™—Kšžœ˜—…— 4 g