<> <> <> <> <> <> <> CornerStitching: CEDAR DEFINITIONS ~ BEGIN <> Number: TYPE = INT; Position: TYPE = RECORD [x, y: Number]; Rect: TYPE = RECORD [x1, y1, x2, y2: Number]; <<--a Rect is called normalized if (x1>x2) OR (y1>y2) means that the Rect is empty.>> <<--Rect's are closed: they include all the endpoints; as you expect, points have size 0.>> <> NewTesselation: PROCEDURE RETURNS [REF Tesselation]; FreeTesselation: PROCEDURE [plane: REF Tesselation]; CoerceToTesselation: PROCEDURE [ref: REF ANY] RETURNS [REF Tesselation]; -- may raise NarrowRefFault <> ChangeRect: PROCEDURE [plane: REF Tesselation, rect: Rect, newvalue: REF ANY _ NIL, checkOldvalue: BOOLEAN _ TRUE, oldvalue: REF ANY _ NIL]; -- Raises TileValue ERROR if checkOldvalue AND the value of a tile in rect # oldvalue. SafeChangeTile: PROCEDURE [plane: REF Tesselation, tile: TilePtr, newvalue: REF ANY] ~ INLINE { <<-- Let a client change a tile provided it doesn't violate invariants.>> TRUSTED { IF tile.ne.value = newvalue OR tile.sw.value = newvalue OR (tile.en.value = newvalue AND tile.en.pos.x = tile.pos.x AND tile.en.ne.pos.x = tile.ne.pos.x) OR (tile.ws.value = newvalue AND tile.ws.pos.x = tile.pos.x AND tile.ws.ne.pos.x = tile.ne.pos.x) THEN ERROR }; tile.value _ newvalue }; <> <> PerTileProc: TYPE ~ PROCEDURE [tile: TilePtr, data: REF ANY] RETURNS [REF ANY]; <> EnumerateArea: PROCEDURE [plane: REF Tesselation, rect: Rect, perTile: PerTileProc _ NIL, data: REF ANY _ NIL, backgroundValue: REF ANY _ NIL] RETURNS [REF ANY]; <<-- If perTile = NIL then returns LIST OF REF Region;>> TileAt: PROCEDURE [plane: REF Tesselation, pos: Position] RETURNS [TilePtr]; <> <> <> <> <> <> ENorthNeighbour: PROCEDURE [tile: TilePtr] RETURNS [TilePtr] ~ INLINE { RETURN [tile.en] }; NEastNeighbour: PROCEDURE [tile: TilePtr] RETURNS [TilePtr] ~ INLINE { TRUSTED { RETURN [LOOPHOLE[tile.ne]] } }; WSouthNeighbour: PROCEDURE [tile: TilePtr] RETURNS [TilePtr] ~ INLINE { TRUSTED { RETURN [LOOPHOLE[tile.ws]] } }; SWestNeighbour: PROCEDURE [tile: TilePtr] RETURNS [TilePtr] ~ INLINE { RETURN [tile.sw] }; <> Value: PROCEDURE [tile: TilePtr] RETURNS [REF ANY] ~ INLINE { RETURN [tile.value] }; Area: PROCEDURE [tile: TilePtr] RETURNS [Rect] ~ INLINE { RETURN [[WestEdge[tile], SouthEdge[tile], EastEdge[tile], NorthEdge[tile]]] }; NorthEdge: PROCEDURE [t: TilePtr] RETURNS [INT] ~ INLINE {RETURN [t.en.pos.y]}; EastEdge: PROCEDURE [t: TilePtr] RETURNS [INT] ~ INLINE { TRUSTED { RETURN [t.ne.pos.x] } }; SouthEdge: PROCEDURE [t: TilePtr] RETURNS [INT] ~ INLINE {RETURN [t.pos.y]}; WestEdge: PROCEDURE [t: TilePtr] RETURNS [INT] ~ INLINE {RETURN [t.pos.x]}; <> AreaEmpty: PROCEDURE [plane: REF Tesselation, rect: Rect, backgroundValue: REF ANY _ NIL] RETURNS [BOOLEAN]; ContentsBound: PROCEDURE [plane: REF Tesselation, rect: Rect, backgroundValue: REF ANY _ NIL] RETURNS [bBox: Rect]; <<-- ContentsBound returns a minimal bounding box for non-backgroundValue tiles in rect>> <> TileValue: ERROR; TileDeleted: ERROR; <> <> TilePtr: TYPE ~ REF Tile; Tile: PRIVATE TYPE ~ RECORD [ <> en, sw: REF Tile _ NIL, ne, ws: LONG POINTER TO Tile _ NIL, pos: Coord, value: REF ANY _ NIL -- NIL for space tiles ]; Coord: PRIVATE TYPE ~ RECORD [x, y: INT]; Region: TYPE ~ RECORD [ rect: Rect, value: REF ANY _ NIL -- NIL for space tiles ]; Tesselation: TYPE ~ RECORD [ southEast, current: REF Tile _, deletionCache: REF Tile _ NIL, tilesInTesselationCount: INT _ 1 ]; END.