DIRECTORY Atom, CD, CDPrivate, CDDefaultProcs, CDEvents, CDBasics, Imager, RefTab, Rope, SafeStorage; CDImpl: CEDAR MONITOR IMPORTS Atom, CD, CDDefaultProcs, CDEvents, RefTab, SafeStorage EXPORTS CD, CDPrivate SHARES CDPrivate = BEGIN Error: PUBLIC ERROR[ec: CD.ErrorCode _ programmingError, explanation: Rope.ROPE _ NIL] = CODE; permanent: ZONE = SafeStorage.GetPermanentZone[]; layers: PUBLIC REF ARRAY CD.Layer OF CDPrivate.LayerRef = permanent.NEW[ARRAY CD.Layer OF CDPrivate.LayerRef]; registerTechEvent: CDEvents.EventRegistration = CDEvents.RegisterEventType[$RegisterTechnology]; technologyRegistration: RefTab.Ref = RefTab.Create[]; -- contains technologies TechnologyPrivate: TYPE = REF TechnologyPrivateRep; TechnologyPrivateRep: PUBLIC TYPE = RECORD [ objectRegisterTab: RefTab.Ref, -- contains object types layerKeyTab: RefTab.Ref -- contains Layers ]; nilTechnologyPrivate: TechnologyPrivate = NEW[TechnologyPrivateRep _ [ objectRegisterTab: RefTab.Create[], --for technology dependant objects it contains NIL layerKeyTab: RefTab.Create[] ]]; RegisterObjectClass: PUBLIC PROC [objectType: ATOM, technology: CD.Technology_NIL] RETURNS [REF CD.ObjectClass] = BEGIN done: BOOL; class: REF CD.ObjectClass = permanent.NEW[CD.ObjectClass]; class.technology _ technology; class.objectType _ objectType; class.further _ RefTab.Create[]; class.drawMe _ CDDefaultProcs.DrawMe; class.quickDrawMe _ CDDefaultProcs.QuickDrawMe; class.showMeSelected _ CDDefaultProcs.ShowMeSelected; class.hitInside _ CDDefaultProcs.HitInside; class.interestRect _ CDDefaultProcs.InterestRect; class.oldInsideRect _ DefaultOldInsideRect; class.inDirectory _ FALSE; class.wireTyped _ FALSE; class.describe _ CDDefaultProcs.Describe; class.describeInst _ CDDefaultProcs.DescribeInstance; class.origin _ CDDefaultProcs.Origin; class.properties _ CD.InitPropRef[]; IF technology=NIL THEN done _ RefTab.Insert[nilTechnologyPrivate.objectRegisterTab, objectType, class] ELSE { techPriv: TechnologyPrivate = technology.technologyPrivate; objectRegisterTab: RefTab.Ref = techPriv.objectRegisterTab; globFound: BOOL; x: REF; [globFound, x] _ RefTab.Fetch[nilTechnologyPrivate.objectRegisterTab, objectType]; IF globFound AND x#NIL THEN done _ FALSE ELSE { [] _ RefTab.Insert[nilTechnologyPrivate.objectRegisterTab, objectType, NIL]; done _ RefTab.Insert[objectRegisterTab, objectType, class]; -- technology register } }; IF NOT done THEN ERROR Error[doubleRegistration]; RETURN [class] END; FetchObjectClass: PUBLIC PROC [objectType: REF, technology: CD.Technology_NIL] RETURNS [REF CD.ObjectClass] = BEGIN x: REF; class: REF CD.ObjectClass _ NIL; found: BOOL _ FALSE; IF technology#NIL THEN { -- search in technology table techPriv: TechnologyPrivate = technology.technologyPrivate; [found, x] _ RefTab.Fetch[techPriv.objectRegisterTab, objectType]; }; IF NOT found THEN { -- search in global table [found, x] _ RefTab.Fetch[nilTechnologyPrivate.objectRegisterTab, objectType]; }; IF found THEN class _ NARROW[x]; RETURN [class] END; DefaultOldInsideRect: PROC [ob: CD.Object] RETURNS [CD.Rect] = BEGIN RETURN [ob.class.interestRect[ob]] END; lastLayer: CD.Layer _ 3; InitiateLayer: PROC [lev: CD.Layer, technology: CD.Technology_NIL, uniqueKey: ATOM] = BEGIN techPriv: TechnologyPrivate; layers[lev].technology _ technology; layers[lev].uniqueKey _ uniqueKey; IF technology=NIL THEN techPriv _ nilTechnologyPrivate ELSE { techPriv _ technology.technologyPrivate; technology.usedLayers _ CONS[lev, technology.usedLayers] }; [] _ RefTab.Insert[techPriv.layerKeyTab, uniqueKey, layers[lev]]; END; ConvertLayer: PUBLIC ENTRY PROC [technology: CD.Technology, uniqueKey: ATOM, into: CD.Layer] = BEGIN ENABLE UNWIND => NULL; techPriv: TechnologyPrivate; IF uniqueKey=NIL OR uniqueKey=$NIL THEN RETURN WITH ERROR Error[callingError, "bad uniqueKey"]; -- avoid problems with NIL as ATOM; any IO routine might use $NIL instead IF technology=NIL THEN techPriv _ nilTechnologyPrivate ELSE techPriv _ technology.technologyPrivate; [] _ RefTab.Insert[techPriv.layerKeyTab, uniqueKey, layers[into]]; END; NewLayer: PUBLIC ENTRY PROC [technology: CD.Technology_NIL, uniqueKey: ATOM] RETURNS [CD.Layer] = BEGIN ENABLE UNWIND => NULL; IF uniqueKey=NIL OR uniqueKey=$NIL THEN RETURN WITH ERROR Error[callingError, "bad uniqueKey"]; -- avoid problems with NIL as ATOM; any IO routine might use $NIL instead IF lastLayer>=CD.layerNum-1 THEN RETURN WITH ERROR Error[noResource, "too many layers have been requested; (probably too many different technologies are used)"]; lastLayer _ lastLayer+1; InitiateLayer[lastLayer, technology, uniqueKey]; RETURN [lastLayer] END; FetchLayer: PUBLIC PROC [t: CD.Technology, uniqueKey: ATOM] RETURNS [CD.Layer] = BEGIN found: BOOL_FALSE; l: CD.Layer _ CD.highLightError; x: REF; IF t#NIL THEN { techPriv: TechnologyPrivate = t.technologyPrivate; [found: found, val: x] _ RefTab.Fetch[techPriv.layerKeyTab, uniqueKey]; }; IF ~found THEN { [found: found, val: x] _ RefTab.Fetch[nilTechnologyPrivate.layerKeyTab, uniqueKey]; }; IF found THEN l _ NARROW[x, CDPrivate.LayerRef].number; RETURN [l] END; LayerTechnology: PUBLIC PROC [l: CD.Layer] RETURNS [CD.Technology] = BEGIN RETURN [layers[l].technology]; END; LayerKey: PUBLIC PROC [l: CD.Layer] RETURNS [ATOM] = BEGIN RETURN [layers[l].uniqueKey]; END; CreateDrawRef: PUBLIC PROC [design: CD.Design, deviceContext: Imager.Context] RETURNS [class: CD.DrawRef] = BEGIN class _ NEW[CD.DrawInformation _ [ interestClip: CDBasics.universe, minimalSize: 0, scaleHint: 0.0, drawChild: CDDefaultProcs.DrawChild, drawRect: CDDefaultProcs.DrawRect, drawOutLine: CDDefaultProcs.DrawOutLine, drawContext: CDDefaultProcs.DrawContext, drawComment: CDDefaultProcs.DrawComment, stopFlag: NEW[BOOL _ FALSE], priorityChecker: CDDefaultProcs.IgnorePriority, setGround: CDDefaultProcs.IgnoreGround, deviceContext: deviceContext, properties: CD.InitPropRef[], design: design ]]; END; RegisterTechnology: PUBLIC PROC [key: ATOM, name: Rope.ROPE, lambda: CD.Number] RETURNS [CD.Technology] = BEGIN t: CD.Technology = permanent.NEW[CD.TechnologyRep_[ properties: CD.InitPropRef[], key: key, name: IF name#NIL THEN name ELSE Atom.GetPName[key], lambda: lambda, usedLayers: NIL, technologyPrivate: permanent.NEW[TechnologyPrivateRep _ [RefTab.Create[], RefTab.Create[]]] ]]; IF ~RefTab.Insert[technologyRegistration, key, t] THEN { Error[doubleRegistration, "technology exist already"]; }; [] _ CDEvents.ProcessEvent[ev: registerTechEvent, design: NIL, x: t]; RETURN[t] END; FetchTechnology: PUBLIC PROC [key: ATOM] RETURNS [tech: CD.Technology _ NIL] = BEGIN x: REF; found: BOOL; [found: found, val: x] _ RefTab.Fetch[technologyRegistration, key]; IF found THEN tech _ NARROW[x]; END; EnumerateTechnologies: PUBLIC PROC [proc: CD.TechnologyEnumerator] RETURNS [quit: BOOL] = BEGIN Action: RefTab.EachPairAction = { quit _ proc[NARROW[val]] }; quit _ RefTab.Pairs[technologyRegistration, Action]; END; IF registerTechEvent=NIL THEN ERROR; FOR l: CD.Layer IN CD.Layer DO layers[l] _ permanent.NEW[CDPrivate.LayerRec _ [ properties: CD.InitPropRef[], number: l ]]; layers[l].globalUniqueKey _ layers[l]; ENDLOOP; InitiateLayer[CD.combined, NIL, $combined]; InitiateLayer[CD.highLightShade, NIL, $highLightShade]; InitiateLayer[CD.highLightError, NIL, $highLightError]; InitiateLayer[CD.backGround, NIL, $backGround]; END. CDImpl.mesa (part of ChipNDale) Copyright c 1983, 1985 by Xerox Corporation. All rights reserved. Christian Jacobi, June 24, 1983 5:07 pm last edited Christian Jacobi, December 30, 1985 10:13:43 am PST --assume everithing gets correct even if all references are lost, --don't care about memory area, hint only --also initializes procedures with default values --still check if it might be global --global register it used per technology --may find it but have NIL value: then is technologydependant --Helps conversion when layers are renamed --Returns NIL if key is already in use --This must be the only way to create data of type TechnologyRep --not ENTRY since RefTab.Insert does necessary monitoring and CDEvents.ProcessEvent --is dangerous --Returns NIL if key is not registered Κ ˜codešœ!™!Kšœ Οmœ7™BKšœ(™(Kšœ?™?—K˜šΟk ˜ Kšœ˜Kšžœ˜Kšœ ˜ K˜K˜ K˜ Kšœ˜K˜Kšœ˜K˜ —K˜šΠblœžœžœ˜Kšžœžœ0˜@Kšžœžœ ˜Kšžœ ˜—Kšž˜K˜Kš œžœžœžœ1žœžœžœ˜^šœ žœ#˜2KšœB™BKšœ)™)—K˜š œžœžœžœžœžœ˜:Kš œ žœžœžœžœ˜5—K˜K˜`K˜Kšœ6Οc˜NK˜Kšœžœžœ˜3šœžœžœžœ˜,Kšœ ˜7Kšœ ˜*K˜K˜K˜—šœ*žœ˜FKšœ$ 3˜WKšœ˜Kšœ˜—K˜K˜š Οnœžœžœžœžœ žœ˜SKšžœžœ˜Kšœ2™2Kšž˜Kšœžœ˜ Kšœžœžœžœ˜:K˜K˜Kšœ ˜ Kšœ%˜%Kšœ/˜/Kšœ5˜5Kšœ+˜+Kšœ1˜1Kšœ+˜+Kšœžœ˜Kšœžœ˜Kšœ)˜)Kšœ5˜5Kšœ%˜%Kšœ$˜$šžœ žœžœ˜KšœO˜O—šž˜K˜;K˜;Kšœ žœ˜Kšœžœ˜šœS˜SKšœ#™#—Kš žœ žœžœžœž˜(šžœ˜šœGžœ˜MKšœ(™(—Kšœ< ˜RKšž˜—Kšžœ˜—Kšžœžœžœžœ˜1Kšžœ˜Kšžœ˜K˜—š ‘œžœžœžœžœ žœ˜OKšžœžœ˜Kšž˜Kšœžœ˜Kšœžœžœ˜ Kšœžœžœ˜šžœ žœžœ ˜6K˜;K˜BKšœ˜—šžœžœžœ ˜-KšœN˜NKšœ=™=Kšœ˜—Kšžœžœ žœ˜ Kšžœ˜Kšžœ˜K˜—š ‘œžœžœ žœžœ ˜?Kšž˜Kšžœ˜"Kšžœ˜K˜—K˜Kšœ žœ ˜K˜š ‘ œžœžœžœ žœ žœ˜UKšž˜Kšœ˜Kšœ$˜$Kšœ"˜"Kšžœ žœžœ ˜6šžœ˜K˜(Kšœžœ˜8K˜—KšœA˜AKšžœ˜—K˜š‘ œžœžœžœžœžœžœ ˜^Kšœ*™*Kšž˜Kšžœžœžœ˜Kšœ˜Kšžœ žœžœžœžœžœžœ' I˜©Kšžœ žœžœ ˜6Kšžœ)˜-KšœB˜BKšžœ˜—K˜š‘œžœžœžœžœ žœ žœžœžœ ˜aKšž˜Kšžœžœžœ˜Kšžœ žœžœžœžœžœžœ' I˜©Kš žœ žœ žœžœžœžœo˜‘K˜Kšœ0˜0Kšžœ ˜Kšžœ˜K˜—K˜š‘ œžœžœžœžœžœžœ ˜PKšž˜Kšœž œ˜Kšœžœ žœ˜ Kšœžœ˜šžœžœžœ˜K˜2KšœG˜GKšœ˜—šžœžœ˜KšœS˜SK˜—Kšžœžœžœ˜7Kšžœ˜ Kšžœ˜K˜—š‘œžœžœžœ˜DKšž˜Kšžœ˜Kšžœ˜—K˜š ‘œžœžœžœžœžœ˜4Kšž˜Kšžœ˜Kšžœ˜—K˜š ‘ œžœžœ žœ(žœ žœ ˜kKšž˜šœžœžœ˜"Kšœ ˜ Kšœ˜Kšœ˜Kšœ$˜$Kšœ"˜"Kšœ(˜(Kšœ(˜(Kšœ(˜(Kšœ žœžœžœ˜Kšœ/˜/Kšœ'˜'Kšœ˜Kšœ žœ˜Kšœ˜Kšœ˜—šžœ˜K˜——š‘œžœžœžœ žœžœ žœžœ˜iKšœ&™&šœ@™@KšœS™SKšœ™—Kšž˜šœžœžœžœ˜3Kšœ žœ˜K˜ Kš œžœžœžœžœ˜4Kšœ˜Kšœ žœ˜Kšœžœ;˜[Kšœ˜—šžœ0žœ˜8Kšœ6˜6K˜—Kšœ:žœ˜EKšžœ˜ Kšžœ˜K˜—š‘œžœžœžœžœžœ žœ˜NKšœ&™&Kšž˜Kšœžœ žœ˜K˜CKšžœžœžœ˜!Kšžœ˜—K˜š ‘œžœžœ!žœžœ˜YKšž˜šΟbœ˜!Kšœ žœ˜K˜—Kšœ4˜4Kšžœ˜—K˜Kšžœžœžœžœ˜&š žœžœžœžœž˜šœžœ˜0Kšœ žœ˜Kšœ ˜ Kšœ˜—Kšœ&˜&Kšžœ˜—Kšœžœ žœ ˜+Kšœžœžœ˜7Kšœžœžœ˜7Kšœžœ žœ˜/Kšžœ˜K˜K˜—…—Ϊ*