CDCommandOpsImpl.mesa
Copyright © 1984, 1986, 1987 by Xerox Corporation. All rights reserved.
Created by Christian Jacobi, July 12, 1984 3:49:16 pm PDT
Last Edited by: Christian Jacobi, September 3, 1987 12:00:29 pm PDT
DIRECTORY
Atom,
CD,
CDCommandOps,
CDEnvironment,
CDLayers,
CDOps,
CDPopUpMenus,
CDPrivate,
CDProperties,
CDSequencer,
CDSequencerExtras,
CDViewer,
Commander,
IO,
PopUpMenus,
Process,
RefTab,
Rope,
TerminalIO;
CDCommandOpsImpl: CEDAR MONITOR
IMPORTS Atom, CD, CDEnvironment, CDLayers, CDOps, CDPopUpMenus, CDProperties, CDSequencer, CDSequencerExtras, CDViewer, IO, PopUpMenus, Process, RefTab, Rope, 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: BOOLTRUE] = {
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 {
Protected: PROC [] = {
ENABLE UNWIND => LeaveResource[resource];
proc[comm];
LeaveResource[resource];
};
Protected[]
}
};
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
CDSequencerExtras.RegisterCommand[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];
};
IncludeOb: PUBLIC PROC [comm: CDSequencer.Command, ob: CD.Object, failMessage: Rope.ROPE] = {
msg: Rope.ROPE ← failMessage;
IF ob=NIL THEN {
IF msg=NIL THEN failMessage ← "failed";
}
ELSE {
i: CD.Instance ← CDOps.IncludeObjectI[design: comm.design, ob: ob, location: comm.pos];
msg ← Rope.Cat["include: ", CDOps.InstRope[i]];
};
TerminalIO.PutRopes[msg, "\n"]
};
NewDesign: Commander.CommandProc = {
IF cmd#NIL AND cmd.procData#NIL THEN
WITH cmd.procData.clientData SELECT FROM
t: CD.Technology => {
design: CD.Design ← CDOps.CreateDesign[t];
CDOps.SetMutability[design, editable];
[] ← CDViewer.CreateViewer[design];
cmd.out.PutRope[Rope.Cat[t.name, " design created\n"]];
RETURN
};
ENDCASE => NULL;
cmd.out.PutRope[" bad command data\n"];
};
PseudoLoadTechnology: Commander.CommandProc = {
The purpose of this procedure is to make load files look as if they did succeed;
When this procedure is registered [or called] the technology is already loaded
cmd.out.PutRope[" technology is loaded\n"];
};
RegisterCommanderNewDesign: PUBLIC PROC [technology: CD.Technology] = {
CDEnvironment.RegisterCommander[
key: Rope.Cat["CDNew", technology.name],
proc: NewDesign,
doc: Rope.Cat["Creates new ", technology.name, " ChipNDale design"],
clientData: technology,
technology: technology
];
CDEnvironment.RegisterCommander[
key: Rope.Cat["CD", technology.name],
proc: PseudoLoadTechnology,
doc: Rope.Cat["Loads ", technology.name, " ChipNDale technology [but is already loaded]"],
technology: technology
];
};
resourceTab: RefTab.Ref ~ RefTab.Create[7];
END.