DIRECTORY CD, CDAtomicObjects, CDBasics, CDPrivate, CDIO, LRUCache, RefTab, Rope, RuntimeError, TokenIO; CDAtomicObjectsImpl: CEDAR MONITOR IMPORTS CD, CDBasics, CDIO, CDPrivate, LRUCache, RefTab, RuntimeError, 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[ classTable.Fetch[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_[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: ReadAO, internalWrite: WriteAO, 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]; }; ReadAO: CD.InternalReadProc --PROC [] RETURNS [Object]-- = { 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] }; WriteAO: CD.InternalWriteProc -- PROC [ob: Object] -- = { CDIO.WritePos[h, CD.InterestSize[ob]]; TokenIO.WriteAtom[h, ob.class.objectType]; CDIO.WriteLayer[h, ob.layer]; }; DrawAO: PROC [inst: CD.Instance, trans: CD.Transformation, pr: CD.DrawRef] = { FOR class: DrawList _ NARROW[inst.ob.specific, AtomicObsSpecific].rList, class.rest WHILE class#NIL DO pr.drawRect[CDBasics.MapRect[class.first.r, trans], class.first.layer, pr] ENDLOOP; }; ShowSelectedAO: PROC [inst: CD.Instance, trans: CD.Transformation, pr: CD.DrawRef] = { aop: AtomicObsSpecific = NARROW[inst.ob.specific]; pr.drawOutLine[CDBasics.MapRect[aop.ir, trans], CD.selectionLayer, pr] }; InsideAO: PROC [ob: CD.Object] RETURNS [CD.Rect] = { RETURN [NARROW[ob.specific, AtomicObsSpecific].ir] }; END. ¨CDAtomicObjectsImpl.mesa (part of ChipNDale) Copyright c 1985, 1986 by Xerox Corporation. All rights reserved. Created by Christian Jacobi, March 13, 1985 9:49:28 am PST Last Edited by: Christian Jacobi, October 22, 1986 12:37:25 pm PDT ---------- --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 old way had the size instead the interest rect in the file Κk˜codešœ3™3Kšœ Οmœ7™BKšœ;™;K™B—K˜šΟk ˜ Kšžœ˜Kšœ˜Kšœ ˜ Kšœ ˜ Kšžœ˜Kšœ ˜ Kšœ˜Kšœ˜Kšœ ˜ Kšœ˜K˜—šΠbnœžœž˜"Kšžœžœ žœ4˜NKšžœ˜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˜šŸœžœ œ˜