<> <> <> <> DIRECTORY CD, CDInstances, CDBasics, CDLRUCache, CDImports, CDOps, CDOrient, CDPinObjects, CDPrivate, CDProperties, CDRects, Imager, Rope, TokenIO; CDPinObjectsImpl: CEDAR PROGRAM IMPORTS CD, CDInstances, CDBasics, CDLRUCache, CDOps, CDOrient, CDPinObjects, CDPrivate, CDProperties, CDRects, Imager, 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.ObjectClass = CD.RegisterObjectClass[$PinOb0]; pinLayer: PUBLIC CD.Layer _ CD.NewLayer[NIL, $pinRepresentation]; pinCache: CDLRUCache.LRUCache = CDLRUCache.Create[size: 17, newProc: New]; New: PROC [] RETURNS [CD.Object] = { ob: CD.Object _ NEW[CD.ObjectRep]; ob.specificRef _ dummyPinSpecific; ob.layer _ pinLayer; ob.class _ 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.description _ "pin"; pForPin.describeInst _ DescribeInstance; [] _ 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.Object] RETURNS [BOOL] = BEGIN RETURN [ob.specificRef=dummyPinSpecific] END; WritePin: CD.InternalWriteProc -- PROC [me: Object] -- = BEGIN TokenIO.WriteInt[me.size.x]; TokenIO.WriteInt[me.size.y]; END; ReadPin: CD.InternalReadProc --PROC [] RETURNS [Object]-- = BEGIN x: INT = TokenIO.ReadInt[]; y: INT = TokenIO.ReadInt[]; RETURN [CreatePinOb[[x, y]]] END; ShowSelectedPin: PROC [inst: CD.Instance, pos: CD.Position, orient: CD.Orientation, pr: CD.DrawRef] = BEGIN pr.drawRect[CDOrient.RectAt[pos, inst.ob.size, orient], CD.highLightShade, pr] END; CreatePinOb: PUBLIC PROC [size: CD.Position] RETURNS [CD.Object] = BEGIN pOb: CD.Object = pinCache.UnusedOrNew[]; pOb.size _ CDBasics.MaxPoint[size, [1, 1]]; RETURN [pinCache.ReplaceByAequivalent[pOb]] END; RCreatePinOb: PROC [size: CD.Position, l: CD.Layer] RETURNS [CD.Object] = BEGIN RETURN [CreatePinOb[size]] END; CreatePinInstance: PUBLIC PROC [name: Rope.ROPE, rect: CD.Rect, lev: CD.Layer_CD.combined, owner: ATOM_NIL] RETURNS [CD.Instance] = BEGIN pinOb: CD.Object = CreatePinOb[CDBasics.SizeOfRect[rect]]; pinInstance: CD.Instance = CDInstances.NewInstance[pinOb, CDBasics.BaseOfRect[rect]]; IF name#NIL THEN SetName[pinInstance, name]; IF lev#CD.combined THEN SetLayer[pinInstance, lev]; IF owner#NIL THEN SetOwner[pinInstance, owner]; RETURN [pinInstance] END; DrawPin: PROC [inst: CD.Instance, pos: CD.Position, orient: CD.Orientation, pr: CD.DrawRef] = BEGIN DrawPinInContext: PROC [context: Imager.Context, ob: CD.Object, layer: CD.Layer] = BEGIN Imager.MaskVector[context, [0, 0], [ob.size.x, ob.size.y]]; Imager.MaskVector[context, [0, ob.size.y], [ob.size.x, 0]]; END; IF pr.symbolics THEN { pr.drawContext[pr, DrawPinInContext, inst.ob, pos, orient, pinLayer]; pr.drawComment[r: CDOrient.RectAt[pos, inst.ob.size, orient], comment: GetName[inst], pr: pr] } END; DescribeInstance: PROC[ap: CD.Instance] RETURNS [Rope.ROPE] = BEGIN RETURN [Rope.Concat[ CDOps.LayerName[CDPinObjects.GetLayer[ap]], " pin" ]]; END; SetName: PUBLIC PROC [pinInstance: CD.Instance, name: Rope.ROPE] = BEGIN IF CDPinObjects.IsPinApp[pinInstance] THEN CDProperties.PutPropOnInstance[pinInstance, pinNameProp, name] END; GetName: PUBLIC PROC [pinInstance: CD.Instance] RETURNS [r: Rope.ROPE _ NIL] = BEGIN IF CDPinObjects.IsPinApp[pinInstance] THEN { WITH CDProperties.GetPropFromInstance[pinInstance, pinNameProp] SELECT FROM n: Rope.ROPE => r _ n ENDCASE => NULL } END; SetOwner: PUBLIC PROC [pinInstance: CD.Instance, owner: ATOM] = BEGIN IF CDPinObjects.IsPinApp[pinInstance] THEN CDProperties.PutPropOnInstance[pinInstance, pinOwnerProp, owner] END; GetOwner: PUBLIC PROC [pinInstance: CD.Instance] RETURNS [at: ATOM_NIL] = BEGIN WITH CDProperties.GetPropFromInstance[pinInstance, pinOwnerProp] SELECT FROM a: ATOM => at _ a ENDCASE => NULL END; SetLayer: PUBLIC PROC [pinInstance: CD.Instance, lev: CD.Layer] = BEGIN IF CDPinObjects.IsPinApp[pinInstance] THEN CDProperties.PutPropOnInstance[pinInstance, pinLevProp, CDPrivate.layers[lev]] END; GetLayer: PUBLIC PROC [pinInstance: CD.Instance] RETURNS [lev: CD.Layer_CD.combined] = BEGIN WITH CDProperties.GetPropFromInstance[pinInstance, pinLevProp] SELECT FROM lp: CDPrivate.LayerRef => lev _ lp^.number ENDCASE => NULL END; EnumeratePins: PUBLIC PROC [ob: CD.Object_NIL, eachPin: CDPinObjects.InstanceEnumerator] 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.boundInstance=NIL THEN RETURN [TRUE]; quit _ EnumeratePins[ip.boundInstance.ob, eachPin]; RETURN }; ENDCASE => RETURN [TRUE]; FOR list: CD.InstanceList _ 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.Object_NIL, pinName: Rope.ROPE] RETURNS [apps: CD.InstanceList] = BEGIN Enumerate: CDPinObjects.InstanceEnumerator = { IF Rope.Equal[GetName[inst], pinName] THEN apps _ CONS[inst, apps]; }; [] _ EnumeratePins[ob, Enumerate]; END; Init[]; END.