-- PolyImpl.mesa -- Last changed by Doug Wyatt, September 19, 1980 2:02 PM DIRECTORY Poly, Vector USING [Vec], Area USING [Rec, Handle, Object, Procs], Boxer USING [Handle, New, Put, Rectangle, Free], Memory USING [zone]; PolyImpl: PROGRAM IMPORTS Memory,Boxer EXPORTS Poly SHARES Poly,Area = { OPEN Poly; zone: UNCOUNTED ZONE = Memory.zone; Node: TYPE = RECORD[next: NodeRef, v: Vector.Vec]; NodeRef: TYPE = LONG POINTER TO Node; free: NodeRef _ NIL; -- head of list of free Nodes NewNode: PROC[v: Vector.Vec] RETURNS[NodeRef] = --INLINE-- { n: NodeRef_free; IF n=NIL THEN n_zone.NEW[Node] ELSE free_n.next; n^_[next: NIL, v: v]; RETURN[n]; }; FreeList: PROC[head,tail: NodeRef] = --INLINE-- { tail.next_free; free_head; }; Data: PUBLIC TYPE = RECORD[ head,tail: NodeRef, boxer: Boxer.Handle, rect: BOOLEAN ]; DataRef: TYPE = LONG POINTER TO Data; AData: TYPE = RECORD[head,tail: NodeRef, rec: Area.Rec]; ADataRef: TYPE = LONG POINTER TO AData; eprocs: LONG POINTER TO READONLY Procs = zone.NEW[Procs = [ Put: EPut, NewArea: ENewArea, Free: EFree ]]; fprocs: LONG POINTER TO READONLY Procs = zone.NEW[Procs = [ Put: FPut, NewArea: FNewArea, Free: FFree ]]; pAreaProcs: LONG POINTER TO READONLY Area.Procs = zone.NEW[Area.Procs = [ Vertices: PVertices, Rectangle: ARectangle, Free: PFree ]]; rAreaProcs: LONG POINTER TO READONLY Area.Procs = zone.NEW[Area.Procs = [ Vertices: RVertices, Rectangle: ARectangle, Free: RFree ]]; New: PUBLIC PROC RETURNS[Handle] = { d: DataRef = zone.NEW[Data _ [ head: NIL, tail: NIL, boxer: NIL, rect: FALSE]]; RETURN[zone.NEW[Object _ [procs: eprocs, data: d]]]; }; EPut: PROC[self: Handle, v: Vector.Vec] = { d: DataRef=self.data; d.head_d.tail_NewNode[v]; d.boxer_Boxer.New[]; Boxer.Put[d.boxer,v]; d.rect_TRUE; self.procs_fprocs; }; FPut: PROC[self: Handle, v: Vector.Vec] = { d: DataRef=self.data; u: Vector.Vec=d.tail.v; n: NodeRef=NewNode[v]; d.tail.next_n; d.tail_n; Boxer.Put[d.boxer,v]; IF u.x#v.x AND u.y#v.y THEN d.rect_FALSE; }; ENewArea: PROC[self: Handle] RETURNS[Area.Handle] = { RETURN[NIL] }; FNewArea: PROC[self: Handle] RETURNS[Area.Handle] = { d: DataRef=self.data; a: ADataRef = zone.NEW[AData _ [ head: NIL, tail: NIL, rec: Boxer.Rectangle[d.boxer] ]]; u: Vector.Vec=d.tail.v; v: Vector.Vec=d.head.v; IF u.x#v.x AND u.y#v.y THEN d.rect_FALSE; IF d.rect THEN FreeList[d.head,d.tail] ELSE { a.head_d.head; a.tail_d.tail }; d.head_d.tail_NIL; Boxer.Free[@d.boxer]; self.procs_eprocs; RETURN[zone.NEW[Area.Object _ [ procs: IF d.rect THEN rAreaProcs ELSE pAreaProcs, data: LOOPHOLE[a], rect: d.rect ]]]; }; EFree: PROC[self: Handle] = { d: DataRef_self.data; zone.FREE[@d]; zone.FREE[@self] }; FFree: PROC[self: Handle] = { d: DataRef_self.data; FreeList[d.head,d.tail]; Boxer.Free[@d.boxer]; zone.FREE[@d]; zone.FREE[@self]; }; NewRec: PUBLIC PROC[rec: Area.Rec] RETURNS[Area.Handle] = { a: ADataRef = zone.NEW[AData _ [head: NIL, tail: NIL, rec: rec]]; RETURN[zone.NEW[Area.Object _ [ procs: rAreaProcs, data: LOOPHOLE[a], rect: TRUE]]]; }; PVertices: PROC[self: Area.Handle, Proc: PROC[Vector.Vec]] = { a: ADataRef=LOOPHOLE[self.data]; FOR n: NodeRef_a.head,n.next UNTIL n=NIL DO Proc[n.v] ENDLOOP; }; RVertices: PROC[self: Area.Handle, Proc: PROC[Vector.Vec]] = { a: ADataRef=LOOPHOLE[self.data]; r: Area.Rec=a.rec; Proc[[r.ll.x,r.ll.y]]; Proc[[r.ur.x,r.ll.y]]; Proc[[r.ur.x,r.ur.y]]; Proc[[r.ll.x,r.ur.y]]; }; ARectangle: PROC[self: Area.Handle] RETURNS[Area.Rec] = { a: ADataRef=LOOPHOLE[self.data]; RETURN[a.rec]; }; PFree: PROC[self: Area.Handle] = { a: ADataRef_LOOPHOLE[self.data]; FreeList[a.head,a.tail]; zone.FREE[@a]; zone.FREE[@self]; }; RFree: PROC[self: Area.Handle] = { a: ADataRef_LOOPHOLE[self.data]; zone.FREE[@a]; zone.FREE[@self]; }; }.(670)