DIRECTORY CD, CDMarks, CDDirectory, CDValue; CDMarksImpl: CEDAR MONITOR IMPORTS CD, CDDirectory, CDValue EXPORTS CDMarks = BEGIN MarkRange: TYPE = CDMarks.MarkRange; ClearAllAccessibleMarks: PUBLIC ENTRY PROC [design: CD.Design] = BEGIN InternalClearAllAccessibleMarks[design]; CDValue.StoreInt[boundTo: design, key: markKey, value: 0]; END; InternalClearAllAccessibleMarks: INTERNAL PROC [design: CD.Design] = BEGIN FOR l: LIST OF CD.PushRec _ design.actual, l.rest WHILE l#NIL DO ClearMarksOfList[l.first.specific.contents] ENDLOOP; [] _ CDDirectory.Enumerate[design, EachEntryClearMark]; END; EachEntryClearMark: CDDirectory.EachEntryAction = --[name: Rope.ROPE, ob: CD.ObPtr] RETURNS [quit: BOOL] -- BEGIN EnumerateChildren: PROC [me: CD.ObPtr, x: REF] = { me.marked _ 0 }; ob.marked _ 0; IF ob.p.inDirectory THEN WITH ob.specificRef SELECT FROM cp: CD.CellPtr => ClearMarksOfList[cp.contents]; ENDCASE => CDDirectory.EnumerateChildObjects[me: ob, p: EnumerateChildren, x: NIL]; quit _ FALSE; END; ClearMarksOfList: PROC [list: CD.ApplicationList] = INLINE BEGIN FOR w: CD.ApplicationList _ list, w.rest WHILE w#NIL DO w.first.ob.marked _ 0; ENDLOOP; END; MarkUnMarkedInclusiveChildren: PUBLIC PROC [design: CD.Design, ob: CD.ObPtr, value: MarkRange] = BEGIN EnumerateChildren: PROC [me: CD.ObPtr, x: REF] = { IF me.marked#value THEN { MarkUnMarkedInclusiveChildren[design, me, value]; me.marked _ value; } }; IF ob.marked#value THEN { IF ob.p.inDirectory THEN WITH ob.specificRef SELECT FROM cellPtr: CD.CellPtr => -- speed up cells FOR w: CD.ApplicationList _ cellPtr.contents, w.rest WHILE w#NIL DO IF w.first.ob.marked#value THEN { IF w.first.ob.p.inDirectory THEN MarkUnMarkedInclusiveChildren[design, w.first.ob, value] ELSE w.first.ob.marked_value } ENDLOOP; ENDCASE => CDDirectory.EnumerateChildObjects[me: ob, p: EnumerateChildren, x: NIL]; ob.marked _ value; } END; PreviousMarkWasNotReleased: PUBLIC ERROR = CODE; GetNewMark: PUBLIC ENTRY PROC [design: CD.Design] RETURNS [MarkRange] = BEGIN i: INT _ CDValue.FetchInt[boundTo: design, key: markKey, propagation: design, ifNotFound: 0]; IF i<0 THEN RETURN WITH ERROR PreviousMarkWasNotReleased; IF i=LAST[MarkRange] THEN { InternalClearAllAccessibleMarks[design]; i _ 0 }; CDValue.StoreInt[boundTo: design, key: markKey, value: -(i+1)]; RETURN [i+1] END; ReleaseMark: PUBLIC ENTRY PROC [design: CD.Design, mark: MarkRange] = BEGIN i: INT _ CDValue.FetchInt[boundTo: design, key: markKey, propagation: design, ifNotFound: 0]; IF -i#mark THEN RETURN WITH ERROR CD.Error[callingError, "CDMarks.ReleaseMark: mark is not current value"]; CDValue.StoreInt[boundTo: design, key: markKey, value: -i]; END; markKey: REF INT = NEW[INT]; --negative value means mark is in use CDValue.EnregisterKey[key: markKey, boundTo: NIL]; END. œCDMarksImpl.mesa a ChipNDale module Copyright c 1983, 1985 by Xerox Corporation. All rights reserved. by Christian Jacobi, July 12, 1983 2:36 pm last edited by Christian Jacobi, March 5, 1984 5:58:10 pm PST -- if object has children, they are accessed through celldirectory --gets new value to be used as a mark --if all values are already used, it has to clear all accessible marks and will be slow. Êk˜šœ%™%Jšœ Ïmœ7™BJšœ+™+Jšœ=™=J˜—šÏk ˜ Jšžœ˜J˜Jšœ ˜ Jšœ˜J˜—šÏn œžœžœ˜Jšžœ˜!Jšžœ ˜—Jšž˜J˜Jšœ žœ˜$J˜šŸœžœž œ žœ ˜@Jšž˜Jšœ(˜(Jšœ:˜:Jšžœ˜—J˜šŸœž œ žœ ˜DJšž˜š žœžœžœžœ!žœžœž˜@J˜,Jšžœ˜—Jšœ7˜7Jšžœ˜—J˜šŸœ ˜2JšÏcœ žœžœ œ˜:Jšž˜J˜šŸœžœžœ žœ˜2Jšœ ˜ Jšœ˜—J˜Jšœ˜šžœž˜šžœžœž˜Jšœžœ*˜0JšžœHžœ˜T——Jšœžœ˜ Jšžœ˜—J˜šŸœžœžœ˜3Jšž ˜ š žœžœ žœžœž˜7Jšœ˜J™BJšžœ˜—Jšžœ˜—J˜š Ÿœžœžœ žœ žœ˜`Jšž˜J˜šŸœžœžœ žœ˜3šžœžœ˜Jšœ1˜1Jšœ˜J˜—Jšžœ˜—J˜šžœžœ˜šžœžœ˜šžœžœž˜šœ žœ  ˜(š žœžœ,žœžœž˜Cšžœžœ˜"Jšžœžœ9˜YJšžœ˜Jšœ˜—Jšžœ˜——JšžœGžœ˜S——Jšœ˜J˜—Jšžœ˜—J˜Jšœžœžœžœ˜0J˜š Ÿ œžœžœžœ žœ žœ˜GJšœ%™%JšœX™XJšž˜JšœžœW˜]Jšžœžœžœ˜9šžœžœ žœ˜Jšœ)˜)Jšœ˜Jšœ˜—Jšœ?˜?Jšžœ˜ Jšžœ˜—J˜š Ÿ œžœžœžœ žœ˜EJšž˜JšœžœW˜]šžœ žœžœžœ˜JšžœžœG˜O—Jšœ;˜;Jšžœ˜—J˜Jš œ žœžœžœžœ %˜BJšœ-žœ˜2Jšžœ˜J˜—…—