DIRECTORY RefTab USING [Ref], Rope USING [ROPE], CD USING [Design, Object, ObjectClass, PropList, Transformation]; CDDirectory: CEDAR DEFINITIONS = BEGIN Fetch: PROC [design: CD.Design, name: Rope.ROPE] RETURNS [object: CD.Object]; IsIncluded: PROC [design: CD.Design, object: CD.Object] RETURNS [BOOL]; Include: PROC [design: CD.Design, object: CD.Object, name: Rope.ROPE, fiddle: BOOL_TRUE] RETURNS [done: BOOL]; Remove: PROC [design: CD.Design, name: Rope.ROPE, expectObject: CD.Object_NIL] RETURNS [ob: CD.Object]; Fiddle: PROC [design: CD.Design, name: Rope.ROPE] RETURNS [ob: CD.Object]; Rename: PROC [design: CD.Design, object: CD.Object, newName: Rope.ROPE, fiddle: BOOL _ TRUE, fiddleFirst: BOOL _ FALSE, removeFirst: BOOL _ FALSE] RETURNS [done: BOOL, conflict: CD.Object]; Enumerate: PROC [design: CD.Design, action: EachEntryAction] RETURNS [quit: BOOL]; EachEntryAction: TYPE = PROC [name: Rope.ROPE, ob: CD.Object] RETURNS [quit: BOOL_FALSE]; DirSize: PROC [design: CD.Design] RETURNS [INT]; Name: PROC [object: CD.Object, design: CD.Design] RETURNS [Rope.ROPE]; IsOwner: PRIVATE PROC [design: CD.Design, object: CD.Object] RETURNS [BOOL]; CompatibleOwner: PRIVATE PROC [design: CD.Design, object: CD.Object] RETURNS [BOOL]; SetOwner: PRIVATE PROC [design: CD.Design, object: CD.Object, check: BOOL_TRUE]; EnumerateChildObjects: PROC [me: CD.Object, proc: EachObjectProc, data: REF_NIL] RETURNS [quit: BOOL_FALSE] = INLINE { IF me.class.composed THEN quit _ ObToDirectoryProcs[me].enumerateChildObjects[me, proc, data] }; EnumerateDesign: PROC [design: CD.Design, proc: EachObjectProc, data: REF_NIL, dir: BOOL_TRUE, top: BOOL_TRUE, recurse: BOOL_TRUE, dummy: BOOL_FALSE, visited: RefTab.Ref_NIL] RETURNS [quit: BOOL_FALSE]; EnumerateObject: PROC [ob: CD.Object, proc: EachObjectProc, data: REF_NIL, recurse: BOOL_TRUE, visited: RefTab.Ref_NIL] RETURNS [quit: BOOL_FALSE]; Another1: PROC [me: CD.Object, fromOrNil: CD.Design_NIL, into: CD.Design_NIL, friendly: BOOL_FALSE] RETURNS [new: CD.Object, childAccessible: BOOL]; Expand1: PROC [me: CD.Object, fromOrNil: CD.Design_NIL, into: CD.Design_NIL, friendly: BOOL_FALSE] RETURNS [new: CD.Object, topAccessible: BOOL, childAccessible: BOOL]; Expand1ByDraw: PROC [ob: CD.Object, ep: ExpandDecisionProc_NIL, data: REF_NIL] RETURNS [new: CD.Object]; ExpandDecision: TYPE = {suppress, leave, recurse} _ leave; ExpandDecisionProc: TYPE = PROC [ob: CD.Object, trans: CD.Transformation, readOnlyInstProps: CD.PropList, data: REF] RETURNS [decides: ExpandDecision _ leave]; LeaveNextLevel: ExpandDecisionProc; LeaveRectangles: ExpandDecisionProc; LeaveDontFlatten: ExpandDecisionProc; FixChildren: PROC [me: CD.Object, into: CD.Design, fromOrNil: CD.Design_NIL, cx: RefTab.Ref_NIL] RETURNS [ok: BOOL]; AnotherRecursed: PROC [me: CD.Object, into: CD.Design_NIL, fromOrNil: CD.Design_NIL, cx: RefTab.Ref_NIL] RETURNS [new: CD.Object]; ExpandRecursed: PROC [me: CD.Object, into: CD.Design_NIL, fromOrNil: CD.Design_NIL, cx: RefTab.Ref_NIL] RETURNS [new: CD.Object]; DirectoryProcs: TYPE = PRIVATE RECORD [ enumerateChildObjects: EnumerateChildObjectsProc _ NIL, replaceDirectChilds: ReplaceDChildsProc _ NIL, another: AnotherProc _ NIL, expand: ExpandProc _ NIL, directoryOp: DirectoryProc _ NIL ]; ObToDirectoryProcs: PROC [ob: CD.Object] RETURNS [REF DirectoryProcs] = INLINE { RETURN [NARROW[ob.class.directoryProcs, REF DirectoryProcs]] }; InstallDirectoryProcs: PRIVATE PROC [type: CD.ObjectClass, dp: DirectoryProcs] RETURNS [REF DirectoryProcs]; EnumerateChildObjectsProc: TYPE = PROC [me: CD.Object, proc: EachObjectProc, data: REF] RETURNS [quit: BOOL_FALSE]; EachObjectProc: TYPE = PROC [me: CD.Object, data: REF_NIL] RETURNS [quit: BOOL_FALSE]; DirectoryFunction: TYPE = {include, remove, rename}; DirectoryProc: TYPE = PROC [me: CD.Object, design: CD.Design, name: Rope.ROPE, function: DirectoryFunction]; ReplaceList: TYPE = LIST OF REF ReplaceRec; ReplaceRec: TYPE = RECORD [ old: CD.Object, new: CD.Object, trans: CD.Transformation_[[0, 0], original] ]; ReplaceDChildsProc: TYPE = PROC [me: CD.Object, design: CD.Design, replace: ReplaceList] RETURNS [changed: BOOL_FALSE]; ExpandProc: TYPE = PROC[me: CD.Object, fromOrNil: CD.Design_NIL, into: CD.Design_NIL, friendly: BOOL_FALSE] RETURNS [new: CD.Object_NIL, topAccessible: BOOL_FALSE, childAccessible: BOOL_FALSE]; AnotherProc: TYPE = PROC[me: CD.Object, fromOrNil: CD.Design_NIL, into: CD.Design_NIL, friendly: BOOL_FALSE] RETURNS [new: CD.Object_NIL, childAccessible: BOOL_FALSE]; PropagateResize: PROC [design: CD.Design, ob: CD.Object]; ReplaceObject: PROC [design: CD.Design, old: CD.Object, new: CD.Object, trans: CD.Transformation_[[0, 0], original]]; ReplaceDirectChild: PROC [me: CD.Object, design: CD.Design, replace: ReplaceList, propagate: BOOL_TRUE] RETURNS [changed: BOOL_FALSE]; PropagateChange: PROC [ob: CD.Object, design: CD.Design]; END. *>CDDirectory.mesa (a ChipNDale module) Copyright c 1983, 1987 by Xerox Corporation. All rights reserved. Created by Christian Jacobi, 23-Aug-83 Last edited by: Christian Jacobi, February 24, 1987 11:25:07 am PST More class procedures for classes of composed objects. These functions are necessary for enumeration and resizeing of objects. Calls handling the same design must be serialized by client (CDSequencer). Directory: designs have a directory of named objects. All objects in the directory of a design are accessible. An object must not be included in a designs directory more than once. NIL is not used as name of an object. Mutable objects must not be accessible from different designs. Accessible children of accessible objects are accessible too. Only accessible children might be mutable. This invariant can NOT completely be checked by ChipNDale; it has to trust its clients. => Objects which have mutable descendants are mutable! -- Basic directory procedures -- Returns named object in directory or NIL if not found -- Checks whether object is included into directory. -- Includes object into directory of design. (Does not make an instance). -- fiddle: on conflicts try to fiddle name of object -- done: object included in directory by this call -- Even if it fiddles the name, the first character of the name is not changed. -- This makes object accessible. -- Removes name from directory of design by removing object. -- If expectObject#NIL: removes or fiddles object only if named object really is expectObject. -- Object may or may not remain accessible. -- Returns removed object or NIL if no object removed. -- Removes name from directory of design by fiddling name of object -- Returns fiddled object or NIL if no object fiddled. -- Renames object in the directory of design. -- fiddle: on conflicts try to fiddle newName -- fiddleFirst: on conflicts try first to rename conflicting object [only if fiddle=FALSE] -- removeFirst: on conflicts try first to remove conflicting object [only if fiddle=FALSE] -- done: object renamed. -- conflict: conflicting, removed or fiddled object. -- Enumerates objects currently in directory in unspecified order. -- Objects Included/Removed/Renamed during enumeration may, may not, or may -- twice be seen. -- Applies action to each object until action returns TRUE or no more objects. -- Returns quit: TRUE if some action returns TRUE -- Returns number of objects in the directory -- Returns name of object. -- NIL for objects not in directory of design. --Ownership procedures; not for clients -- Checks whether object is included in design. -- Client programs must not rely on this procedure; except for self checks. -- Checks whether object is included in different design. -- Not to be called by clients, because ChipNDale's internal invariants may change. -- Sets flag for IsOwner checks. -- Not to be called by clients, because ChipNDale's internal invariants may change. --Class procedures --Dealing with hierarchy --Enumerates accessible direct children. -- Unspecified order; -- Object may be enumerated more than ones. -- May or may not enumerate objects of non composed classes. -- [This is how the class declares accessibility to ChipNDale] -- Enumerates accessible composed objects in unspecified order; except if recurse, then -- topologically sorted. Objects of non composed classes may, may not, or may -- partly be enumerated. -- Applies proc to each non composed object until proc returns TRUE or no more objects. -- Returns quit: TRUE if some proc returns TRUE. -- Objects Included/Removed/Renamed during enumeration (and their children!) -- may, may not, or may twice be seen. -- data: user data handled to proc. -- dir: enumerates the directory. -- top: enumerates the top level objects. -- recurse: enumerates children (transitive) of enumerated objects. -- dummy: enumerates dummy cells, active only if top=TRUE. -- visited: read-write cache of already visited object. Normally use NIL! -- Enumerates accessible composed children in unspecified order; except if recurse, then -- topologically sorted. Objects of non composed classes may, may not, or may -- partly be enumerated. -- Applies proc to each non composed object until proc returns TRUE or no more objects. -- Returns quit: TRUE if some proc returns TRUE. -- data: user data handled to proc. -- recurse: enumerates children (transitive) of enumerated objects. -- visited: read-write cache of already visited object. Normally use NIL! -- Building block to copy an object into an other design. Does not fail if into#NIL. -- CAUTION: may go only one Layer deep; -- see explanations for "AnotherProc" and "childAccessible". -- Caller must do fixups on result and children objects according to accesssibility if -- the returned object is made available to any other client. -- Get object of simpler structure. -- Returned object is of expand-simpler object class (half ordered); but -- it will generate exactly the same mask. NIL on failure. -- CAUTION: see explanations for "ExpandProc" "topAccessible" and "childAccessible". -- Caller must do fixups on result and children objects according to accesssibility if -- the returned object is made available to any other client. -- bbox must not change; only unfriendly classes change interestrect. -- Expands an object by using its draw procedures. -- Returns cell with "childAccessible" = ~ob.class.xDesign for all recursed objects -- and "topAccessible" = TRUE. -- Caller must do fixups on result and children objects according to accesssibility if -- returned object is made available to any other client. -- ep: is a decision procedure whether children should be expanded -- data: is passed to ep -- Decision procedure to expand objects of composed classes just one level down. -- Decision procedure to expand object all the way down to bare rectangles; -- Removes symbolic objects. -- Decision procedure to expand objects of composed classes: all objects of composed -- classes not having a non NIL $DontFlatten property will be expanded. -- Warning: may expand accros designs with objects of xDesign classes. -- Replace un-accessible children by objects in the into design, complete down the hierarchy. -- Does not propagate the change. -- E.g. to use after an expand. -- Optional: cx: state of handled subobjects; use new cx for each [into, fromOrNil] pair ! -- Might or might not use cx for me itself. -- Another1, and fix children recursively -- Tries hard, but might fail -- Optional: cx: state of handled subobjects; use new cx for each [into, fromOrNil] pair ! -- Might or might not use cx for me itself. -- Expand1, and fix children recursively -- Tries hard, but might fail -- Optional: cx: state of handled subobjects; use new cx for each [into, fromOrNil] pair ! -- Might or might not use cx for me itself. -- Implementation of compound objects -- Enumerates all accessible [composed] direct children [at least once], but NOT any -- in-accessible children. -- Default: uses class.xDesign and the DrawProc; slow -- [a faster client implementation is essential for the overall speed; enumeration -- is a frequent operation] -- Replace children and recompute bbox -- Default: Don't default this. Only a fraction of the funcionality is necessary, but -- that is essential for inter design copy and pruning to work correctly. -- copy; inter design copy -- Default: make a copy of the ObjectRep and shares the specific -- Recast... -- Default: expand using ExpandByDraw -- Notification of directory operations; -- Not to be called directly by clients. -- Installs the class procedures and set type.composed -- Objects which are composed must not directly cause drawing in a context -- -- Think twice before implementing object classes outside the ChipNDale implementation. -- In general this is not a good idea and will introduce long living data and maintenance -- problems. -- Enumerates at least immediate descendants of composed classes -- At least once, but eventualy duplications; -- Class procedure to get notified of directory actions -- The object class gets notified of actions, but it can not rely on -- getting the include notification only once. --Resizing and exchanging sub objects -- Class procedure for request to exchange direct children and recomputation of bbox. -- Must fail to actually replace children if me is immutable -- May fail to actually replace children with the listed new objects [may compute -- other new children], but must remove old children and must recompute bbox -- when children match [with old object in ReplaceList] -- [An explicite editing operation might fail, but the parts used for making inter - -- design copy of objects, or a recomputation of the bbox, are not allowed to fail -- on mutable objects] -- Returns changed: whether me is changed. -- [Class should not call PropagateChange directly, but may resize] --Expansion and copy -- Class procedure to simplify the structure -- friendly: tries to come up with childAccessible=TRUE (even if more expensive) -- fromOrNil not mandatory, but might speed up some implementations -- topAccessible, childAccessible see below -- Class procedure to make a copy of an object -- copy does not need to be unique -- (it could even be me if into allows [then topMode is included]) -- friendly: tries to come up with childAccessible=TRUE (even if more expensive) -- fromOrNil not mandatory, but might speed up some implementations -- childAccessible see below; top is always accessible. -- topAccessible, childAccessible -- An object with either top or children not accessible must NOT be changed nor included -- into any design or directory by any program. -- To fix an un-accessible top, use Another -- To fix un-accessible children, use Another [recursively], or use FixChildren. --Changes -- All over in the design tries to re-size objects containing ob. -- Delayed if called recursively or through ReplaceObject. -- Also notifies Event $resize; x of type ReplaceRec -- Replace old by new in all instances of the design and its objects. -- Does not change the directory. -- Does not change sub objects of immutable objects. -- Might also fail for children of objects in some funny object classes. -- Delayed if called recursively or through PropagateResize. -- Checks me and its direct children; performs operations as required in replace. -- May fail if me is immutable or its children are not accessible. -- changed: whether me did replace a child. -- propagate: If propagate, calls PropagateChange if me did replace a child. -- Necessary resizing is done independent of propagate. -- Process an CDEvent $AfterChange Κ Θ˜codešœ'™'Kšœ Οmœ7™BKšœ&™&K™CK™—šΟk ˜ Kšœžœ˜Kšœžœžœ˜Kšžœžœ9˜A—K˜KšΟn œžœž œ˜!Kšž˜K˜šœ6™6KšœI™IKšœJ™JK™—šœ7™7K™8K™EK™%K™—šœ>™>K™=K™*K™W—˜Kšœ8™8—K™K™KšΠbc™K˜š Ÿœžœ žœžœžœ žœ ˜MKšœ8™8K™—š Ÿ œžœ žœžœ žœžœ˜GK™4—K˜šŸœžœ žœžœžœ žœžœžœžœ˜nKšΟcJ™JKš‘4™4Kš‘2™2Kš‘O™OKš‘ ™ K™—šŸœžœ žœžœžœžœžœžœ ˜gKš‘<™Kšœ@™@šžœžœ˜KšœC˜C—K˜K˜—K˜š"Ÿœžœ žœ%žœžœžœžœžœžœ žœžœ žœžœžœžœžœžœ˜ΚKš‘X™XKšœ‘M™OKš‘™Kš‘W™WKš‘0™0Kš‘M™MKš‘&™&Kš‘#™#Kš‘!™!Kš‘)™)Kš‘C™CKš‘:™:Kš‘œ‘@™JK™—šŸœžœžœ%žœžœ žœžœžœžœžœžœ˜“Kš‘Y™YKšœ‘L™TKš‘œ‘™Kš‘W™WKš‘0™0Kš‘#™#Kš‘C™CKš‘œ‘@™JK™—šŸœžœžœžœžœžœžœ žœžœžœžœžœ˜”KšœT™TKšœ’œ™(KšœA™AKšœ ’œH™VK™BK˜—šŸœžœžœžœžœžœžœ žœžœžœžœžœžœ˜¨K™$K™IK™@Kšœ’œJ™TKšœ ’œH™VK™BKšœE™EK˜K˜—šŸ œžœžœ žœžœžœžœžœ ˜hKšœ2™2KšœS™SKšœ#™#Kšœ ’œH™VKšœ>™>KšœB™BKšœ™K™Kšœžœ&˜:K˜Kšœžœžœžœžœ$žœžœžœ#˜ŸK˜šŸœ˜#KšœP™P—šŸœ˜$KšœK™KKšœ™—šŸœ˜%Kš‘ œ7™WKšœG™GKšœF™F—K™K™—šŸ œžœžœžœžœžœžœžœžœ˜tKš‘]™]K™!K™Kšœ\™\Kšœ-™-—K˜šŸœžœžœžœžœ žœžœžœžœžœ ˜‚Kš‘*™*K™Kšœ\™\Kšœ-™-—K˜šŸœžœžœžœžœ žœžœžœžœžœ ˜Kšœ‘ œ™)K™Kšœ\™\Kšœ-™-—K˜K™K™š’%™%K™K™—šœžœžœžœ˜'šœ3žœ˜8KšœT™TKšœ™Kšœ5™5KšœW™WKšœ ™ —šœ*žœ˜/Kšœ&™&KšœW™WKšœM™M—šœžœ˜Kšœ™Kšœ@™@—šœžœ˜Kšœ ™ Kš‘œ‘™%—šœžœ˜!Kš‘)™)Kš‘(™(—K˜K˜—š Ÿœžœžœ žœžœžœ˜PKšžœžœžœ˜