<> <> <> <> <> DIRECTORY CD USING [ApplicationPtr, ObPtr, DrawProc, DrawRectProc, Design, DrawRef, NewNullDeviceDrawRef, original], RefTab USING [Create, Insert, Fetch, Ref], SpinifexCellPredicates USING [IsLogicalCell, CellPredicateProc], SpinifexInvert ; SpinifexInvertImpl: CEDAR PROGRAM IMPORTS CD, RefTab, SpinifexCellPredicates EXPORTS SpinifexInvert ~ BEGIN Inversion: TYPE ~ SpinifexInvert.Inversion; Invert: PUBLIC PROCEDURE [design: CD.Design, appls: LIST OF CD.ApplicationPtr, ClientData: SpinifexInvert.ClientDataProc _ NIL, IsCell: SpinifexCellPredicates.CellPredicateProc _ SpinifexCellPredicates.IsLogicalCell] RETURNS [leaves: LIST OF REF Inversion] ~ { dr: CD.DrawRef ~ CD.NewNullDeviceDrawRef[design]; leafList: LIST OF REF Inversion ~ CONS[NIL, NIL]; lilith: REF Inversion ~ NEW[Inversion _ [childCount~ 0, parents~ NIL, cell~ NIL, data~ NIL]]; idRef: REF InvData ~ NEW[InvData _ [listTail~ leafList, parent~ lilith, design~ design, parentData~ NIL, ClientData~ ClientData, IsCell~ IsCell, CellTab~ RefTab.Create[997]]]; dr.drawChild _ InvCell; dr.drawRect _ dr.saveRect _ Oops; dr.devicePrivate _ idRef; FOR al: LIST OF CD.ApplicationPtr _ appls, al.rest WHILE al # NIL DO InvCell[al.first, [0,0], CD.original, dr]; ENDLOOP; leaves _ NIL; FOR invList: LIST OF REF Inversion _ leafList.rest, invList.rest WHILE invList # NIL DO IF invList.first.childCount = 0 THEN { leaves _ CONS[ invList.first, leaves] } ENDLOOP; IF leaves = NIL THEN ERROR; }; Oops: CD.DrawRectProc ~ { ERROR }; InvData: TYPE ~ RECORD [ listTail: LIST OF REF Inversion, parent: REF Inversion, design: CD.Design, parentData: REF ANY, ClientData: SpinifexInvert.ClientDataProc, IsCell: SpinifexCellPredicates.CellPredicateProc, CellTab: RefTab.Ref ]; InvCell: CD.DrawProc -- [aptr: ApplicationPtr, pos: DesignPosition, orient: Orientation, pr: REF DrawInformation] -- ~ { data: REF InvData ~ NARROW[pr.devicePrivate]; <> IF ~data.IsCell[aptr.ob] THEN { IF aptr.ob.p.inDirectory THEN aptr.ob.p.drawMe[ aptr, pos, orient, pr] } ELSE { <> thisCell: REF Inversion; tc: REF ANY; <> WITH tc _ data.CellTab.Fetch[aptr.ob].val SELECT FROM this: REF Inversion => thisCell _ this; ENDCASE => IF tc # NIL THEN ERROR ELSE { <> thisCellParent: REF Inversion~ data.parent; thisCell _ NEW[Inversion _ [childCount~ 0, parents~ NIL, cell~ aptr.ob, data~ IF data.ClientData = NIL THEN NIL ELSE data.ClientData[data.design, aptr, pos, orient, thisCellParent] ]]; <> data.parent _ thisCell; aptr.ob.p.drawMe[ aptr, [0,0], CD.original, pr]; data.parent _ thisCellParent; IF ~data.CellTab.Insert[aptr.ob, thisCell] THEN ERROR; data.listTail.rest _ CONS[thisCell, NIL]; data.listTail _ data.listTail.rest; }; <> IF data.parent # NIL THEN { IF thisCell.parents = NIL THEN { thisCell.parents _ CONS[data.parent, NIL]; data.parent.childCount _ data.parent.childCount.SUCC } ELSE { FOR p: LIST OF REF Inversion _ thisCell.parents, p.rest DO IF p.first = data.parent THEN EXIT; IF p.rest = NIL THEN { p.rest _ CONS[data.parent, NIL]; data.parent.childCount _ data.parent.childCount.SUCC; EXIT } ENDLOOP; } } } }; END.