CDBackgroundCheck.mesa
Copyright © 1986, 1987 by Xerox Corporation. All rights reserved.
Created by Christian Jacobi, February 19, 1986 10:12:40 am PST
Last Edited by: Christian Jacobi, April 14, 1987 5:18:05 pm PDT
DIRECTORY Atom, CD, CDBasics, CDCSUtil, CDErrors, CDInstances, CDProperties, CDSequencer, CDSimpleRules, CDValue, CDViewer, CedarProcess, IO, Process, Rope, TerminalIO, ViewerClasses, ViewerOps;
CDBackgroundCheck:
CEDAR
PROGRAM
IMPORTS Atom, CD, CDBasics, CDCSUtil, CDErrors, CDInstances, CDProperties, CDSequencer, CDSimpleRules, CDValue, CDViewer, CedarProcess, IO, Process, Rope, TerminalIO, ViewerOps =
BEGIN
Message:
PROC [comm: CDSequencer.Command] = {
h: CDCSUtil.CDWorld ~ NARROW[comm.data];
errors: CDCSUtil.Tesselation ~ NARROW[CDProperties.GetProp[h.propRef, $err]];
layerName: Rope.ROPE ~ NARROW[CDProperties.GetProp[h.propRef, $layer]];
key: ATOM ~ Atom.MakeAtom[Rope.Concat["||ck-", layerName]];
IF CDValue.Fetch[h.design, key]=h.design.actual.first.dummyCell.ob
THEN
CDErrors.RemoveMessages[h.design, NIL, key]
ELSE
CDErrors.RemoveAllMessages[h.design, key];
[] ← CDCSUtil.ExtractErrors[h, errors, Rope.Concat[layerName, " spacing"], key];
CDValue.Store[h.design, key, h.design.actual.first.dummyCell.ob];
};
CheckSpacing:
PROC [d:
CD.Design, r:
CD.Rect, layer:
CD.Layer, rules: CDSimpleRules.Rules←
NIL] = {
scaleNum: INT = 2;
h: CDCSUtil.CDWorld ← NEW[CDCSUtil.CDWorldRec ← [design: d, restrict: r, scale: [num: scaleNum], propRef: CD.InitPropRef[]]];
original: CDCSUtil.Tesselation ← CDCSUtil.Make[h, LIST[NEW[CDCSUtil.LayerDescRec←[layer]]]];
distRule: CD.Number ← CDSimpleRules.MinDist[layer, layer, rules];
amount: INT ← (scaleNum*distRule)/2-1;
grown: CDCSUtil.Tesselation ← CDCSUtil.Grow[original, amount];
again: CDCSUtil.Tesselation ← CDCSUtil.Grow[grown, -amount];
errors: CDCSUtil.Tesselation ← CDCSUtil.AndNot[again, original];
CDProperties.PutProp[h.propRef, $err, errors];
CDProperties.PutProp[h.propRef, $layer, Atom.GetPName[CD.LayerKey[layer]]];
CDSequencer.ExecuteProc[proc: Message, queue: doQueueAndMark,
comm: NEW[CDSequencer.CommandRec ← [data: h, design: d]]
];
};
CheckProcess:
PROC [] = {
d: CD.Design; md: CD.Number; key: ATOM;
CedarProcess.SetPriority[CedarProcess.Priority[background]];
DO
-- forever
v: ViewerClasses.Viewer ← CDViewer.LastViewer[];
IF v#
NIL
AND ViewerOps.FetchProp[v, $backCheck]=$y
AND (dViewer.DesignOf[v])#
NIL
THEN {
r: CD.Rect ← CDViewer.VisibleRect[v]; --handle view rect only for speed up
--restrict further to pushed in cell
IF d.actual.rest#
NIL
THEN
r ← CDBasics.Intersection[r, CDInstances.InstRectO[d.actual.first.mightReplace]];
--restrict further to handy scales
IF r.y2-r.y1<150*d.technology.lambda
THEN {
x: REF ← CDProperties.GetProp[d, $DesignRules];
IF x=NIL THEN x ← d.technology;
key ← CDSimpleRules.GetRulesKey[x !
CDSimpleRules.NotKnown => {key ← NIL; CONTINUE}
];
IF key#
NIL
THEN
FOR ll:
LIST
OF
CD.Layer ← d.technology.usedLayers, ll.rest
WHILE ll#
NIL
DO
IF (mdSimpleRules.MinDist[ll.first, ll.first, key])>0
THEN
CheckSpacing[d, CDBasics.Extend[r, md+d.technology.lambda], ll.first, key];
Process.Pause[Process.MsecToTicks[1]];
ENDLOOP;
}
};
d ← NIL; --gc
Process.Pause[Process.MsecToTicks[500]];
ENDLOOP;
};
CheckStartCommand:
PROC [comm: CDSequencer.Command] = {
key: ATOM ← NIL;
x: REF ← CDProperties.GetProp[comm.design, $DesignRules];
v: ViewerClasses.Viewer ← CDViewer.GetViewer[comm];
TerminalIO.PutRope[" start background checking for this viewer\n"];
IF x=NIL THEN x ← comm.design.technology;
key ← CDSimpleRules.GetRulesKey[x ! CDSimpleRules.NotKnown => CONTINUE];
IF key=
NIL
THEN TerminalIO.PutRope[" failed: no design rules\n"]
ELSE TerminalIO.PutF[" using design rules: %g\n", IO.atom[key]];
IF v#NIL AND key#NIL THEN ViewerOps.AddProp[v, $backCheck, $y];
};
CheckStopCommand:
PROC [comm: CDSequencer.Command] = {
v: ViewerClasses.Viewer ← CDViewer.GetViewer[comm];
TerminalIO.PutRope[" stop background checking in this viewer\n"];
IF v#NIL THEN ViewerOps.AddProp[v, $backCheck, NIL];
};
CDSequencer.ImplementCommand[$BackgroundCheckStart, CheckStartCommand,, dontQueue];
CDSequencer.ImplementCommand[$BackgroundCheckStop, CheckStopCommand,, dontQueue];
TRUSTED { Process.Detach[FORK CheckProcess[]] };
END.