CDSequencerImpl.mesa (part of Chipndale)
by Christian Jacobi June 22, 1983 6:02 pm
last edited by Christian Jacobi February 16, 1984 5:05 pm
DIRECTORY
Atom,
CDSequencer,
CD USING [Technology, Number, DesignPosition, Level, Design,
TechnologyCommandsRep, Error],
CDEvents USING [EventProc, RegisterEventProc],
CDOps USING [DoTheDelayedRedraws],
RefTab USING [Val, Ref, Fetch, Create, Insert, Store],
TerminalIO USING [WriteRope, UserAbort],
MBQueue USING [Queue, Create, QueueClientAction];
CDSequencerImpl: CEDAR MONITOR
IMPORTS Atom, CD, CDOps, RefTab, MBQueue, TerminalIO, CDEvents
EXPORTS CDSequencer, CD =
BEGIN
Command: TYPE = CDSequencer.Command;
CommandProc: TYPE = CDSequencer.CommandProc;
priviledgedRefTab: RefTab.Ref = RefTab.Create[mod: 17]; -- holds commands not to be used
globalRefTab: RefTab.Ref = RefTab.Create[mod: 53]; -- holds commands used in all technologies
TechnologyCommandsRep: PUBLIC TYPE = RECORD [
commandTab: RefTab.Ref
];
DesignHasBeenCreated: CDEvents.EventProc ={
design.queue ← MBQueue.Create[];
};
TechnologyHasBeenRegistered: CDEvents.EventProc =
BEGIN
tech: CD.Technology ~ NARROW[x];
tech.technologyCommands ← NEW[TechnologyCommandsRep
← [commandTab: RefTab.Create[mod: 31]]]
END;
InternalExecuteCommand: PROC [ref: REF ANY] =
BEGIN
ENABLE {
ABORTED => GOTO Aborted;
TerminalIO.UserAbort => GOTO TerminalAborted;
};
found: BOOLEANFALSE;
val: RefTab.Val;
comm: Command ← NARROW[ref];
IF comm.design.technology#NIL THEN { -- search first for particular technology
techCommands: REF TechnologyCommandsRep ~
comm.design.technology.technologyCommands;
[found, val] ← RefTab.Fetch[techCommands.commandTab, comm.a];
};
IF NOT found THEN [found, val] ← RefTab.Fetch[globalRefTab, comm.a]; -- search global
IF found AND val#NIL THEN NARROW[val, REF CommandProc]^[comm]
ELSE {
TerminalIO.WriteRope["command "];
TerminalIO.WriteRope[Atom.GetPName[comm.a]];
TerminalIO.WriteRope[" not loaded\n"];
};
CDOps.DoTheDelayedRedraws[comm.design];
EXITS
Aborted => {TerminalIO.WriteRope["** ABORTED\n"]};
TerminalAborted => {TerminalIO.WriteRope["** user aborted\n"]};
END;
ImplementCommand: PUBLIC ENTRY PROC [a: ATOM, p: CommandProc, technology: CD.Technology←NIL] =
-- If technology is NIL implement for all technologies.
-- There is a (finite, short) list of atoms you MUST NOT use.
-- Reimplementing the same atom in a technology it already exists overwrites the command;
-- If the same atom is specified for a particular technology and all technologies,
-- the more specific implementation wins independent of order.
-- Don't fool with NIL CommandProc's if you don't know EXACTLY what it does.
-- (NIL CommandProc's serves too install the list of commands you MUST NOT use.)
BEGIN
ptr: REF CommandProc ~ NEW[CommandProc←p];
myRefTab: RefTab.Ref ← globalRefTab;
-- check if is reserved atom not to be used
IF p=NIL THEN {[] ← RefTab.Insert[priviledgedRefTab, a, technology]; RETURN}
ELSE IF RefTab.Fetch[priviledgedRefTab, a].found THEN
RETURN WITH ERROR CD.Error[doubleRegistration, "This atom is reserved"];
-- do implementation
IF technology#NIL THEN {
techCommands: REF TechnologyCommandsRep ~ technology.technologyCommands;
myRefTab ← techCommands.commandTab;
};
[] ← RefTab.Store[myRefTab, a, ptr]
END;
QueueCommand: PUBLIC PROC[design: CD.Design←NIL, comm: Command] =
-- oldy, for speed reason don't call ExecuteCommand
BEGIN
IF design=NIL THEN design ← comm.design;
comm.design ← design;
IF design=NIL THEN ERROR;
MBQueue.QueueClientAction[design.queue, InternalExecuteCommand, comm];
END;
ExecuteCommand: PUBLIC PROC [comm: Command, design: CD.Design, as: ATOM, queue: CDSequencer.Queueing] =
-- if as#NIL replaces comm.a
-- if design#NIL replaces comm.design
BEGIN
newComm: CDSequencer.Command ~ NEW[CDSequencer.CommandRec𡤌omm^];
IF as#NIL THEN newComm.a ← as;
IF design#design THEN newComm.design ← design;
IF comm.design=NIL THEN ERROR;
IF queue=doQueue THEN
MBQueue.QueueClientAction[design.queue, InternalExecuteCommand, newComm]
ELSE InternalExecuteCommand[newComm]
END;
CDEvents.RegisterEventProc[$RegisterTechnology, TechnologyHasBeenRegistered];
CDEvents.RegisterEventProc[$CreateNewDesign, DesignHasBeenCreated];
END.