CDRepetitionCommands.mesa (part of ChipNDale)
Copyright © 1983, 1984 by Xerox Corporation. All rights reserved.
by Christian Jacobi, July 11, 1983 3:42 pm
last edited Christian Jacobi, March 17, 1986 5:20:43 pm PST
DIRECTORY
CD,
CDInstances,
CDCallSpecific,
CDCells,
CDCommandOps,
CDDirectory,
CDOps,
CDOrient,
CDRepetitions,
CDSequencer,
Rope,
TerminalIO;
CDRepetitionCommands:
CEDAR
PROGRAM
IMPORTS CDInstances, CDCallSpecific, CDCells, CDCommandOps, CDDirectory, CDOps, CDOrient, CDRepetitions, CDSequencer, TerminalIO =
BEGIN
MakeRepetition:
PROC [comm: CDSequencer.Command] =
BEGIN
sel: CD.InstanceList;
ob: CD.Object;
offset, location: CD.Position;
count: INT;
first: CD.Instance;
multiple: BOOL;
TerminalIO.WriteRope["make a repetition "];
[first, multiple] ← CDOps.SelectedInstance[comm.design];
IF first=NIL THEN {TerminalIO.WriteRope["no selected object\n"]; RETURN};
count ← TerminalIO.RequestInt["number: "];
IF count<1
OR count>=
LAST[
NAT]
THEN {
TerminalIO.WriteRope["bad number\n"]; RETURN
};
IF count>=257
THEN {
TerminalIO.WriteRope["don't exagerate\n"]; RETURN
};
IF multiple
THEN {
[done: multiple, cellOb: ob] ← CDCells.CreateCellSelected[comm.design, "-dummy"];
IF NOT multiple THEN {TerminalIO.WriteRope["not done\n"]; RETURN};
};
[selected: sel, others: comm.design.actual.first.specific.contents] ←
CDInstances.SplitSelected[comm.design.actual.first.specific.contents];
IF sel.first=NIL OR sel.rest#NIL THEN ERROR; -- therefore sel#NIL !
offset ← [comm.pos.x-comm.sPos.x, comm.pos.y-comm.sPos.y];
ob ← CDRepetitions.CreateRepetition[comm.design, sel.first.ob, count, offset, sel.first.orientation];
location ← sel.first.location;
IF offset.x<0 THEN location.x ← location.x+(count-1)*offset.x;
IF offset.y<0 THEN location.y ← location.y+(count-1)*offset.y;
CDOps.IncludeObjectI[comm.design, ob, location, CDOrient.original];
END;
ChangeRepetition:
PROC [comm: CDSequencer.Command] =
BEGIN
inst: CD.Instance = CDCommandOps.TheInstance[comm, "change a repetition "];
IF inst#
NIL
THEN
IF ~
ISTYPE[inst.ob.specificRef, CDRepetitions.RepPtr]
THEN
TerminalIO.WriteRope["selected ob not a repetition"]
ELSE {
offset: CD.Position = [comm.pos.x-comm.sPos.x, comm.pos.y-comm.sPos.y];
rp: CDRepetitions.RepPtr = NARROW[inst.ob.specificRef];
CDOps.RedrawInstance[comm.design, inst];
inst.ob ← CDRepetitions.CreateRepetition[comm.design, rp.ob, rp.count, offset, CDOrient.ComposeOrient[rp.orientation, inst.orientation]];
inst.orientation ← CDOrient.original;
CDOps.RedrawInstance[comm.design, inst, FALSE];
TerminalIO.WriteRope[" done\n"]
};
END;
TransformToCellS:
PROC [comm: CDSequencer.Command] =
BEGIN
n: NAT;
TerminalIO.WriteRope["transform to cell\n"];
n ← CDCallSpecific.CallForSelected[design: comm.design, objectSpecific: $TransformToCell, whatElse: TransformOthers];
TerminalIO.WriteInt[n]; TerminalIO.WriteRope[" objects transformed\n"];
END;
TransformOthers:
PROC [design:
CD.Design, inst:
CD.Instance, x:
REF]
RETURNS [done: BOOL←TRUE, removeMe: BOOL←FALSE, include: CD.InstanceList←NIL,
repaintMe: BOOL←FALSE, repaintInclude: BOOL←FALSE] =
BEGIN
IF inst.ob.class.inDirectory
AND ~CDCells.IsCell[inst.ob]
THEN {
cob: CD.Object ← CDDirectory.ExpandComplete[inst.ob, design, design];
IF done ← cob#
NIL
THEN {
ci: CD.Instance ← CDInstances.Copy[inst];
repaintInclude ← removeMe ← repaintMe ← TRUE;
include ← LIST[ci];
ci.ob ← cob;
}
};
END;
AllRepetitionsToCells: PROC [comm: CDSequencer.Command] =
BEGIN
n: NAT ← 0;
repList: LIST OF CD.Object ← NIL;
--we make a list first, otherwise: directory changes while the enumeration
FindRepetitions: CDDirectory.EachEntryAction =
-- PROC [name: Rope.ROPE, ob: CD.Object] RETURNS [quit: BOOLLSE]
BEGIN
WITH ob.specificRef SELECT FROM
rp: CDRepetitions.RepPtr => repList ← CONS[ob, repList];
ENDCASE => NULL
END;
TerminalIO.WriteRope["transform all repetitions to cells\n"];
[] ← CDDirectory.Enumerate[design: comm.design, action: FindRepetitions];
FOR list: LIST OF CD.Object ← repList, list.rest WHILE list#NIL DO
name: Rope.ROPE ← CDDirectory.Name[list.first];
rCell: CD.Object ← CDDirectory.Expand[list.first, comm.design, comm.design];
IF rCell=NIL THEN
TerminalIO.WriteRope[Rope.Cat["** ", name, " not transformed\n"]]
ELSE {
[] ← CDDirectory.Remove[design: comm.design, name: name, expectObject: list.first];
[] ← CDDirectory.Rename[design: comm.design, object: rCell, newName: name];
n ← n+1;
CDDirectory.ReplaceObject[design: comm.design, old: list.first, new: rCell];
TerminalIO.WriteRope[Rope.Cat[" cell ", CDDirectory.Name[rCell], " generated\n"]]
};
ENDLOOP;
TerminalIO.WriteInt[n]; TerminalIO.WriteRope[" repetitions transformed\n"];
END;
CDSequencer.ImplementCommand[$DrawRepetition, MakeRepetition];
CDSequencer.ImplementCommand[$ChangeRepetition, ChangeRepetition];
CDSequencer.ImplementCommand[$TransformToCellS, TransformToCellS];
END.