CDHierarchyMarksImpl.mesa (part of ChipNDale)
Copyright © 1986 by Xerox Corporation. All rights reserved.
Christian Jacobi, July 16, 1986 8:09:57 pm PDT
last edited by Christian Jacobi, July 17, 1986 11:29:46 am PDT
DIRECTORY
CD,
CDBasics,
CDCells,
CDCommandOps,
CDCommandOpsExtras2,
CDHierarchyMarks,
CDInstances,
CDOps,
CDProperties,
CDRects,
CDSequencer,
CDSimpleOps,
CDViewer,
CDViewHighlight,
RuntimeError USING [UNCAUGHT],
TerminalIO,
ViewerClasses USING [Viewer];
CDHierarchyMarksImpl: CEDAR MONITOR
IMPORTS CD, CDInstances, CDBasics, CDCells, CDCommandOps, CDCommandOpsExtras2, CDOps, CDProperties, CDRects, CDSequencer, CDSimpleOps, CDViewer, CDViewHighlight, RuntimeError, TerminalIO
EXPORTS CDHierarchyMarks =
BEGIN
SetHierarchyMarkProc: TYPE = CDHierarchyMarks.SetHierarchyMarkProc;
myKey: ATOM ← $CDHierarchyMark;
GetHierarchyMark: PUBLIC PROC [design: CD.Design←NIL, ob: CD.Object←NIL] RETURNS [inst: CD.Instance←NIL] = {
GetFrom: PROC [x: REF] RETURNS [inst: CD.Instance←NIL] = {
WITH CDProperties.GetProp[x, myKey] SELECT FROM
i: CD.Instance => RETURN [i];
ENDCASE => NULL;
};
IF ob#NIL THEN inst ← GetFrom[ob]
ELSE IF design#NIL THEN inst ← GetFrom[design];
};
ReallySetHierarchyMark: PROC [design: CD.Design, ob: CD.Object←NIL, inst: CD.Instance] = {
i2: CD.Instance;
inst ← CDInstances.Copy[inst];
IF design=NIL THEN {
IF ob#NIL THEN CDProperties.PutProp[ob, myKey, inst]
}
ELSE {
IF ob=NIL THEN {
CDProperties.PutProp[design, myKey, inst];
--put it also to the real top level cell
FOR list: LIST OF CD.PushRec ← design.actual, list.rest WHILE list#NIL DO
IF list.first.mightReplace=NIL THEN
CDProperties.PutProp[list.first.dummyCell.ob, myKey, inst]
ENDLOOP;
}
ELSE {
--put property to both, the mightReplace and the dummyCell, if it should go on either
FOR list: LIST OF CD.PushRec ← design.actual, list.rest WHILE list#NIL DO
IF list.first.dummyCell.ob=ob THEN {
CDProperties.PutProp[ob, myKey, inst];
IF list.first.mightReplace=NIL THEN CDProperties.PutProp[design, myKey, inst]
ELSE {
i2 ← CDInstances.DeComposed[inst, list.first.mightReplace.location, list.first.mightReplace.ob.size, list.first.mightReplace.orientation];
CDProperties.PutProp[list.first.mightReplace.ob, myKey, i2];
};
RETURN;
}
ENDLOOP;
FOR list: LIST OF CD.PushRec ← design.actual, list.rest WHILE list#NIL DO
IF list.first.mightReplace#NIL AND list.first.mightReplace.ob=ob THEN {
CDProperties.PutProp[ob, myKey, inst];
i2 ← CDInstances.Composed[inst, list.first.mightReplace.location, list.first.mightReplace.ob.size, list.first.mightReplace.orientation];
CDProperties.PutProp[list.first.dummyCell.ob, myKey, i2];
RETURN;
}
ENDLOOP;
--an ordinary cell; no pushed in state...
CDProperties.PutProp[ob, myKey, inst]
};
};
};
SetHierarchyMark: PUBLIC PROC [design: CD.Design, ob: CD.Object←NIL, inst: CD.Instance] = {
FOR list: LIST OF SetHierarchyMarkProc ← regList, list.rest WHILE list#NIL DO
list.first[design, ob, inst ! RuntimeError.UNCAUGHT => CONTINUE];
ENDLOOP;
};
regList: LIST OF SetHierarchyMarkProc;
RegisterHierarchyMarker: PUBLIC ENTRY PROC [setHierarchyMark: SetHierarchyMarkProc] = {
IF setHierarchyMark#NIL THEN {
IF regList=NIL THEN regList ← LIST[setHierarchyMark]
ELSE
FOR list: LIST OF SetHierarchyMarkProc ← regList, list.rest DO
IF list.rest=NIL THEN {list.rest ← LIST[setHierarchyMark]; EXIT}
ENDLOOP
};
};
--########################
RemDisplayHierachyMarkComm: PROC [comm: CDSequencer.Command] = {
viewer: ViewerClasses.Viewer ← CDViewer.GetViewer[comm];
IF viewer#NIL THEN CDViewHighlight.ShowInstance[v: viewer, key: myViewKey]
};
PutHierachyMarkComm: PROC [comm: CDSequencer.Command] = {
selected: CD.Instance ← CDCommandOps.TheInstance[comm, "place the hierarchy mark"];
IF selected#NIL THEN {
IF ~CDCells.IsPushedIn[comm.design] THEN SetHierarchyMark[comm.design, NIL, selected]
ELSE SetHierarchyMark[comm.design, comm.design.actual.first.dummyCell.ob, selected];
TDisplayHierarchyMarkComm[comm];
};
};
SelectHierachyMarkComm: PROC [comm: CDSequencer.Command] = {
Match: PROC [i1, i2: CD.Instance] RETURNS [BOOL] = INLINE {
RETURN [i1.ob=i2.ob AND i1.location=i2.location AND i1.orientation=i2.orientation]
};
inst: CD.Instance;
TerminalIO.WriteRope["Select hierarchy mark\n"];
IF CDCells.IsPushedIn[comm.design] THEN {
mr: CD.Instance ← comm.design.actual.first.mightReplace;
inst ← GetHierarchyMark[comm.design, mr.ob];
IF inst#NIL THEN
inst ← CDInstances.Composed[inst, mr.location, mr.ob.size, mr.orientation];
}
ELSE inst ← GetHierarchyMark[comm.design, NIL];
IF inst=NIL THEN TerminalIO.WriteRope["no hierarchy mark is set\n"]
ELSE {
CDSimpleOps.DeselectAll[comm.design];
FOR il: CD.InstanceList ← CDOps.InstList[comm.design], il.rest WHILE il#NIL DO
IF Match[il.first, inst] THEN {
il.first.selected ← TRUE;
CDOps.RedrawInstance[comm.design, il.first, FALSE];
};
ENDLOOP;
};
};
TDisplayHierarchyMarkComm: PROC [comm: CDSequencer.Command] = {
--T=>Top
startInst: CD.Instance ← comm.design.actual.first.mightReplace;
IF startInst=NIL THEN startInst ← comm.design.actual.first.dummyCell;
DisplayHierarchyMarks[comm.design, LIST[startInst], comm];
};
ADisplayHierarchyMarkComm: PROC [comm: CDSequencer.Command] = {
--A=>Selected from top level
DisplayHierarchyMarks[comm.design, CDOps.InstList[comm.design], comm];
};
SDisplayHierarchyMarkComm: PROC [comm: CDSequencer.Command] = {
--S=>All from top level
DisplayHierarchyMarks[comm.design, CDInstances.SplitSelected[CDOps.InstList[comm.design]].selected, comm];
};
myViewKey: ATOMNIL; --$CDHierarchyMark;
CreateEmptyCell: PROC [] RETURNS [cell: CD.Object] = {
cell ← CDCells.CreateEmptyCell[];
CDCells.SetSimplificationTreshhold[cell, 0];
};
MakeMarker: PROC [highlightInst: CD.Instance, mark: CD.Rect, lambda: CD.Number𡤂] = {
mOb: CD.Object ← CreateEmptyCell[];
d: CD.Number ← MAX[lambda, MIN[mark.x2-mark.x1, mark.y2-mark.y1]/20];
lineOb: CD.Object;
lineOb ← CDRects.CreateRect[size: [mark.x2-mark.x1+2*d, d], l: CD.shadeLayer];
[] ← CDCells.IncludeOb[cell: mOb, ob: lineOb, position: [-d, -d]];
[] ← CDCells.IncludeOb[cell: mOb, ob: lineOb, position: [-d, mark.y2-mark.y1]];
lineOb ← CDRects.CreateRect[size: [d, mark.y2-mark.y1], l: CD.shadeLayer];
[] ← CDCells.IncludeOb[cell: mOb, ob: lineOb, position: [-d, 0]];
[] ← CDCells.IncludeOb[cell: mOb, ob: lineOb, position: [mark.x2-mark.x1, 0]];
[] ← CDCells.RepositionCell[mOb, NIL];
[] ← CDCells.IncludeOb[cell: highlightInst.ob, ob: mOb, position: CDBasics.BaseOfRect[mark]];
};
foundAndStop: SIGNAL [ig: CD.Instance] = CODE;
--ig in global design coordinates
DontDrawRects: PROC [r: CD.Rect, l: CD.Layer, pr: CD.DrawRef] = {};
DrawChild: PROC [inst: CD.Instance, pos: CD.Position, orient: CD.Orientation, pr: REF CD.DrawInformation] = {
searchInst: CD.Instance ← NARROW[pr.devicePrivate];
IF searchInst.ob=inst.ob AND searchInst.location=pos AND searchInst.orientation=orient THEN {
ig: CD.Instance ← CDInstances.NewInst[inst.ob, pos, orient];
SIGNAL foundAndStop [ig]
};
};
DisplayHierarchyMarks: PROC [design: CD.Design, il: CD.InstanceList, viewerHint: REF] = {
highlightInst: CD.Instance ← NIL;
GoDown: PROC [fromInst: CD.Instance] = {
--fromInst in global world coordinate system
foundInst, markInst: CD.Instance ← NIL; multiple: BOOLFALSE;
IF CDProperties.GetProp[fromInst.ob, $IconFor]#NIL THEN RETURN;
markInst ← GetHierarchyMark[design, fromInst.ob];
IF markInst#NIL THEN {
pr.devicePrivate ← CDInstances.Composed[markInst, fromInst.location, fromInst.ob.size, fromInst.orientation];
fromInst.ob.class.drawMe[inst: fromInst, pos: fromInst.location, orient: fromInst.orientation, pr: pr !
foundAndStop => {
IF foundInst=NIL THEN {foundInst ← ig; RESUME}
ELSE {multiple ← TRUE; CONTINUE}
}
];
IF foundInst#NIL THEN {
IF multiple THEN TerminalIO.WriteRopes["****multiple hierarchymarks in ", CDCommandOps.InstRope[fromInst], "\n"]
ELSE {
IF highlightInst=NIL THEN highlightInst ← CDInstances.NewInst[CreateEmptyCell[]];
MakeMarker[highlightInst, CDInstances.InstRectI[foundInst], design.technology.lambda];
GoDown[foundInst];
};
};
}
};
pr: CD.DrawRef ← CD.CreateDrawRef[inf: [
design: design,
drawChild: DrawChild,
drawRect: DontDrawRects
]];
FOR list: CD.InstanceList ← il, list.rest WHILE list#NIL DO
GoDown[list.first];
IF CDSequencer.Aborted[design] THEN EXIT;
ENDLOOP;
IF highlightInst=NIL THEN TerminalIO.WriteRope["no hierarchy marks set\n"]
ELSE {
[] ← CDCells.RepositionCell[highlightInst.ob, NIL];
highlightInst.location ← CDBasics.NegOffset[CD.ClientOrigin[highlightInst.ob]];
};
FOR vL: CDViewer.ViewerList ← CDViewer.ViewersOf[viewerHint], vL.rest WHILE vL#NIL DO
CDViewHighlight.ShowInstance[v: vL.first, instOrList: highlightInst, key: myViewKey];
ENDLOOP
};
--########################
[] ← CDProperties.RegisterProperty[myKey, $CDHierarchyMarks];
RegisterHierarchyMarker[ReallySetHierarchyMark];
--########################
CDCommandOpsExtras2.RegisterWithMenu[menu: $ProgramMenu, entry: "Place hierarchy mark", proc: PutHierachyMarkComm, key: $CDHierarchyMarksPut];
CDCommandOpsExtras2.RegisterWithMenu[menu: $ProgramMenu, entry: "Display hierarchy marks top", proc: TDisplayHierarchyMarkComm, key: $CDHierarchyMarksTDisplay];
CDCommandOpsExtras2.RegisterWithMenu[menu: $ProgramMenu, entry: "Display hierarchy marks selected", proc: SDisplayHierarchyMarkComm, key: $CDHierarchyMarksSDisplay];
CDCommandOpsExtras2.RegisterWithMenu[menu: $ProgramMenu, entry: "Display hierarchy marks all", proc: ADisplayHierarchyMarkComm, key: $CDHierarchyMarksADisplay];
CDCommandOpsExtras2.RegisterWithMenu[menu: $ProgramMenu, entry: "Un-display hierarchy marks", proc: RemDisplayHierachyMarkComm, key: $CDHierarchyMarksUnDisplay];
CDCommandOpsExtras2.RegisterWithMenu[menu: $ProgramMenu, entry: "Select hierarchy mark", proc: SelectHierachyMarkComm, key: $CDHierarchyMarksSelect];
--########################
END.