<> <> <> <> DIRECTORY CD, Rope USING [ROPE]; CDSequencer: CEDAR DEFINITIONS = BEGIN <> <> <<>> <> <> Command: TYPE = REF CommandRec; CommandRec: TYPE = RECORD [ key: ATOM _ NIL, design: CD.Design _ NIL, l: CD.Layer _ CD.undefLayer, n: CD.Number _ 0, pos: CD.Position _ [0, 0], -- final position of command sPos: CD.Position _ [0, 0], -- special position, start position, (exceptional: size) orient: CD.Orientation _ CD.original, b: BOOL _ FALSE, ref: REF _ NIL, --typically describes issuer the command (if interactive: viewers data field) data: REF _ NIL --reserved for command implementor ]; CommandProc: TYPE = PROC[Command]; QueueMethod: TYPE = {doQueueAndMark, doQueue, dontQueue, useDefault}; <<--doQueueAndMark: fork and queue, mark the design as changed>> <<--doQueue: fork and queue, don't mark the design as changed>> <<--dontQueue: don't fork, don't queue, don't mark (procedure call)>> <<--useDefault: use the commands default QueueMethod >> ExecuteProc: PROC [proc: CommandProc, design: CD.Design _ NIL, queue: QueueMethod _ doQueue, comm: CDSequencer.Command _ NIL]; <<--Executes a command procedure proc.>> <<--design#NIL: design replaces comm.design>> <<--proc must be global >> <<--To transfer data to proc use: "comm: NEW[CommandRec _ [data: ..]]" >> ExecuteCommand: PROC [key: ATOM _ NIL, design: CD.Design _ NIL, queue: QueueMethod _ useDefault, comm: CDSequencer.Command _ NIL]; <<--Fetches and executes a command.>> <<--key#NIL: key replaces comm.a>> <<--design#NIL: design replaces comm.design>> ImplementCommand: PROC [key: ATOM, proc: CommandProc, technology: CD.Technology_NIL, queue: QueueMethod _ doQueueAndMark]; <<--Registeres a command>> <<--technology=NIL: implement command for all technologies.>> <<--Re-using the same atom (in same technology) overwrites the command >> FetchCommand: PROC [key: ATOM, technology: CD.Technology_NIL] RETURNS [proc: CommandProc, qm: QueueMethod]; <<--Fetches a commands registration>> <<--NIL proc if not defined>> MarkChanged: PROC [design: CD.Design]; <<--Mark the design as changed; it will be saved some time later again...>> OpenDialogue: PROC [design: CD.Design]; <<--Initializes the command queue>> <<>> Quit: PROC [message: Rope.ROPE_NIL]; <<--Write message and terminates execution of the command of this process>> <<--Never returns>> <<--(use only from ChipNDale processes which have the CDSequencer lock of the design)>> <<>> <<--aborts>> <<-- Abortion does not guarantee the aborted process to stop, but most long >> <<-- commands are benevolent.>> <<-- Abortion of a command is also propagated using an event $Aborted.>> AbortDesignsCommand: PROC [design: CD.Design]; <<--Called from any process; tries to abort the designs current command >> <<--May flush commands not yet started >> <<--(On return success is not yet known) >> Aborted: PROC [design: CD.Design] RETURNS [BOOL]; <<--Checks whether the current command on design has been aborted>> <<--(Accurate only inside CDSequencer's lock of design)>> CheckAborted: PROC [design: CD.Design]; <<--IF Aborted[design] THEN Quit[]>> END.