CDCommandOpsImpl.mesa
Copyright © 1984, 1986 by Xerox Corporation. All rights reserved.
Created by Christian Jacobi, July 12, 1984 3:49:16 pm PDT
Last Edited by: Christian Jacobi, December 12, 1986 10:04:23 am PST
DIRECTORY
Atom,
CD,
CDCommandOps,
CDLayers,
CDOps,
CDPopUpMenus,
CDPrivate,
CDProperties,
CDSequencer,
IO,
PopUpMenus,
Process,
RefTab,
Rope,
TerminalIO;
CDCommandOpsImpl:
CEDAR
MONITOR
IMPORTS Atom, CD, CDLayers, CDOps, CDPopUpMenus, CDProperties, CDSequencer, IO, PopUpMenus, Process, RefTab, TerminalIO
EXPORTS CDCommandOps =
BEGIN
reCheck: CONDITION ← [timeout: Process.MsecToTicks[1000]];
EnterResource:
ENTRY
PROC [resource:
REF, wait:
BOOL, design:
REF]
RETURNS [ok:
BOOL] = {
IF design=NIL THEN design ← $NIL;
DO
ok ← RefTab.Insert[resourceTab, resource, design];
IF ok OR ~wait THEN EXIT;
WAIT reCheck;
ENDLOOP
};
LeaveResource:
ENTRY
PROC [resource:
REF] = {
[] ← RefTab.Delete[resourceTab, resource];
BROADCAST reCheck
};
DoWithResource:
PUBLIC
PROC [proc: CDSequencer.CommandProc, comm: CDSequencer.Command, resource:
REF ←
NIL, waitIfBusy:
BOOL ←
FALSE, messageIfSkipped:
BOOL ←
TRUE]
RETURNS [skipped:
BOOL←TRUE] = {
design: CD.Design = IF comm#NIL THEN comm.design ELSE NIL;
IF skipped ← ~EnterResource[resource, waitIfBusy, design]
THEN {
IF messageIfSkipped THEN TerminalIO.PutRope[" not reentrant; skipped\n"]
}
ELSE {
proc[comm ! UNWIND => LeaveResource[resource]];
LeaveResource[resource];
}
};
unique: INT ← 0;
RegisterWithMenu:
PUBLIC PROC [menu:
REF←
NIL, entry: Rope.
ROPE←
NIL, doc: Rope.
ROPE←
NIL, key:
ATOM←
NIL, proc: CDSequencer.CommandProc←
NIL, queue: CDSequencer.QueueMethod𡤍oQueue, tech:
CD.Technology←
NIL] = {
IF key=NIL THEN key ← Atom.MakeAtom[IO.PutFR1["a%g", IO.int[unique ← unique+1]]];
IF proc#
NIL
THEN
CDSequencer.ImplementCommand[key: key, proc: proc, queue: queue, technology: tech];
IF menu#
NIL
THEN
[] ← PopUpMenus.Entry[CDPopUpMenus.GetMenu[menu], entry, NIL, key, doc];
};
currentLayerReg: CD.PropRef ← CD.InitPropRef[];
SetCurrentLayer:
PROC [comm: CDSequencer.Command] = {
x: REF ← CDProperties.GetPropProp[currentLayerReg, comm.design.technology.key, comm.key];
IF x=NIL THEN x ← CDProperties.GetPropProp[currentLayerReg, $all, comm.key];
WITH x
SELECT
FROM
lora:
LIST
OF
REF
ANY => {
lay: CD.Layer ← CD.errorLayer;
w: INT ← -1;
WITH lora.first
SELECT
FROM
l: REF CD.Layer => lay ← l^;
ENDCASE => NULL;
IF lora.rest#
NIL
THEN
WITH lora.rest.first
SELECT
FROM
i: REF INT => w ← i^
ENDCASE => NULL;
SELECT
TRUE
FROM
w>=0 => CDLayers.SetLayerWidth[comm.design, lay, w];
w=-2 => CDLayers.SetLayerWidth[comm.design, lay, CDLayers.LayerWidth[comm.design, CD.commentLayer]];
ENDCASE => NULL; --don't change current width of layer
CDLayers.SetCurrentLayer[comm.design, lay];
TerminalIO.PutRopes["set default layer: ", CDOps.LayerRope[lay], "\n"];
};
ENDCASE => TerminalIO.PutF["command %g failed\n", [atom[comm.key]]];
};
RegisterCurrentLayerCommand:
PUBLIC PROC [key:
ATOM, layer:
CD.Layer, tech:
CD.Technology, w:
CD.Number←-1] = {
tKey: ATOM ← IF tech#NIL THEN tech.key ELSE $all;
CDProperties.PutPropProp[currentLayerReg, tKey, key, LIST[NEW[CD.Layer←layer], NEW[INT←w]]];
CDSequencer.ImplementCommand[key: key, proc: SetCurrentLayer, queue: doQueue, technology: tech];
};
resourceTab: RefTab.Ref ~ RefTab.Create[7];
END.