DIRECTORY CD, CDAtomicObjects, CDBasics, CDPrivate, CDProperties, CDIO, LRUCache, RefTab, Rope, RuntimeError, TerminalIO, TokenIO; CDAtomicObjectsImpl: CEDAR MONITOR IMPORTS CD, CDBasics, CDIO, CDPrivate, CDProperties, LRUCache, RefTab, RuntimeError, TerminalIO, TokenIO EXPORTS CDAtomicObjects SHARES CD = --want access technology of ObjectClass BEGIN DrawRec: TYPE = CDAtomicObjects.DrawRec; DrawList: TYPE = CDAtomicObjects.DrawList; AtomicObsSpecific: TYPE = CDAtomicObjects.AtomicObsSpecific; AtomicObsRec: TYPE = CDAtomicObjects.AtomicObsRec; FillObjectProc: TYPE = CDAtomicObjects.FillObjectProc; classTable: RefTab.Ref = RefTab.Create[41]; ClassEntry: TYPE = RECORD[ tech: CD.Technology, fillProc: FillObjectProc, class: CD.ObjectClass_NIL ]; GetClassEntry: PROC [classKey: ATOM, tech: CD.Technology] RETURNS [ce: REF ClassEntry_NIL] = INLINE { class: CD.ObjectClass = CD.FetchObjectClass[classKey, tech]; IF class#NIL THEN ce _ NARROW[ RefTab.Fetch[classTable, class].val ] }; queue: LRUCache.Handle _ LRUCache.Create[255, CDPrivate.Hash, CDPrivate.Equal]; free: CD.Object _ NIL; GiveOb: ENTRY PROC [] RETURNS [ob: CD.Object] = INLINE { ob _ free; free _ NIL; IF ob=NIL THEN ob _ NEW[CD.ObjectRep_[class: NIL, immutable: TRUE, specific: NEW[AtomicObsRec]]]; }; CreateAtomicOb: PUBLIC PROC [classKey: ATOM, size: CD.Position, tech: CD.Technology, layer: CD.Layer] RETURNS [ob: CD.Object_NIL] = { insert: BOOL; used: REF; ob1: CD.Object _ GiveOb[]; aop: AtomicObsSpecific _ NARROW[ob1.specific]; ce: REF ClassEntry = GetClassEntry[classKey, tech]; IF ce=NIL THEN RETURN; aop^ _ [NIL, CDBasics.empty]; ob1.class _ ce.class; ob1.bbox _ CDPrivate.MinBBox[size]; ob1.layer _ layer; ob1.specific _ aop; IF ce.fillProc[ob1 ! RuntimeError.UNCAUGHT => GOTO xx].mustFail THEN RETURN [NIL]; [insert: insert, used: used] _ LRUCache.Include[queue, ob1]; IF ~insert THEN { free _ ob1; ob _ NARROW[used]; } ELSE { ob _ ob1; IF aop.rList=NIL OR ~CDBasics.NonEmpty[aop.ir] OR aop.ir.x1<0 OR aop.ir.y1<0 OR aop.ir.x2>ob.bbox.x2 OR aop.ir.y2>ob.bbox.y2 THEN GOTO xx; }; EXITS xx => ERROR CD.Error[other, "Error in technology, implementing creation of atomic object"]; }; RegisterAtomicObClass: PUBLIC PROC [classKey: ATOM, fillProc: FillObjectProc, description: Rope.ROPE_NIL, tech: CD.Technology_NIL] RETURNS [type: CD.ObjectClass _ NIL] = { ce: REF ClassEntry _ NEW[ClassEntry_[ tech: tech, fillProc: fillProc ]]; done: BOOL_TRUE; ce.class _ type _ CD.RegisterObjectClass[classKey, [ technology: tech, drawMe: DrawAO, quickDrawMe: DrawAO, internalRead: ReadDLO, internalWrite: WriteDLO, interestRect: InsideAO, showMeSelected: ShowSelectedAO, wireTyped: FALSE, atomicOb: TRUE, description: description] ! CD.Error => {done _ FALSE; CONTINUE}]; IF ~done THEN RETURN WITH ERROR CD.Error[doubleRegistration]; done _ RefTab.Insert[classTable, type, ce]; }; Incorporate: PUBLIC PROC [ob: CD.Object, r: CD.Rect, layer: CD.Layer, inside: BOOL] = { aop: AtomicObsSpecific = NARROW[ob.specific]; IF inside THEN aop.ir _ CDBasics.Surround[aop.ir, r]; ob.bbox _ CDBasics.Surround[ob.bbox, r]; aop.rList _ CONS[[r, layer], aop.rList]; }; DrawAO: CD.DrawProc = { FOR class: DrawList _ NARROW[ob.specific, AtomicObsSpecific].rList, class.rest WHILE class#NIL DO pr.drawRect[pr, CDBasics.MapRect[class.first.r, trans], class.first.layer] ENDLOOP; }; anyAtomic: CD.ObjectClass _ CD.RegisterObjectClass[$Atomic, [ technology: NIL, drawMe: DrawAO, quickDrawMe: DrawAO, internalRead: ReadDLO, internalWrite: WriteDLO, interestRect: InsideAO, showMeSelected: ShowSelectedAO, wireTyped: FALSE, atomicOb: TRUE, description: "unknown atomic object" ]]; OldReadAO: CD.InternalReadProc = { sz: CD.Position _ CDIO.ReadPos[h]; code: ATOM = TokenIO.ReadAtom[h]; layer: CD.Layer = CDIO.ReadLayer[h]; tech: CD.Technology = CDIO.DesignInReadOperation[h].technology; ob: CD.Object _ CreateAtomicOb[code, sz, tech, layer]; IF CDIO.VersionKey[h]<10 THEN { ob _ CreateAtomicOb[code, [sz.x - (ob.bbox.x2-ob.bbox.x1-sz.x), sz.y - (ob.bbox.y2-ob.bbox.y1-sz.y)], tech, layer]; }; RETURN [ob] }; ReadDLO: CD.InternalReadProc = { ob: CD.Object; ir, bbox: CD.Rect; layer: CD.Layer; key2: ATOM; cnt: INT; dr: DrawRec; rl: DrawList_NIL; tech: CD.Technology = CDIO.DesignInReadOperation[h].technology; IF h.oldVersion AND CDIO.VersionKey[h]<=17 THEN { RETURN [OldReadAO[h, key]]; }; key2 _ TokenIO.ReadAtom[h]; ir _ CDIO.ReadRect[h]; bbox _ CDIO.ReadRect[h]; layer _ CDIO.ReadLayer[h]; cnt _ TokenIO.ReadInt[h]; FOR i: INT IN [0..cnt) DO dr.layer _ CDIO.ReadLayer[h]; dr.r _ CDIO.ReadRect[h]; rl _ CONS[dr, rl]; ENDLOOP; ob _ CreateAtomicOb[key2, CDBasics.SizeOfRect[ir], tech, layer]; IF ob=NIL OR ob.bbox#bbox OR CD.InterestRect[ob]#ir THEN { design: CD.Design _ CDIO.DesignInReadOperation[h]; ob _ NEW[CD.ObjectRep_[ bbox: bbox, class: anyAtomic, immutable: TRUE, specific: NEW[AtomicObsRec_[rl, ir]], layer: layer ]]; CDProperties.PutObjectProp[ob, $OriginalKey, key2]; CDProperties.PutObjectProp[ob, $OriginalSize, NEW[CD.Position_CDBasics.SizeOfRect[ir]]]; IF CDProperties.GetDesignProp[design, $ContainsUnknownAtomicObjects]=NIL THEN { TerminalIO.PutRope["\n\n*** WARNING ***"]; TerminalIO.PutRope["\nThis design contains atomic objects which are currently undefined"]; TerminalIO.PutRope["\nPlease RUN the appropriate code and READ THE DESIGN AGAIN"]; TerminalIO.PutRope["\nFailure to do this will result in loss of information\n\n"]; [] _ TerminalIO.Confirm["Confirm that you read the WARNING"]; CDProperties.PutDesignProp[design, $ContainsUnknownAtomicObjects, $Yep]; }; }; RETURN [ob]; }; WriteDLO: CD.InternalWriteProc = { cnt: INT _ 0; rList: DrawList _ NARROW[ob.specific, AtomicObsSpecific].rList; TokenIO.WriteAtom[h, ob.class.objectType]; CDIO.WriteRect[h, CD.InterestRect[ob]]; CDIO.WriteRect[h, ob.bbox]; CDIO.WriteLayer[h, ob.layer]; FOR rl: DrawList _ rList, rl.rest WHILE rl#NIL DO cnt _ cnt+1 ENDLOOP; TokenIO.WriteInt[h, cnt]; FOR rl: DrawList _ rList, rl.rest WHILE cnt>0 DO CDIO.WriteLayer[h, rl.first.layer]; CDIO.WriteRect[h, rl.first.r]; cnt_cnt-1; ENDLOOP; }; ShowSelectedAO: CD.DrawProc = { aop: AtomicObsSpecific = NARROW[ob.specific]; pr.drawOutLine[pr, CDBasics.MapRect[aop.ir, trans], CD.selectionLayer] }; InsideAO: PROC [ob: CD.Object] RETURNS [CD.Rect] = { RETURN [NARROW[ob.specific, AtomicObsSpecific].ir] }; END. κCDAtomicObjectsImpl.mesa (part of ChipNDale) Copyright c 1985, 1986, 1987 by Xerox Corporation. All rights reserved. Created by Christian Jacobi, March 13, 1985 9:49:28 am PST Last Edited by: Christian Jacobi, April 20, 1987 6:13:16 pm PDT Louis Monier December 5, 1988 2:25:35 pm PST ---------- --as efficiencyhack, the object is now already in the lru cache, inspite --of not yet beeing checked. --If object is bad, however, the technology implementing code is bad, and therefore --we do not really feel responsible for the design... --drawMe, quickDrawMe are considered variables and should not --be changed by class implementor. ------------ --The very old way had the size instead the interest rect in the file -- Warn user Κγ˜codešœ3™3Kšœ Οmœ=™HKšœ;™;K™?K™,—K˜šΟk ˜ Kšžœ˜Kšœ˜Kšœ ˜ Kšœ ˜ Kšœ ž˜ Kšžœ˜Kšœ ˜ Kšœ˜Kšœ˜Kšœ ˜ Kšœ ˜ Kšœ˜K˜—šΠbnœžœž˜"Kšžœžœ žœN˜hKšžœ˜KšžœžœΟc'˜4—Kšž˜K˜Kšœ žœ˜(Kšœ žœ˜*Kšœžœ%˜™>Kšœ"™"šœžœžœ ˜%Kšœ ˜ Kšœ˜K˜—Kšœžœžœ˜šœžœ ˜4Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ ˜ Kšœ žœ˜Kšœ žœ˜Kšœžœžœžœ˜B—šžœžœ˜Kšžœžœžœžœ˜/—Kšœ+˜+Kšœ˜—K˜š‘ œžœžœžœ žœžœžœ˜WKšœžœ˜-Kšžœžœ'˜5Kšœžœžœ ˜(Kšœ žœ˜(Kšœ˜—K˜Kšœ ™ K˜š‘œ˜š žœžœ3žœžœž˜aKšœJ˜JKšžœ˜—Kšœ˜—K˜šœ žœžœ˜=Kšœ žœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ ˜ Kšœ žœ˜Kšœ žœ˜Kšœ$˜$Kšœ˜—K˜š‘ œžœ˜"Kšœžœ žœ ˜"Kšœžœ˜!Kšœžœ žœ˜$Kšœžœžœ%˜?Kšœžœ0˜6šžœžœžœ˜Kš E™EKšœs˜sK˜—Kšžœ˜ Kšœ˜—K˜š‘œžœ˜ Kšœžœžœžœ˜3Kšœžœžœžœ˜4Kšœžœžœ%˜?šžœžœžœžœ˜1Kšžœ˜K˜—Kšœ˜Kšœžœžœ ˜/Kšœžœ(˜4šžœžœžœ ž˜Kšœ žœžœ ˜6Kšœžœ ˜Kšžœ˜—Kšœ@˜@š žœžœžœžœžœžœ˜:Kšœžœ žœ˜2šœžœžœ ˜Kšœ ˜ Kšœ˜Kšœ žœ˜Kšœ žœ˜%Kšœ ˜ Kšœ˜—Kšœ3˜3Kšœ.žœžœ$˜XK™ šžœCžœžœ˜OKšœ*˜*KšœZ˜ZKšœR˜RKšœR˜RKšœ=˜=KšœH˜HKšœ˜—K˜—Kšžœ˜ Kšœ˜—K˜š‘œžœ˜"Kšœžœ˜ Kšœžœ'˜?Kšœ*˜*Kšžœžœ˜'Kšžœ˜Kšžœ˜Kš žœžœžœžœ žœ˜FKšœ˜šžœžœž˜0Kšžœ˜#Kšžœ˜Kšœ ˜ Kšžœ˜—K˜K˜—K˜š‘œ˜Kšœžœ˜-Kšœ3žœ˜FKšœ˜—K˜š ‘œžœžœ žœžœ ˜4Kšžœžœ$˜2Kšœ˜—K˜Kšžœ˜K˜—…—Τ$‘