<> <> <> <> DIRECTORY CD, CDApplications, CDBasics, CDLRUCache, CDImports, CDOps, CDOrient, CDPinObjects, CDPrivate, CDProperties, CDRects, Graphics, Rope, TokenIO; CDPinObjectsImpl: CEDAR PROGRAM IMPORTS CD, CDApplications, CDBasics, CDLRUCache, CDOps, CDOrient, CDPinObjects, CDPrivate, CDProperties, CDRects, Graphics, Rope, TokenIO EXPORTS CDPinObjects = BEGIN pinNameProp: ATOM = $SignalName; pinLevProp: ATOM = $layerOfPin; pinOwnerProp: ATOM = $ownerOfPin; PinSpecific: TYPE = REF PinRec; PinRec: TYPE = RECORD [dummy: INT _ 17]; dummyPinSpecific: PinSpecific = NEW[PinRec]; pForPin: REF CD.ObjectProcs = CD.RegisterObjectType[$PinOb0]; pinLayer: PUBLIC CD.Layer _ CD.NewLayer[NIL, $pinRepresentation]; pinCache: CDLRUCache.LRUCache = CDLRUCache.Create[size: 17, newProc: New]; New: PROC [] RETURNS [CD.ObPtr] = { ob: CD.ObPtr _ NEW[CD.ObjectDefinition]; ob.specificRef _ dummyPinSpecific; ob.layer _ pinLayer; ob.p _ pForPin; RETURN [ob] }; Init: PROC [] = BEGIN pForPin.drawMe _ pForPin.quickDrawMe _ DrawPin; pForPin.showMeSelected _ ShowSelectedPin; pForPin.internalRead _ ReadPin; pForPin.internalWrite _ WritePin; pForPin.wireTyped _ TRUE; pForPin.symbolic _ TRUE; pForPin.describe _ Describe; pForPin.describeApp _ DescribeApp; [] _ CDProperties.RegisterProperty[pinLevProp, $layer]; [] _ CDProperties.RegisterProperty[pinOwnerProp, $atom]; CDProperties.InstallProcs[prop: pinOwnerProp, new: [makeCopy: CDProperties.CopyVal]]; CDProperties.InstallProcs[prop: pinLevProp, new: [makeCopy: CDProperties.CopyVal]]; CDRects.UseAsCreateRect[pinLayer, RCreatePinOb, pForPin]; END; IsPinOb: PUBLIC PROC [ob: CD.ObPtr] RETURNS [BOOL] = BEGIN RETURN [ob.specificRef=dummyPinSpecific] END; WritePin: CD.InternalWriteProc -- PROC [me: ObPtr] -- = BEGIN TokenIO.WriteInt[me.size.x]; TokenIO.WriteInt[me.size.y]; END; ReadPin: CD.InternalReadProc --PROC [] RETURNS [ObPtr]-- = BEGIN x: INT = TokenIO.ReadInt[]; y: INT = TokenIO.ReadInt[]; RETURN [CreatePinOb[[x, y]]] END; ShowSelectedPin: PROC [aptr: CD.ApplicationPtr, pos: CD.DesignPosition, orient: CD.Orientation, pr: CD.DrawRef] = BEGIN pr.drawRect[CDOrient.RectAt[pos, aptr.ob.size, orient], CD.highLightShade, pr] END; CreatePinOb: PUBLIC PROC [size: CD.DesignPosition] RETURNS [CD.ObPtr] = BEGIN pOb: CD.ObPtr = pinCache.UnusedOrNew[]; pOb.size _ CDBasics.MaxPoint[size, [1, 1]]; RETURN [pinCache.ReplaceByAequivalent[pOb]] END; RCreatePinOb: PROC [size: CD.DesignPosition, l: CD.Layer] RETURNS [CD.ObPtr] = BEGIN RETURN [CreatePinOb[size]] END; CreatePinApp: PUBLIC PROC [name: Rope.ROPE, rect: CD.DesignRect, lev: CD.Layer_CD.combined, owner: ATOM_NIL] RETURNS [CD.ApplicationPtr] = BEGIN pinOb: CD.ObPtr = CreatePinOb[CDBasics.SizeOfRect[rect]]; pinApp: CD.ApplicationPtr = CDApplications.NewApplicationI[pinOb, CDBasics.BaseOfRect[rect]]; IF name#NIL THEN SetName[pinApp, name]; IF lev#CD.combined THEN SetLayer[pinApp, lev]; IF owner#NIL THEN SetOwner[pinApp, owner]; RETURN [pinApp] END; DrawPin: PROC [aptr: CD.ApplicationPtr, pos: CD.DesignPosition, orient: CD.Orientation, pr: CD.DrawRef] = BEGIN DrawPinInContext: PROC [context: Graphics.Context, ob: CD.ObPtr, layer: CD.Layer] = BEGIN Graphics.SetCP[self: context, x: 0, y: 0]; Graphics.DrawTo[self: context, x: ob.size.x, y: ob.size.y]; Graphics.SetCP[self: context, x: 0, y: ob.size.y]; Graphics.DrawTo[self: context, x: ob.size.x, y: 0]; END; IF pr.symbolics THEN { pr.drawContext[pr, DrawPinInContext, aptr.ob, pos, orient, pinLayer]; pr.drawComment[r: CDOrient.RectAt[pos, aptr.ob.size, orient], comment: GetName[aptr], pr: pr] } END; Describe: PROC[me: CD.ObPtr] RETURNS [Rope.ROPE] = BEGIN RETURN ["pin"] END; DescribeApp: PROC[ap: CD.ApplicationPtr] RETURNS [Rope.ROPE] = BEGIN RETURN [Rope.Concat[ CDOps.LayerName[CDPinObjects.GetLayer[ap]], " pin" ]]; END; SetName: PUBLIC PROC [pinApp: CD.ApplicationPtr, name: Rope.ROPE] = BEGIN IF CDPinObjects.IsPinApp[pinApp] THEN CDProperties.PutPropOnApplication[pinApp, pinNameProp, name] END; GetName: PUBLIC PROC [pinApp: CD.ApplicationPtr] RETURNS [r: Rope.ROPE _ NIL] = BEGIN IF CDPinObjects.IsPinApp[pinApp] THEN { WITH CDProperties.GetPropFromApplication[pinApp, pinNameProp] SELECT FROM n: Rope.ROPE => r _ n ENDCASE => NULL } END; SetOwner: PUBLIC PROC [pinApp: CD.ApplicationPtr, owner: ATOM] = BEGIN IF CDPinObjects.IsPinApp[pinApp] THEN CDProperties.PutPropOnApplication[pinApp, pinOwnerProp, owner] END; GetOwner: PUBLIC PROC [pinApp: CD.ApplicationPtr] RETURNS [at: ATOM_NIL] = BEGIN WITH CDProperties.GetPropFromApplication[pinApp, pinOwnerProp] SELECT FROM a: ATOM => at _ a ENDCASE => NULL END; SetLayer: PUBLIC PROC [pinApp: CD.ApplicationPtr, lev: CD.Layer] = BEGIN IF CDPinObjects.IsPinApp[pinApp] THEN CDProperties.PutPropOnApplication[pinApp, pinLevProp, CDPrivate.layers[lev]] END; GetLayer: PUBLIC PROC [pinApp: CD.ApplicationPtr] RETURNS [lev: CD.Layer_CD.combined] = BEGIN WITH CDProperties.GetPropFromApplication[pinApp, pinLevProp] SELECT FROM lp: CDPrivate.LayerRef => lev _ lp^.number ENDCASE => NULL END; EnumeratePins: PUBLIC PROC [ob: CD.ObPtr_NIL, eachPin: CDPinObjects.AppEnumerator] RETURNS [quit: BOOL_FALSE] = BEGIN cp: CD.CellPtr; WITH ob.specificRef SELECT FROM c: CD.CellPtr => cp _ c; ip: CDImports.ReferencePtr => { -- HACKK until imports handle pins reasonably IF ip.boundApp=NIL THEN RETURN [TRUE]; quit _ EnumeratePins[ip.boundApp.ob, eachPin]; }; ENDCASE => RETURN [TRUE]; FOR list: CD.ApplicationList _ cp.contents, list.rest WHILE (list#NIL AND ~quit) DO IF list.first.ob.specificRef=dummyPinSpecific THEN { quit _ eachPin[list.first]; -- do NOT catch errors }; ENDLOOP; END; FindPins: PUBLIC PROC [ob: CD.ObPtr_NIL, pinName: Rope.ROPE] RETURNS [apps: CD.ApplicationList] = BEGIN Enumerate: CDPinObjects.AppEnumerator = { IF Rope.Equal[GetName[app], pinName] THEN apps _ CONS[app, apps]; }; [] _ EnumeratePins[ob, Enumerate]; END; Init[]; END.