-- File: IPCTG.mesa
-- Last Edited by: CSChow, February 2, 1985 2:53:20 am PST
Preas, August 1, 1986 4:33:38 pm PDT
--Note: IPCTG = ChannelTopologyGraph
--Intro: This is a collection of all the channels and information on their intersection topology.
-- At this point the only interesting top level thing this interface do are
DIRECTORY
Rope USING [ROPE],
RefTab USING [Ref],
IO USING[STREAM],
Imager USING [Context],
CCG USING[Ref],
IPCB,
IP USING [ChannelRep, IntersectionRep, IntersectionType, ComponentRep, ChType],
IPParams USING[ChDefaultWidth];
IPCTG: CEDAR DEFINITIONS
IMPORTS IPCB, IPParams
= BEGIN
Ref: TYPE = REF Rep;
Rep: TYPE = RECORD[horCCG, verCCG: CCG.Ref, extConstraintsTable: RefTab.Ref, horChNameCounter, verChNameCounter: NAT ← 0];
Channel: TYPE = REF ChannelRep;
ChannelRep: TYPE = IP.ChannelRep;
Component: TYPE = REF IP.ComponentRep;
ChType: TYPE = IP.ChType;
Intersection: TYPE = REF IntersectionRep;
IntersectionRep: TYPE = IP.IntersectionRep;
IntersectionType: TYPE = IP.IntersectionType;
Side: TYPE = IPCB.Side;
Cross, TEnd: IntersectionType = 0;
TNeg, LNeg: IntersectionType = -1;
TPos, LPos: IntersectionType = 1;
EachComponentAction: TYPE = IPCB.EachComponentAction;
EachChannelAction: TYPE = PROC[ch: Channel] RETURNS[quit: BOOLFALSE];
EachIntersectionAction: TYPE = IPCB.EachIntersectionAction;
ChannelTypeMismatch: ERROR;
CyclicConstraints: ERROR [negCh, posCh: Channel];
--These are the top level global operations on IPCTG--
Create: PROC[] RETURNS[Ref];
--Create an instance of Channel Topology Graph--
DescribeSelf: PROC[ctg: Ref, stream: IO.STREAM];
--Create a recoverable textual description of self. Used for creating checkpoint--
ReconstructSelf: PROC[stream: IO.STREAM] RETURNS [ctg: Ref];
-- Create the ctg based on the textual description in s. The reconstruction is perfect except the ref's are different.
CheckSelf: PROC[ctg: Ref];
-- Check to see if everything is all right. Useful for debugging--
DestroySelf: PROC[ctg: Ref];
-- Use to clean up cyclic garabage--
PaintSelf: PROC[ctg: Ref, context: Imager.Context, xOffset, yOffset: REAL ← 0.0, scaleFactor: REAL ← 1.0, showChName: BOOLTRUE];
CreateChannel: PROC[ctg: Ref, type: ChType, width: NAT ← IPParams.ChDefaultWidth, coord: INT ← 0, name: Rope.ROPENIL] RETURNS[ch: Channel];
--Create a channel in ctg--
DeActivateChannel: PROC[ctg: Ref, ch: Channel];
--remove the channel, inverse of ReActivateChannel--
ReActivateChannel: PROC[ctg: Ref, ch: Channel];
--put the channel back--
Size: PROC[ctg: Ref, type: ChType] RETURNS[NAT];
--Return the number of channels of the given type
GetChannel: PROC[ctg: Ref, name: Rope.ROPE, raiseError: BOOLTRUE] RETURNS[channel: Channel];
--Given the name get the channel. If no channel AND raiseError = TRUE then error UnknownName[name] else returns NIL
DirectedChannels: PROC[ctg: Ref, p: EachChannelAction, chType: ChType] RETURNS[BOOL];
-- Enumerate all channels of chType (hor or ver) or until p returns true. Returns TRUE <=> p returns FALSE ON ALL Channels.
Channels: PROC[ctg: Ref, p: EachChannelAction, horChsFirst: BOOLTRUE] RETURNS[BOOL];
-- Enumerate all channels or until p returns true. Returns TRUE <=> p returns FALSE ON ALL Channels. IF horChsFirst is true then all horizontal channels will be enumerated before the vertical channels else vice versa; this is an implementation dependent feature may disappear in future
--These are operations on individual channel --
GetType: PROC[ch: Channel] RETURNS[ChType] = INLINE{RETURN[ch.type]};
GetCoord: PROC[ch: Channel] RETURNS[INT] = INLINE {RETURN[ch.coord]};
GetSlack: PROC[ch: Channel] RETURNS[neg, pos: INT ] = INLINE {[neg, pos] ← ch.slack};
GetWidth: PROC[ch: Channel] RETURNS[NAT]= INLINE {RETURN[ch.width]};
GetName: PROC[ch: Channel] RETURNS[Rope.ROPE] = INLINE {RETURN[ch.name]};
SetWidth: PROC[ch: Channel, width: NAT] = INLINE {ch.width ← width};
SetCoord: PROC[ch: Channel, coord: INT] = INLINE {ch.coord ← coord};
PaintChannel: PROC[ch: Channel, context: Imager.Context, xOffset, yOffset: REAL ← 0.0, scaleFactor: REAL ← 1.0, showName: BOOLTRUE];
--Operations on intersection--
NewIn: PROC[ch: Channel, type:IntersectionType] RETURNS [Intersection] = INLINE {RETURN [NEW[IntersectionRep ←[ch: ch, type: type]]]};--NewIn--
ComputeGeometry: PROC[ctg: Ref, xPosition, yPosition: INT, horPosSense, verPosSense: BOOLTRUE]; -- This computes the positions and the slacks of all the channels --
GetBoundingChannels: PROC[ctg: Ref] RETURNS [southMost, eastMost, northMost, westMost: Channel]; --This find the bounding channels of the assembly--
RefreshAllConstraints: PROC [ctg: Ref];
AddExternalConstraints: PROC[ctg: Ref]; --This actually add the external constraints set to the channels. The lifetime of constraints is also until the next invocation of Compute Geometry--
SetExternalConstraint: PROC[ctg: Ref, negCh, posCh: Channel, wt: INT]; --This is the same as the above except that all external constraints will be remembered until explicitly cleared--
ClearExternalConstraints: PROC[ctg: Ref, negCh, posCh: Channel];
ClearAllExternalConstraints: PROC[ctg: Ref];
AddTopologicalConstraints: PROC[ctg: Ref]; --This add the topological constraints to the model. Topological constraints are like imposed to preserved the topology of the channel intersection. The lifetime of the constraints is until the next invocation of Compute Geometry--
ConstrainChannels0: PROC[ctg: Ref, negCh, posCh: Channel, wt: INT]; --This set a constraint between channels. It will be used in the next computation of geometrical information but will be forgotten afterwards. It is meant to be called by a program--
ConstrainChannels: PROC[ctg: Ref, negCh, posCh: Channel, wt: INT]; --This is the same as ConstrainChannels0[ctg, negCh, posCh, wt + negChWidth/2 + posChWidth/2]--
--##################--
InsertCoAt: PROC[ch: Channel, co: Component, whichSide, whichEnd: Side] = INLINE {IPCB.InsertCoAt[ch.boundary, co, whichSide, whichEnd]};
InsertCoBetween: PROC[ch: Channel, co: Component, negBnd, posBnd: Channel, which: Side]= INLINE{IPCB.InsertCoBetween[ch.boundary, co, negBnd, posBnd, which]};
SetBoundary: PROC[ch: Channel, negEnd, posEnd: Intersection, negSide, posSide: LIST OF Intersection ← NIL] = INLINE {IPCB.SetBoundary[ch.boundary, negEnd, posEnd, negSide, posSide]}; -- SetBoundary--
ComponentOn: PROC[ch: Channel, co: Component, which: Side] RETURNS[BOOL] = INLINE {RETURN[IPCB.ComponentOn[ch.boundary, co, which]]}; --ComponentOn--
EndCh: PROC[refCh, ch: Channel] RETURNS [BOOL] = INLINE {
RETURN [IPCB.EndCh[refCh.boundary, ch]]}; --EndCh--
GetChNbr: PROC[refCh, ch: Channel, whichNbr, hint: Side] RETURNS [Channel] = INLINE {
RETURN [IPCB.GetChNbr[refCh.boundary, ch, whichNbr, hint]]};
End: PROC[ch: Channel, which: Side] RETURNS[Intersection];
NthComponent: PROC [ch: Channel, which: Side, n: INT] RETURNS[Component];
NthIntersection: PROC[ch: Channel, which: Side, n: INT] RETURNS[Intersection];
IntersectsCh: PROC[refCh, ch: Channel] RETURNS [BOOL]= INLINE{RETURN [IPCB.IntersectsCh[refCh.boundary, ch]]};
Components: PROC[ch: Channel, which: Side, p: EachComponentAction] RETURNS[BOOL];
Intersections: PROC[ch: Channel, which: Side, p: EachIntersectionAction] RETURNS[BOOL];
NoIntersection: PROC[ch: Channel, which: Side] RETURNS[BOOL];
NoComponent: PROC[ch: Channel, which: Side] RETURNS[BOOL];
ArmOn: PROC[refCh: Channel, ch: Channel, which: Side] RETURNS [BOOL] = INLINE {
RETURN [IPCB.ArmOn[refCh.boundary, ch, which]]}; --ArmOn--
InCount: PROC[refCh, ch: IPCTG.Channel, which: IPCB.Side] RETURNS [INT] = INLINE{
RETURN [IPCB.InCount[refCh.boundary, ch, which]]}; --InCount--
Length: PROC[ch: Channel] RETURNS [INT] = INLINE{
RETURN [End[ch, pos].ch.coord - End[ch, neg].ch.coord]};--Length
Bounds: PROC[ch: Channel] RETURNS [neg, pos: INT] = INLINE {
RETURN [End[ch, neg].ch.coord, End[ch, pos].ch.coord]}; --Bounds
END.