<> <> <> <> DIRECTORY Atom, CD, CDCells, CDDirectory, CDExtras, CDOps, CDPrivate, CDProperties, CDSimpleOps, Rope; CDExtrasImpl: CEDAR MONITOR IMPORTS Atom, CD, CDCells, CDDirectory, CDOps, CDProperties, CDSimpleOps, Rope EXPORTS CDExtras SHARES CD = BEGIN CreateDummyObject: PUBLIC PROC[design: CD.Design] RETURNS [CD.Object] = <<--create a dummy cell object which contains the whole design.>> <<--On future changes of the design, the dummy object may or may not>> <<--get obsolete.>> BEGIN cellOb: CD.Object _ CDCells.CreateEmptyCell[]; cptr: CD.CellPtr _ NARROW[cellOb.specificRef]; FOR l: LIST OF CD.PushRec _ design.actual, l.rest WHILE l#NIL DO cptr.contents _ CONS[ NEW[CD.InstanceRep _ [ ob: l.first.dummyCell.ob, location: [0, 0], orientation: CD.original, selected: FALSE ]], cptr.contents ]; ENDLOOP; RETURN [cellOb] END; Pair: TYPE = RECORD [p: CDDirectory.EnumerateObjectsProc, x: REF, key: REF]; EnumerationEnteredWhileInProgress: ERROR = CODE; entered: BOOL _ FALSE; Enter: ENTRY PROC [] = BEGIN IF entered THEN RETURN WITH ERROR EnumerationEnteredWhileInProgress; entered_TRUE; END; Leave: ENTRY PROC [] = BEGIN entered_FALSE; END; EnumerateChildrenObjects: PUBLIC PROC[me: CD.Object, p: CDDirectory.EnumerateObjectsProc, x: REF] = <<--enumerate me and its children objects>> BEGIN ENABLE UNWIND => Leave[]; pair: REF Pair _ NEW[Pair]; pair^ _ [p, x, pair]; Enter[]; MyEnum[me, pair]; Leave[]; END; MyEnum: PROC [me: CD.Object, x: REF] = BEGIN pair: REF Pair _ NARROW[x]; v: REF _ CDProperties.GetProp[me, $CDExtrasImplsTouched]; IF v=pair.key THEN RETURN; -- already visited <<--mark visited>> CDProperties.PutProp[me, $CDExtrasImplsTouched, pair.key]; <<--enumerate my children first>> IF me.class.inDirectory THEN CDDirectory.EnumerateChildObjects[me, MyEnum, x]; pair.p[me, pair.x]; -- call clients enumerator proc END; EnumerateDesignObjects: PUBLIC PROC [design: CD.Design, p: CDDirectory.EnumerateObjectsProc, x: REF] = BEGIN ENABLE UNWIND => Leave[]; EachChild: CDDirectory.EachEntryAction = {MyEnum[ob, pair]}; pair: REF Pair _ NEW[Pair]; pair^ _ [p, x, pair]; Enter[]; [] _ CDDirectory.Enumerate[design, EachChild]; FOR l: LIST OF CD.PushRec _ design.actual, l.rest WHILE l#NIL DO MyEnum[l.first.dummyCell.ob, pair]; IF l.first.mightReplace#NIL THEN MyEnum[l.first.mightReplace.ob, pair]; ENDLOOP; Leave[]; END; PopToTopLayer: PUBLIC PROC [design: CD.Design] = <<--if "design" is pushed in, it will be popped out, either by flushing, >> <<--replacing cells or creating new cells>> BEGIN WHILE design.actual.rest#NIL DO IF NOT CDCells.PopFromCell[design, newcell] THEN EXIT ENDLOOP; IF design.actual.rest#NIL THEN ERROR END; PopToTopLevel: PUBLIC PROC [design: CD.Design] = BEGIN WHILE CDCells.IsPushedIn[design] DO [] _ CDCells.PopFromCell[design, newcell, "--wasPushedIn--"]; ENDLOOP; END; Cellize: PUBLIC PROC [design: CD.Design, name: Rope.ROPE_NIL] RETURNS [cell: CD.Object_NIL, pos: CD.Position] = <<--makes a single "cell" of of the "design", removes all instances; >> <<--pos: if "cell" is included at position "pos" in an empty design we would get "design" again>> <<--if "design" is pushed in, it will be popped out, either by flushing, >> <<--replacing cells or creating new cells>> BEGIN done: BOOL; il: CD.InstanceList; PopToTopLayer[design]; CDSimpleOps.SelectAll[design]; IF (il_CDOps.InstList[design])#NIL THEN { IF il.rest=NIL AND ISTYPE[il.first.ob.specificRef, CD.CellPtr] AND il.first.orientation=CD.original THEN { cell _ il.first.ob; IF name#NIL THEN [] _ CDDirectory.Rename[design, cell, name]; done _ TRUE } ELSE { IF name=NIL THEN name _ design.name; IF name=NIL THEN name _ "no named design"; [done, cell] _ CDCells.CreateCellSelected[design, name]; }; IF done THEN { pos _ CDOps.InstList[design].first.location; } ELSE cell _ NIL }; CDOps.SetInstList[design, NIL] END; GetTechnology: PUBLIC PROC [name: Rope.ROPE] RETURNS [t: CD.Technology] = <<--far more friendly version of CD.GetTechnology>> <<--NIL if not found>> BEGIN EachTechnology: CD.TechnologyEnumerator = { IF Rope.Equal[tech.name, name, FALSE] OR Rope.Equal[Atom.GetPName[tech.key], name, FALSE] THEN {quit _ TRUE; t _ tech} }; [] _ CD.EnumerateTechnologies[EachTechnology]; END; END.