DIRECTORY CD, CDBasics, CDDirectory, CDDirectoryOps, CDDynamicObs, CDEvents, CDGenerate, CDGenerateBackdoor, CDImports, CDInstances, CDIO, CDOps, CDRects, CDValue, RefTab, Rope, RuntimeError USING [UNCAUGHT], SymTab, TerminalIO, TokenIO; CDDynamicObsImpl: CEDAR MONITOR IMPORTS CD, CDBasics, CDDirectory, CDDirectoryOps, CDGenerate, CDGenerateBackdoor, CDImports, CDInstances, CDIO, CDOps, CDRects, RefTab, Rope, RuntimeError, SymTab, TerminalIO, TokenIO EXPORTS CDDynamicObs SHARES CDDirectory = BEGIN DynamicPtr: TYPE = REF DynamicRep; DynamicRep: TYPE = RECORD [ pseudoInst: CD.Instance _ NIL, ir: CD.Rect _ [0, 0, -1, -1], used: RefTab.Ref _ NIL, project: Rope.ROPE _ NIL, passContext: CDGenerate.Context_NIL, genContext: CDGenerate.Context_NIL, generatorKey: Rope.ROPE _ NIL ]; key: ATOM = $CDDynamicObs; class: CD.ObjectClass = CD.RegisterObjectClass[key, [ interestRect: InterestRect, drawMe: DrawMe, quickDrawMe: QuickDrawMe, internalRead: ReadMe, describe: Describe ]]; EnumerateItsObjects: PROC [me: CD.Object, p: CDDirectory.EnumerateObjectsProc, x: REF] = { pp: DynamicPtr = NARROW[me.specific]; IF pp.pseudoInst#NIL THEN p[pp.pseudoInst.ob, x]; }; IncludeChild: PROC [me: CD.Object, x: REF] = { IF me.class.inDirectory THEN {--otherwise it will not change used: RefTab.Ref = NARROW[x]; newChild: BOOL _ RefTab.Insert[used, me, me]; IF newChild AND ~ISTYPE[me.specific, DynamicPtr] --it will propagate changes of it's children AND ~CDImports.IsImport[me] THEN --it will not change... CDDirectory.EnumerateChildObjects[me, IncludeChild, x] } }; BuildChildrenList: PROC [me: CD.Object] = { pp: DynamicPtr = NARROW[me.specific]; pp.used _ NIL; IF pp.pseudoInst#NIL THEN { pp.used _ RefTab.Create[]; IncludeChild[pp.pseudoInst.ob, pp.used]; }; }; ReplaceDirectChilds: CDDirectory.ReplaceDChildsProc = { pp: DynamicPtr = NARROW[me.specific]; IF pp.pseudoInst#NIL THEN { FOR rl: CDDirectory.ReplaceList _ replace, rl.rest WHILE rl#NIL DO IF pp.pseudoInst.ob=rl.first.old OR (pp.used#NIL AND RefTab.Fetch[pp.used, rl.first.old].found) THEN { [] _ BuildUp[me, design]; RETURN } ENDLOOP }; }; Create: PUBLIC PROC [design: CD.Design, project, key: Rope.ROPE] RETURNS [ob: CD.Object] = { context: CDGenerate.Context _ MakeAnIndirector[project].useContext; ob _ CDGenerate.FetchNCall[context, design, key]; }; InternalCreate: PROC [design: CD.Design, r: CD.Rect _ [0, 0, 1, 1], project: Rope.ROPE _ NIL, generatorKey: Rope.ROPE _ NIL, catch: BOOL_TRUE, include: BOOL_TRUE] RETURNS [CD.Object] = { ob: CD.Object; pp: DynamicPtr; r.x2 _ MAX[r.x2, r.x1+1]; r.y2 _ MAX[r.y2, r.y1+1]; pp _ NEW[DynamicRep _ [ project: project, generatorKey: generatorKey, ir: r ]]; ob _ NEW[CD.ObjectRep _ [ bbox: r, class: class, layer: CD.undefLayer, specific: pp ]]; IF include THEN [] _ CDDirectory.Include[design: design, object: ob]; [] _ BuildUp[ob, design]; -- no repositioning needs be done RETURN [ob] }; Describe: PROC[me: CD.Object] RETURNS [Rope.ROPE] = { pp: DynamicPtr = NARROW[me.specific]; RETURN [Rope.Cat["generated object [", Rope.Cat[pp.project, ".", pp.generatorKey], "] ", CDDirectory.Name[me]]] }; DrawMe: PROC [inst: CD.Instance, trans: CD.Transformation, pr: CD.DrawRef] = { pp: DynamicPtr = NARROW[inst.ob.specific]; IF pp.pseudoInst#NIL THEN pr.drawChild[pp.pseudoInst, trans, pr] ELSE { r: CD.Rect = CDBasics.MapRect[CD.InterestRect[inst.ob], trans]; pr.drawRect[r, CD.shadeLayer, pr]; pr.drawComment[r, CDDirectory.Name[inst.ob], pr] } }; QuickDrawMe: PROC [inst: CD.Instance, trans: CD.Transformation, pr: CD.DrawRef] = { pp: DynamicPtr = NARROW[inst.ob.specific]; IF pp.pseudoInst#NIL THEN pp.pseudoInst.ob.class.quickDrawMe[pp.pseudoInst, trans, pr] ELSE { r: CD.Rect = CDBasics.MapRect[CD.InterestRect[inst.ob], trans]; pr.drawRect[r, CD.shadeLayer, pr]; pr.drawComment[r, CDDirectory.Name[inst.ob], pr] } }; WriteMe: CD.InternalWriteProc = { pp: DynamicPtr = NARROW[ob.specific]; CDIO.WriteRect[h, ob.bbox]; TokenIO.WriteRope[h, pp.project]; TokenIO.WriteRope[h, pp.generatorKey]; }; ReadMe: CD.InternalReadProc = { ob: CD.Object; r: CD.Rect; generatorKey, project: Rope.ROPE; context: CDGenerate.Context; r _ CDIO.ReadRect[h]; project _ TokenIO.ReadRope[h]; generatorKey _ TokenIO.ReadRope[h]; context _ MakeAnIndirector[project].useContext; ob _ CDGenerate.FetchNCall[context, CDIO.DesignInReadOperation[h], generatorKey]; IF ob#NIL AND ob.bbox=r THEN { [] _ CDDirectory.Remove[CDIO.DesignInReadOperation[h], CDDirectory.Name[ob], ob]; RETURN [ob]; }; TerminalIO.PutRope["**generated object not created\n"]; ob _ CDRects.CreateRect[CDBasics.SizeOfRect[r], CD.errorLayer]; RETURN [ob] }; Expand: PROC [me: CD.Object, fromOrNil: CD.Design_NIL, into: CD.Design_NIL, friendly: BOOL_FALSE] RETURNS [ new: CD.Object_NIL, topMode: CDDirectory.DMode_ready, childMode: CDDirectory.ImmOrIncl_immutable ] = { pp: DynamicPtr = NARROW[me.specific]; IF pp.pseudoInst#NIL THEN [new, topMode, childMode] _ CDDirectory.Another[pp.pseudoInst.ob, fromOrNil, into] }; Another: PROC [me: CD.Object, fromOrNil: CD.Design_NIL, into: CD.Design_NIL, friendly: BOOL_FALSE] RETURNS [ new: CD.Object_NIL, topMode: CDDirectory.InclOrReady_ready, childMode: CDDirectory.ImmOrIncl_included ] = { pp: DynamicPtr = NARROW[me.specific]; new _ InternalCreate[design: into, r: me.bbox, generatorKey: pp.generatorKey, project: pp.project, catch: TRUE, include: FALSE ]; }; myContexts: RefTab.Ref _ RefTab.Create[]; Finder: TYPE = RECORD[realProject, autoProject: Rope.ROPE, useContext: CDGenerate.Context]; GetContext: PUBLIC PROC [for: Rope.ROPE] RETURNS [name: Rope.ROPE, context: CDGenerate.Context] = { [useContext: context, autoProject: name] _ MakeAnIndirector[for]; }; MakeAnIndirector: PROC [to: Rope.ROPE] RETURNS [useContext, normalContext: CDGenerate.Context, autoProject: Rope.ROPE] = { normalContext _ CDGenerate.AssertContext[to]; WITH myContexts.Fetch[normalContext].val SELECT FROM find: REF Finder => { useContext _ find.useContext; autoProject _ find.autoProject; } ENDCASE => { f: REF Finder = NEW[Finder _ [realProject: to, useContext: NIL]]; f.useContext _ useContext _ CDGenerateBackdoor.CreateIndirect[ onTopOf: normalContext, iGenerator: CrazoIndirector, selector: CDGenerate.SelectOneOf, cache: TRUE ]; autoProject _ f.autoProject _ Rope.Cat["%AUTO-", to]; [] _ myContexts.Insert[normalContext, f]; --the real entry to use is the normalcontext [] _ myContexts.Insert[useContext, f]; --prevents creation of (direct) recursion [useContext, normalContext, autoProject] _ MakeAnIndirector[to]; [] _ SymTab.Insert[CDGenerateBackdoor.publicContexts, f.autoProject, useContext]; }; }; CrazoIndirector: CDGenerateBackdoor.IGeneratorProc = { onTopOf: CDGenerate.Context _ CDGenerateBackdoor.Indiretee[realContext]; finder: REF Finder _ NARROW[myContexts.Fetch[onTopOf].val]; project: Rope.ROPE _ finder.realProject; ob _ InternalCreate[design: design, generatorKey: key, project: project]; }; BuildUp: PROC[ob: CD.Object, design: CD.Design_NIL] RETURNS [done: BOOL_FALSE] = { ok: BOOL_TRUE; refOb: CD.Object; pp: DynamicPtr = NARROW[ob.specific]; IF pp.passContext=NIL OR pp.genContext=NIL THEN { [useContext: pp.passContext, normalContext: pp.genContext] _ MakeAnIndirector[pp.project]; }; refOb _ CDGenerateBackdoor.FetchIndirect[passContext: pp.passContext, realContext: pp.genContext, design: design, key: pp.generatorKey, cache: FALSE ! RuntimeError.UNCAUGHT => {ok _ FALSE; CONTINUE}]; IF ok AND refOb#NIL THEN { oldRef: CD.Object_NIL; newInst: CD.Instance _ CDInstances.NewInst[refOb]; oldR: CD.Rect _ ob.bbox; oldIr: CD.Rect = CD.InterestRect[ob]; newIr: CD.Rect = CD.InterestRect[refOb]; IF pp.pseudoInst#NIL THEN oldRef _ pp.pseudoInst.ob; pp.pseudoInst _ newInst; BuildChildrenList[ob]; ob.bbox _ refOb.bbox; pp.ir _ newIr; IF design#NIL THEN { IF ob.bbox#oldR OR oldIr#newIr THEN { CDDirectory.PropagateResize[design, ob]; IF oldRef#NIL AND oldRef.class.inDirectory THEN [] _ CDDirectoryOps.RemoveIfUnused[design, oldRef] }; CDOps.Redraw[design] }; } }; InterestRect: PROC [ob: CD.Object] RETURNS [CD.Rect] = { RETURN [NARROW[ob.specific, DynamicPtr].ir] }; Init: PROC [] = { pp: REF CDDirectory.DirectoryProcs = CDDirectory.InstallDirectoryProcs[class, [ enumerateChildObjects: EnumerateItsObjects, replaceDirectChilds: ReplaceDirectChilds, another: Another, expand: Expand ]]; }; Init[]; END. ^CDDynamicObsImpl.mesa (part of ChipNDale) Copyright c 1984, 1985 by Xerox Copporation. All rights reserved. Created by Christian Jacobi, November 9, 1984 2:30:07 pm PST Last edited by: Christian Jacobi, October 20, 1986 12:55:01 pm PDT --dont write.... internalWrite: WriteMe, --me: child to be included --x: RefTab.Ref --we can't do it but we recompute if old appears --hack: read routine is supposed to return object not already in design and re-include it... --deals with concurency problems PROC [design: CD.Design, key: Rope.ROPE, context: Context, data: REF] RETURNS [ob: CD.Object_NIL] Κ ˜codešœ+™+Kšœ Οmœ7™BKšœ>™>K™BK˜—šΟk ˜ Kšžœ˜Kšœ ˜ Kšœ ˜ Kšœ˜Kšœ ˜ Kšœ ˜ Kšœ ˜ Kšœ˜Kšœ ˜ K˜ Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ žœžœ˜Kšœ˜Kšœ ˜ Kšœ˜—K˜šΟnœžœžœ˜#KšžœžœažœJ˜ΉKšžœ˜Kšžœ˜—Kšž˜K˜Kšœ žœžœ ˜"šœ žœžœ˜Kšœ žœ žœ˜ Kšœžœ˜Kšœžœ˜Kšœžœžœ˜Kšœ žœ˜$Kšœžœ˜#Kšœžœž˜Kšœ˜—K˜Kšœžœ˜šœžœžœ˜5Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ)™)Kšœ˜Kšœ˜—K˜šŸœžœžœ1žœ˜ZKšœžœ˜%Kšžœžœžœ˜1Kšœ˜—˜šŸ œžœžœ žœ˜.Kšœ™Kšœ™šžœžœΟc˜˜>Kšœ˜Kšœ˜Kšœ!˜!Kšœž˜ Kšœ˜—Kšœ5˜5Kšœ* -˜WKšœ' *˜QKšœ ™ Kšœ@˜@KšœQ˜QK˜——Kšœ˜—K˜š‘œ'˜6Kšžœ žœžœžœžœžœžœ™aKšœH˜HKšœžœ žœ ˜;Kšœžœ˜(KšœI˜IKšœ˜—K˜šŸœžœžœžœžœžœžœžœ˜RKšœžœžœ˜Kšœžœ˜Kšœžœ˜%šžœžœžœ ž œ˜1KšœZ˜ZK˜—Kš œžœžœ žœžœ˜Θšžœžœžœžœ˜Kšœžœžœ˜Kšœ žœ'˜2Kšœžœ˜Kšœžœžœ˜%Kšœžœžœ˜(Kšžœžœžœ˜4Kšœ˜Kšœ˜Kšœ˜Kšœ˜šžœžœžœ˜šžœžœ žœ˜%Kšœ(˜(šžœžœžœžœ˜0Kšœ3˜3—K˜—Kšœ˜K˜—Kšœ˜—Kšœ˜—K˜š Ÿ œžœžœ žœžœ ˜8Kšžœžœ˜+Kšœ˜K˜—šŸœžœ˜šœžœH˜OKšœ+˜+Kšœ)˜)Kšœ˜Kšœ˜Kšœ˜—Kšœ˜—K˜K˜Kšžœ˜K˜—…— ͺ.%