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: REFNIL, waitIfBusy: BOOLFALSE, messageIfSkipped: BOOLTRUE] 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: REFNIL, entry: Rope.ROPENIL, doc: Rope.ROPENIL, key: ATOMNIL, 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: ATOMIF 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.