<> <> <> DIRECTORY Atom, CDBusses, CD, CDIO, CDOrient, CDInline, CDCallSpecific, CDCells, CDDirectory, CDProperties, CDRects, CDApplications, TerminalIO, TokenIO; CDBussesImpl: CEDAR PROGRAM IMPORTS Atom, CD, CDApplications, CDCallSpecific, CDCells, CDDirectory, CDInline, CDIO, CDOrient, CDProperties, CDRects, TerminalIO, TokenIO EXPORTS CDBusses = BEGIN BusPtr: TYPE = CDBusses.BusPtr; BusRec: TYPE = CDBusses.BusRec; CreateBus: PUBLIC PROC [sizeOfFirst: CD.DesignPosition, lev: CD.Level, count: NAT, offset: CD.DesignPosition, lengIncrement: CD.DesignNumber_0] RETURNS [CD.ObPtr] = BEGIN ob: CD.ObPtr; bp: BusPtr ~ NEW[BusRec]; lowY, highY, left, right: CD.DesignNumber; IF CDProperties.GetPropFromLevel[from: lev, prop: $CDxRectCreation]#NIL THEN { TerminalIO.WriteRope["busses on level "]; TerminalIO.WriteRope[Atom.GetPName[CD.LevelKey[lev]]]; TerminalIO.WriteRope[" not implemented\n"]; RETURN [CDRects.CreateRect[size: sizeOfFirst, l: lev]] }; count _ MAX[1, MIN[count, 512]]; IF sizeOfFirst.y<=0 THEN sizeOfFirst.y_CD.lambda; IF sizeOfFirst.x<=0 THEN sizeOfFirst.x_CD.lambda; IF sizeOfFirst.y+(count-1)*lengIncrement<=0 THEN lengIncrement_0; lowY _ MIN[0, (count-1)*offset.y]; highY _ MAX[sizeOfFirst.y, (count-1)*(offset.y+lengIncrement)+sizeOfFirst.y]; left _ MIN[0, (count-1)*offset.x]; right _ MAX[sizeOfFirst.x, (count-1)*(offset.x)+sizeOfFirst.x]; ob _ NEW[CD.ObjectDefinition _ [ p: pForBusses, size: [x: right-left, y: highY-lowY], level: lev, specificRef: bp ]]; bp.sizeOfFirst _ sizeOfFirst; bp.offsetOfFirst _ [-left, -lowY]; bp.offset _ offset; bp.count _ count; bp.lengIncrement _ lengIncrement; RETURN [ob] END; ReadBus: CD.InternalReadProc --PROC [] RETURNS [ObPtr]-- = BEGIN sizeOfFirstX: INT = TokenIO.ReadInt[]; sizeOfFirstY: INT = TokenIO.ReadInt[]; lev: CD.Level = CDIO.ReadLevel[]; count: INT = TokenIO.ReadInt[]; offsetX: INT = TokenIO.ReadInt[]; offsetY: INT = TokenIO.ReadInt[]; lengIncrement: INT = TokenIO.ReadInt[]; RETURN [ CreateBus[ sizeOfFirst: [sizeOfFirstX, sizeOfFirstY], lev: lev, count: count, offset: [offsetX, offsetY], lengIncrement: lengIncrement ]]; END; WriteBus: CD.InternalWriteProc -- PROC [me: ObPtr] -- = BEGIN bp: BusPtr = NARROW[me.specificRef]; TokenIO.WriteInt[bp.sizeOfFirst.x]; TokenIO.WriteInt[bp.sizeOfFirst.y]; CDIO.WriteLevel[me.level]; TokenIO.WriteInt[bp.count]; TokenIO.WriteInt[bp.offset.x]; TokenIO.WriteInt[bp.offset.y]; TokenIO.WriteInt[bp.lengIncrement]; END; pForBusses: REF CD.ObjectProcs; TransformToCell: CDCallSpecific.CallProc = BEGIN bptr: BusPtr_NARROW[aptr.ob.specificRef]; cob: CD.ObPtr _ CreateBusCell[design: design, sizeOfFirst: bptr.sizeOfFirst, lev: aptr.ob.level, count: bptr.count, offset: bptr.offset, lengIncrement: bptr.lengIncrement ]; removeMe_TRUE; repaintMe_TRUE; include_LIST[CDApplications.NewApplicationI[ cob, aptr.location, aptr.orientation, aptr.selected, aptr.properties]]; repaintInclude_TRUE; END; Init: PROC [] = BEGIN pForBusses _ CD.RegisterObjectType[$Bus]; pForBusses.objectType _ $Bus; pForBusses.drawMe _ DrawMeForBus; pForBusses.internalRead _ ReadBus; pForBusses.internalWrite _ WriteBus; CDCallSpecific.Register[$TransformToCell, pForBusses, TransformToCell]; END; DrawMeForBus: PROC [aptr: CD.ApplicationPtr, pos: CD.DesignPosition, orient: CD.Orientation, pr: CD.DrawRef] = BEGIN bp: BusPtr _ NARROW[aptr.ob.specificRef]; rel, sz: CD.DesignPosition; rel _ bp.offsetOfFirst; sz _ bp.sizeOfFirst; THROUGH [0..bp.count) DO IF pr.stopFlag^ THEN EXIT; pr.drawRect[ CDOrient.MapRect[ itemInCell: CDInline.RectAt[rel, sz], cellSize: aptr.ob.size, cellInstOrient: orient, cellInstPos: pos], aptr.ob.level, pr]; rel _ CDInline.AddPoints[rel, bp.offset]; sz.y _ sz.y+bp.lengIncrement; ENDLOOP END; CreateBusCell: PUBLIC PROC [design: CD.Design, sizeOfFirst: CD.DesignPosition, lev: CD.Level, count: NAT, offset: CD.DesignPosition, lengIncrement: CD.DesignNumber_0] RETURNS [CD.ObPtr] = BEGIN sz: CD.DesignPosition_sizeOfFirst; ap: CD.ApplicationPtr; pos: CD.DesignPosition _ [0, 0]; co: CD.ObPtr _ CDCells.CreateEmptyCell[]; cp: CD.CellPtr _ NARROW[co.specificRef]; IF CDProperties.GetPropFromLevel[from: lev, prop: $CDxRectCreation]#NIL THEN { TerminalIO.WriteRope["busses on level "]; TerminalIO.WriteRope[Atom.GetPName[CD.LevelKey[lev]]]; TerminalIO.WriteRope[" not implemented\n"]; RETURN [CDRects.CreateRect[size: sizeOfFirst, l: lev]] }; count _ MAX[count, 1]; IF sz.x<=0 THEN sz.x_CD.lambda; IF sz.y<=0 THEN sz.y_CD.lambda; IF sz.y+(count-1)*lengIncrement<0 THEN lengIncrement_0; IF offset.x<0 THEN {pos.x _ -offset.x*(count-1)}; IF offset.y<0 THEN {pos.y _ -offset.y*(count-1)}; FOR i: NAT IN [1..count] DO rec: CD.ObPtr _ CDRects.CreateRect[sz, lev]; ap _ CDApplications.NewApplicationI[ob: rec, location: pos]; pos _ CDInline.AddPoints[pos, offset]; sz.y _ sz.y+lengIncrement; cp.contents _ CONS[ap, cp.contents] ENDLOOP; co.size _ CDInline.SizeOfRect[CDApplications.BoundingRect[cp.contents]]; [] _ CDDirectory.Include[design, co, "-bus-"]; RETURN [co]; END; Init[]; END.