DIRECTORY CD, CDAtomicObjects, CDBasics, CDCallSpecific, CDPrivate, CDIO, CDOrient, LRUCache, RefTab, Rope, RuntimeError, TokenIO; CDAtomicObjectsImpl: CEDAR MONITOR IMPORTS CD, CDBasics, CDCallSpecific, CDIO, CDOrient, CDPrivate, LRUCache, RefTab, RuntimeError, TokenIO EXPORTS CDAtomicObjects SHARES CD = --want access technology of ObjectClass 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, 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, 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_[specificRef: NEW[AtomicObsRec]]]; }; Equal: PROC[x, y: REF] RETURNS [BOOL] = { ob1: CD.Object = NARROW[x]; ob2: CD.Object = NARROW[y]; RETURN [ ob1.class=ob2.class AND ob1.size=ob2.size AND ob1.layer=ob2.layer AND CD.InterestRect[ob1]=CD.InterestRect[ob2] ] }; CreateAtomicOb: PUBLIC PROC [classKey: ATOM, size: CD.Position, tech: CD.Technology, lev: CD.Layer] RETURNS [ob: CD.Object_NIL] = { insert: BOOL; used: REF; ob1: CD.Object _ GiveOb[]; aop: AtomicObsPtr _ NARROW[ob1.specificRef]; ce: REF ClassEntry = GetClassEntry[classKey, tech]; IF ce=NIL THEN RETURN; aop^ _ [NIL, CDBasics.empty]; ob1.class _ ce.class; ob1.size _ CDBasics.MaxPoint[size, [1, 1]]; ob1.layer _ lev; ob1.specificRef _ 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.size.x OR aop.ir.y2>ob.size.y THEN GOTO xx; IF aop.ir#CDBasics.RectAt[[0, 0], ob.size] THEN IF ce.class.showMeSelected=XShowSelectedAO THEN ob.class.showMeSelected _ ShowSelectedAO; }; 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: XShowSelectedAO, wireTyped: FALSE, description: description] ! CD.Error => {done _ FALSE; CONTINUE}]; IF ~done THEN RETURN WITH ERROR CD.Error[doubleRegistration]; done _ RefTab.Insert[classTable, type, ce]; CDCallSpecific.Register[$Lengthen, type, LengthenAO]; }; Incorporate: PUBLIC PROC [ob: CD.Object, r: CD.Rect, lev: CD.Layer, inside: BOOL] = { aop: AtomicObsPtr = NARROW[ob.specificRef]; IF inside THEN aop.ir _ CDBasics.Surround[aop.ir, r]; aop.rList _ CONS[[r, lev], aop.rList]; }; ReadAO: CD.InternalReadProc --PROC [] RETURNS [Object]-- = { sz: CD.Position _ CDIO.ReadPos[]; code: ATOM = TokenIO.ReadAtom[]; lev: CD.Layer = CDIO.ReadLayer[]; tech: CD.Technology = CDIO.DesignInReadOperation[].technology; ob: CD.Object _ CreateAtomicOb[code, sz, tech, lev]; IF CDIO.VersionKey[]<10 THEN { ob _ CreateAtomicOb[code, [sz.x - (ob.size.x-sz.x), sz.y - (ob.size.y-sz.y)], tech, lev]; }; RETURN [ob] }; WriteAO: CD.InternalWriteProc -- PROC [me: Object] -- = { CDIO.WritePos[CD.InterestSize[me]]; TokenIO.WriteAtom[me.class.objectType]; CDIO.WriteLayer[me.layer]; }; DrawAO: PROC [inst: CD.Instance, pos: CD.Position, orient: CD.Orientation, pr: CD.DrawRef] = { FOR class: DrawList _ NARROW[inst.ob.specificRef, AtomicObsPtr].rList, class.rest WHILE class#NIL DO pr.drawRect[ CDOrient.MapRect[ itemInCell: class.first.r, cellSize: inst.ob.size, cellInstOrient: orient, cellInstPos: pos], class.first.lev, pr] ENDLOOP; }; ShowSelectedAO: PROC [inst: CD.Instance, pos: CD.Position, orient: CD.Orientation, pr: CD.DrawRef] = { aop: AtomicObsPtr = NARROW[inst.ob.specificRef]; pr.drawOutLine[ CDOrient.MapRect[ itemInCell: aop.ir, cellSize: inst.ob.size, cellInstOrient: orient, cellInstPos: pos], CD.selectionLayer, pr] }; XShowSelectedAO: PROC [inst: CD.Instance, pos: CD.Position, orient: CD.Orientation, pr: CD.DrawRef] = { pr.drawOutLine[CDOrient.RectAt[pos, inst.ob.size, orient], CD.selectionLayer, pr] }; InsideAO: PROC [ob: CD.Object] RETURNS [CD.Rect] = { RETURN [NARROW[ob.specificRef, AtomicObsPtr].ir] }; LengthenAO: CDCallSpecific.CallProc = { ToPosition: PROC [x: REF] RETURNS [class: CD.Position] = { IF x=NIL THEN class _ [0, design.technology.lambda] ELSE WITH x SELECT FROM rp: REF CD.Position => class _ rp^; rn: REF CD.Number => class _ [0, rn^]; ENDCASE => class _ [0, 0]; }; amount: CD.Position = ToPosition[x]; IF amount.y=0 AND amount.x=0 THEN done _ FALSE ELSE { sz: CD.Position _ CDBasics.AddPoints[CD.InterestSize[inst.ob], amount]; new: CD.Object _ CreateAtomicOb[size: sz, classKey: inst.ob.class.objectType, lev: inst.ob.layer, tech: inst.ob.class.technology]; done _ new#NIL AND new#inst.ob AND new.size#inst.ob.size; IF done THEN { inst.ob _ new; repaintMe _ TRUE; } }; }; 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, August 16, 1986 6:57:05 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... --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. ------------ --The old way had the size instead the interest rect in the file --PROC [design: CD.Design, inst: CD.Instance, x: REF] --RETURNS [done: BOOL_TRUE, removeMe: BOOL_FALSE, include: CD.InstanceList_NIL, --repaintMe: BOOL_FALSE, repaintInclude: BOOL_FALSE] --y field defaults to lambda, x field defaults to 0 --[0, 0] if not done --LengthenAO Κ ˜codešœ3™3Kšœ Οmœ7™BKšœ;™;K™@—K˜šΟk ˜ Kšžœ˜Kšœ˜Kšœ ˜ Kšœ˜Kšœ ˜ Kšžœ˜Kšœ ˜ Kšœ ˜ Kšœ˜Kšœ˜Kšœ ˜ Kšœ˜K˜—šΠbnœžœž˜"Kšžœžœžœ>˜hKšžœ˜KšžœžœΟc'˜4—Kšž˜K˜Kšœ žœ˜(Kšœ žœ˜*Kšœžœ ˜2Kšœžœ ˜2Kšœžœ"˜6K˜Kšœ ™ K˜Kšœ+˜+šœ žœžœ˜Kšœžœ ˜Kšœ˜Kšœžœ ž˜Kšœ˜—K˜šΟn œžœ žœžœ žœžœ žœžœ˜eKšœžœžœ"˜™>Kšœ"™"šœžœžœ ˜%Kšœ ˜ Kšœ˜K˜—Kšœžœžœ˜šœžœ ˜4Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ!˜!Kšœ žœ˜Kšœžœžœžœ˜B—šžœžœ˜Kšžœžœžœžœ˜/—Kšœ+˜+Kšœ5˜5Kšœ˜—K˜š‘ œžœžœžœ žœ žœžœ˜UKšœžœ˜+Kšžœžœ'˜5Kšœ žœ˜&Kšœ˜—K˜Kšœ ™ K˜šŸœžœ œ˜Kšœžœ.˜4šžœžœžœ˜Kšœ@™@KšœY˜YK˜—Kšžœ˜ Kšœ˜—K˜šŸœžœ œ˜9Kšžœ žœ˜#Kšœ'˜'Kšžœ˜Kšœ˜—K˜š ‘œžœžœžœžœžœ ˜^š žœžœ6žœžœž˜d˜ ˜Kšœ˜Kšœ˜K˜K˜—Kšœ˜K˜—Kšžœ˜—Kšœ˜—K˜š ‘œžœžœžœžœžœ ˜fKšœžœ˜0šœ˜˜Kšœ˜Kšœ˜K˜K˜—Kšžœ˜Kšœ˜—Kšœ˜—K˜š ‘œžœžœžœžœžœ ˜gKšœ;žœ˜QKšœ˜—K˜š ‘œžœžœ žœžœ ˜4Kšžœžœ"˜0Kšœ˜—K˜šŸ œ˜'šžœ žœžœžœ™6Kšž œžœžœ žœžœ žœžœ™OKš œ žœžœžœžœ™4—K˜š ‘ œžœžœžœ žœ˜:Kšœ3™3Kšœ™Kšžœžœžœ&˜3šžœžœžœž˜Kšœžœžœ˜#Kšœžœžœ˜&Kšžœ˜—Kšœ˜—K™Kšœ ™ Kšœžœ˜$Kšžœ žœ žœž˜.šžœ˜Kšœžœžœ ˜GKšœžœ{˜‚Kšœ žœžœ žœ˜9šžœžœ˜Kšœ˜Kšœ žœ˜Kšœ˜—K˜—Kšœ˜K˜—Kšžœ˜K˜—…—<#O