DIRECTORY CD, CDAtomicObjects, CDBasics, CDCallSpecific, CDIO, CDLRUCache, CDOrient, RefTab, Rope, RuntimeError, TokenIO; CDAtomicObjectsImpl: CEDAR MONITOR IMPORTS CD, CDBasics, CDCallSpecific, CDIO, CDLRUCache, CDOrient, RefTab, RuntimeError, TokenIO EXPORTS CDAtomicObjects SHARES CD = --want access technology of ObjectProcs BEGIN DrawRec: TYPE = CDAtomicObjects.DrawRec; DrawList: TYPE = CDAtomicObjects.DrawList; AtomicObsPtr: TYPE = CDAtomicObjects.AtomicObsPtr; AtomicObsRec: TYPE = CDAtomicObjects.AtomicObsRec; FillObjectProc: TYPE = CDAtomicObjects.FillObjectProc; ------------ classTable: RefTab.Ref = RefTab.Create[41]; ClassEntry: TYPE = RECORD[ tech: CD.Technology, fillProc: FillObjectProc, p: REF CD.ObjectProcs_NIL ]; GetClassEntry: PROC [class: ATOM, tech: CD.Technology] RETURNS [ce: REF ClassEntry_NIL] = INLINE BEGIN p: REF CD.ObjectProcs = CD.FetchObjectProcs[class, tech]; IF p#NIL THEN ce _ NARROW[ classTable.Fetch[p].val ] END; ------------ cache1: CDLRUCache.LRUCache = CDLRUCache.Create[size: 37, aequivalenceProc: AequivalenceAO]; cache2: CDLRUCache.LRUCache = CDLRUCache.Create[size: 37, aequivalenceProc: AequivalenceAO]; cache3: CDLRUCache.LRUCache = CDLRUCache.Create[size: 37, aequivalenceProc: AequivalenceAO]; myRectPtr: CD.RectPtr = NEW[CD.RectRecord]; AequivalenceAO: PROC [mySpecific, other: REF ANY] RETURNS [BOOL] = { RETURN [~ISTYPE[mySpecific, CD.RectPtr]] }; ------------ CreateAtomicOb: PUBLIC PROC [class: ATOM, size: CD.DesignPosition, tech: CD.Technology, lev: CD.Layer_CD.combined] RETURNS [ob: CD.ObPtr_NIL] = BEGIN ENABLE UNWIND => NULL; ce: REF ClassEntry = GetClassEntry[class, tech]; size _ CDBasics.MaxPoint[size, [1, 1]]; IF ce#NIL THEN { cache: CDLRUCache.LRUCache _ SELECT size.x+size.y FROM <=30 => cache1, --any minimal size ndiff construct <=60 => cache2, --any minimal size pdiff construct ENDCASE => cache3; --long crazy stuff aop: AtomicObsPtr = NEW[AtomicObsRec _ [ir: CDBasics.empty]]; ob1: CD.ObPtr _ cache.UnusedOrNew[]; ob1.p _ ce.p; ob1.size _ size; ob1.layer _ lev; ob1.specificRef _ aop; IF ce.fillProc[ob1 ! RuntimeError.UNCAUGHT => GOTO xx].mustFail THEN RETURN [NIL]; ob _ cache.ReplaceByAequivalent[ob1]; IF ob=ob1 THEN TRUSTED { --new entry IF ~CDBasics.Inside[aop.ir, CDBasics.RectAt[[0, 0], ob.size]] OR CDBasics.empty=aop.ir OR (aop.rList=NIL AND aop.sList=NIL) THEN GOTO xx; IF aop.sList#NIL AND ce.p.drawMe=XDrawAO AND ce.p.quickDrawMe=XDrawAO THEN { p: REF CD.ObjectProcs = LOOPHOLE[ob.p]; --get rid of readonly p.drawMe _ p.quickDrawMe _ DrawAO; }; IF aop.ir#CDBasics.RectAt[[0, 0], ob.size] THEN { IF aop.ir.x1<0 OR aop.ir.y1<0 OR aop.ir.x2>ob.size.x OR aop.ir.y2>ob.size.y THEN GOTO xx; IF ce.p.showMeSelected=XShowSelectedAO THEN { p: REF CD.ObjectProcs = LOOPHOLE[ob.p]; --get rid of readonly p.showMeSelected _ ShowSelectedAO; } }; }; }; EXITS xx => RETURN WITH ERROR CD.Error[other, "Error in technology, implementing creation of atomic object"]; END; RegisterAtomicObClass: PUBLIC PROC [class: ATOM, fillProc: FillObjectProc, description: Rope.ROPE_NIL, tech: CD.Technology_NIL] RETURNS [type: REF CD.ObjectProcs _ NIL] = BEGIN ce: REF ClassEntry _ NEW[ClassEntry_[ tech: tech, fillProc: fillProc ]]; done: BOOL_TRUE; ce.p _ type _ CD.RegisterObjectType[class, tech ! CD.Error => {done _ FALSE; CONTINUE}]; IF ~done THEN RETURN WITH ERROR CD.Error[doubleRegistration]; done _ RefTab.Insert[classTable, type, ce]; type.drawMe _ type.quickDrawMe _ XDrawAO; type.internalRead _ ReadAO; type.internalWrite _ WriteAO; type.oldInsideRect _ type.interestRect _ InsideAO; type.showMeSelected _ XShowSelectedAO; type.wireTyped _ FALSE; type.description _ description; CDCallSpecific.Register[$Lengthen, type, LengthenAO]; END; Incorporate: PUBLIC PROC [ob: CD.ObPtr, r: CD.DesignRect, lev: CD.Layer, inside: BOOL _ TRUE, save: BOOL _ FALSE] = BEGIN aop: AtomicObsPtr = NARROW[ob.specificRef]; IF inside THEN aop.ir _ CDBasics.Surround[aop.ir, r]; IF save THEN aop.sList _ CONS[[r, lev], aop.sList] ELSE aop.rList _ CONS[[r, lev], aop.rList]; END; -------------- ReadAO: CD.InternalReadProc --PROC [] RETURNS [ObPtr]-- = BEGIN x: INT = TokenIO.ReadInt[]; y: INT = TokenIO.ReadInt[]; code: ATOM = TokenIO.ReadAtom[]; lev: CD.Layer = CDIO.ReadLayer[]; tech: CD.Technology = CDIO.DesignInReadOperation[].technology; RETURN [ CreateAtomicOb[code, [x, y], tech, lev] ] END; WriteAO: CD.InternalWriteProc -- PROC [me: ObPtr] -- = BEGIN TokenIO.WriteInt[me.size.x]; TokenIO.WriteInt[me.size.y]; TokenIO.WriteAtom[me.p.objectType]; CDIO.WriteLayer[me.layer]; END; XDrawAO: PROC [aptr: CD.ApplicationPtr, pos: CD.DesignPosition, orient: CD.Orientation, pr: CD.DrawRef] = BEGIN aop: AtomicObsPtr = NARROW[aptr.ob.specificRef]; FOR p: DrawList _ aop.rList, p.rest WHILE p#NIL DO pr.drawRect[ CDOrient.MapRect[ itemInCell: p.first.r, cellSize: aptr.ob.size, cellInstOrient: orient, cellInstPos: pos], p.first.lev, pr] ENDLOOP; END; DrawAO: PROC [aptr: CD.ApplicationPtr, pos: CD.DesignPosition, orient: CD.Orientation, pr: CD.DrawRef] = BEGIN aop: AtomicObsPtr = NARROW[aptr.ob.specificRef]; FOR p: DrawList _ aop.rList, p.rest WHILE p#NIL DO pr.drawRect[ CDOrient.MapRect[ itemInCell: p.first.r, cellSize: aptr.ob.size, cellInstOrient: orient, cellInstPos: pos], p.first.lev, pr] ENDLOOP; FOR p: DrawList _ aop.sList, p.rest WHILE p#NIL DO pr.saveRect[ CDOrient.MapRect[ itemInCell: p.first.r, cellSize: aptr.ob.size, cellInstOrient: orient, cellInstPos: pos], p.first.lev, pr] ENDLOOP; END; ShowSelectedAO: PROC [aptr: CD.ApplicationPtr, pos: CD.DesignPosition, orient: CD.Orientation, pr: CD.DrawRef] = BEGIN aop: AtomicObsPtr = NARROW[aptr.ob.specificRef]; pr.outLineProc[ CDOrient.MapRect[ itemInCell: aop.ir, cellSize: aptr.ob.size, cellInstOrient: orient, cellInstPos: pos], pr] END; XShowSelectedAO: PROC [aptr: CD.ApplicationPtr, pos: CD.DesignPosition, orient: CD.Orientation, pr: CD.DrawRef] = BEGIN pr.outLineProc[CDOrient.RectAt[pos, aptr.ob.size, orient], pr] END; InsideAO: PROC [ob: CD.ObPtr] RETURNS [CD.DesignRect] = BEGIN RETURN [NARROW[ob.specificRef, AtomicObsPtr].ir] END; LengthenAO: CDCallSpecific.CallProc = BEGIN ToPosition: PROC [x: REF] RETURNS [p: CD.DesignPosition] = BEGIN IF x=NIL THEN p _ [0, CD.lambda] ELSE WITH x SELECT FROM rp: REF CD.DesignPosition => p _ rp^; rn: REF CD.DesignNumber => p _ [0, rn^]; ENDCASE => p _ [0, 0]; END; amount: CD.DesignPosition = ToPosition[x]; IF amount.y=0 AND amount.x=0 THEN done _ FALSE ELSE { sz: CD.DesignPosition _ CDBasics.AddPoints[aptr.ob.size, amount]; new: CD.ObPtr _ CreateAtomicOb[size: sz, class: aptr.ob.p.objectType, lev: aptr.ob.layer, tech: aptr.ob.p.technology]; done _ new#NIL AND new#aptr.ob AND new.size#aptr.ob.size; IF done THEN { aptr.ob _ new; repaintMe _ TRUE; } }; END; END. zCDAtomicObjectsImpl.mesa (part of ChipNDale) Copyright c 1985 by Xerox Corporation. All rights reserved. by Christian Jacobi, March 13, 1985 9:49:28 am PST last edited by Christian Jacobi, April 11, 1985 12:57:25 pm PST --This module helps the implementation of a wide class of atomic ChipNDale --objects, which do not have children and are shared between designs. Despite --its name this are not the only atomic object classes. --RECORD [r: CD.DesignRect, lev: CD.Layer _ CD.highLightError]; --LIST OF DrawRec; --REF AtomicObsRec; --RECORD [ -- rList: DrawList_NIL, --do not change directly -- sList: DrawList_NIL, --do not change directly -- ir: CD.DesignRect, --do not change directly -- data: REF_NIL --for free use by class implementor -- ]; --PROC [ob: CD.ObPtr] RETURNS [mustFail: BOOL _ FALSE]; --read (and even rewrite) size, layer --calls IncorporateRect --do not read or write ir --rList, sList will be initialized to NIL --Insider info: mySpecific is already in the cache; other is the one to be inserted --NIL if not done --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... --TRUSTED because we LOOPHOLE; --LOOPHOLE because we change the ob's objectprocs in case the fillProc --change the p field --now check if we should change the objectprocs to be more general --drawMe, quickDrawMe are considered variables and should not --be changed by class implementor. --faster, hacked routine without saveRects --PROC [design: CD.Design, aptr: CD.ApplicationPtr, x: REF] --RETURNS [done: BOOL_TRUE, removeMe: BOOL_FALSE, include: CD.ApplicationList_NIL, --repaintMe: BOOL_FALSE, repaintInclude: BOOL_FALSE] --y field defaults to lambda, x field defaults to 0 --[0, 0] if not done --LengthenAO Ê 1˜šœ3™3Jšœ Ïmœ1™Jšžœ˜Jš žœ žœžœ žœžœžœ˜3—JšœB™Bš žœ žœžœžœžœ˜LJšœžœžœžœ ˜=Jšœ"˜"Jšœ˜—šžœ)žœ˜1Jš žœ žœ žœžœžœžœ˜Yšžœ%žœ˜.Jšœžœžœžœ ˜=Jšœ"˜"J˜—J˜—J˜—Jšœ˜—šžœžœžœžœ˜JšžœM˜O—Jšžœ˜—J˜š ¡¢ œžœžœ žœ˜1Jšœ˜Jšœžœžœ˜Jš œžœ žœžœžœžœžœ˜CJšœ>™>Jšœ"™"Jšž˜šœžœžœ ˜%Jšœ ˜ Jšœ˜J˜—Jšœž œ˜Jš œžœ"žœžœžœ˜Xšžœžœ˜Jšžœžœžœžœ˜/—Jšœ+˜+Jšœ)˜)Jšœ˜Jšœ˜Jšœ2˜2Jšœ&˜&Jšœžœ˜Jšœ˜Jšœ5˜5Jšžœ˜—J˜š ¡ œž œžœ žœžœ˜IJš œžœžœžœžœ˜*Jšž˜Jšœžœ˜+Jšžœžœ'˜5Jšžœžœ žœ˜2Jšžœ žœ˜+Jšžœ˜—J˜J˜J˜šŸœžœ œ˜9Jšž˜Jšœžœ˜Jšœžœ˜Jšœžœ˜ Jšœžœ žœ ˜!Jšœžœžœ$˜>Jšžœ,˜2Jšžœ˜—J˜šŸœžœ œ˜6Jšž˜Jšœ˜Jšœ˜Jšœ#˜#Jšžœ˜Jšžœ˜—J˜š ¡œžœžœžœžœžœ ˜iJšœ*™*Jšž˜Jšœžœ˜0šžœ!žœžœž˜2˜ ˜Jšœ˜Jšœ˜J˜J˜—Jšœ ˜ J˜—Jšžœ˜—Jšžœ˜—J˜š ¡œžœžœžœžœžœ ˜hJšž˜Jšœžœ˜0šžœ!žœžœž˜2˜ ˜Jšœ˜Jšœ˜J˜J˜—Jšœ ˜ J˜—Jšžœ˜—šžœ!žœžœž˜2˜ ˜Jšœ˜Jšœ˜J˜J˜—Jšœ ˜ J˜—Jšžœ˜—Jšžœ˜—J˜š¡œžœžœžœ˜GJšœžœžœ ˜)Jšž˜Jšœžœ˜0šœ˜˜Jšœ˜Jšœ˜J˜J˜—J˜—Jšžœ˜—J˜š¡œžœžœžœ˜HJšœžœžœ ˜)Jšž˜Jšœ>˜>Jšžœ˜—J˜š ¡œžœžœžœžœ˜7Jšž˜Jšžœžœ"˜0Jšžœ˜—J˜šŸ œ˜%šžœ žœžœžœ™