<> <> <> <> DIRECTORY CD; CDProperties: CEDAR DEFINITIONS = BEGIN <> <<>> <> <<>> <> <> <> <<>> <> <> <<>> <> <> <<>> <> <<>> <> <<>> <> <<>> <> <<>> <> <> <<>> <<>> <<>> <<--Types and registration>> PropList: TYPE = CD.PropList; PropRef: TYPE = CD.PropRef; --ABSOLUTELY NEVER NIL <<--Use only CDProperties to access ChipNDale PropList's; Never Properties directly.>> <<--Direct use of Properties can cause chaos in ChipNDale, which depends heavy>> <<--on concurrent processes accessing PropList's.>> InitPropRef: PROC [] RETURNS [PropRef] = INLINE { <<--Initialization value for a PropRef>> <<--An object MUST be NOT accessible for ChipNDale until all its PropRef's are initialized. >> RETURN [NEW[PropList_NIL]] }; RegisterProperty: PROC [prop: REF, registrationKey: REF_NIL] RETURNS [first: BOOLEAN]; <<--Registers "prop" for usage; any program which wants to use an ATOM as a "prop" can >> <<--make sure it is the only user of this "prop". >> <<--If registrationKey#NIL and registrationKey is equal to registrationKey of previous >> <<--registration, a property may be multiple registered. >> <<--Otherwise raise CD.Error[doubleRegistration] if prop was already registered.>> <<>> <<--Property names cannot be removed, since they may reside somewhere in the>> <<--stored data. >> <<>> <<--Usage>> PutProp: PROC [onto: REF, prop: REF, val: REF_NIL]; <<--Puts a prop val pair on a property list>> <<--a NIL val removes the property>> GetProp: PROC [from: REF, prop: REF] RETURNS [REF]; <<--Fetches a value from a property list; NIL if not found>> <<--Reorders list partially; next GetProp of the same prop may be faster>> GetPropFromList: PROC [propList: PropList, prop: REF] RETURNS [REF]; <<--Fetches a value from a property list; NIL if not found>> <<--Reorders list partially; next GetPropFromList of the same prop may be faster>> <<--PutProp and GetProp "understand" the following types: CD.Instance CD.Object CD.PropRef (CDProperties.PropRef) some more types which are only of secondary importance.>> <<--Speed ups and special cases >> PutPropOnInstance: PROC [onto: CD.Instance, prop: REF, val: REF_NIL]; <<--a NIL val removes the property>> PutPropOnDesign: PROC [onto: CD.Design, prop: REF, val: REF_NIL]; <<--a NIL val removes the property>> PutPropOnTechnology: PROC [onto: CD.Technology, prop: REF, val: REF_NIL]; <<--a NIL val removes the property>> PutPropOnAtom: PROC [onto: ATOM, prop: REF, val: REF_NIL]; <<--this property is NOT fetchable with Atom.GetProp>> <<--The onto Atom need not be registered anywhere, the registration of the>> <<--prop is enough to prevent conflicts.>> <<--a NIL val removes the property>> PutPropOnObject: PROC [onto: CD.Object, prop: REF, val: REF_NIL]; <<--a NIL val removes the property>> <<--warning: different objects may share bits, property owners loose!>> PutPropOnLayer: PROC [onto: CD.Layer, prop: REF, val: REF_NIL]; <<--a NIL val removes the property>> PutPropOnPropRef: PROC [onto: CD.PropRef, prop: REF, val: REF_NIL]; <<--a NIL val removes the property>> <<>> GetPropFromInstance: PROC [from: CD.Instance, prop: REF] RETURNS [REF] = INLINE { <<--NIL if prop is not found>> RETURN [GetPropFromList[from.properties, prop]] }; GetPropFromDesign: PROC [from: CD.Design, prop: REF] RETURNS [REF] = INLINE { <<--NIL if prop is not found>> RETURN [GetPropFromList[from.properties^, prop]] }; GetPropFromTechnology: PROC [from: CD.Technology, prop: REF] RETURNS [REF] = INLINE { <<--NIL if prop is not found >> RETURN [GetPropFromList[from.properties^, prop]] }; GetPropFromAtom: PROC [from: ATOM, prop: REF] RETURNS [REF]; <<--does NOT fetch properties put on an ATOM with Atom.PutProp>> <<--The from Atom need not be registered anywhere, the registration of the>> <<--prop is enough to prevent conflicts>> <<--NIL if prop is not found >> GetPropFromObject: PROC [from: CD.Object, prop: REF] RETURNS [REF] = INLINE { <<--NIL if prop is not found>> <<--warning: different objects may share bits, property owners loose!>> RETURN [GetPropFromList[from.properties, prop]] }; GetPropFromLayer: PROC [from: CD.Layer, prop: REF] RETURNS [REF]; <<--NIL if prop is not found>> GetPropFromPropRef: PROC [from: CD.PropRef, prop: REF] RETURNS [REF] = INLINE { <<--NIL if prop is not found>> RETURN [GetPropFromList[from^, prop]] }; <<>> <<--general property procedures>> InstallProcs: PROC [prop: REF, new: PropertyProcsRec _ [properties: NIL]]; <<--Installs procedures for a property registration>> <<--Overwrites values for which new has non NIL entries (except key).>> <<--prop must be registered and yours.>> <<--Exceptional rule: The actual parameter new.properties might have been >> <<-- created with Properties directly, if the caller can assert that >> <<-- they are not reordered for the time of this call to InstallProcs.>> <<>> FetchProcs: PROC [prop: REF] RETURNS [PropertyProcs]; <<--Fetches the procedures on the property registration>> <<--Never copy PropertyProcs^; it can be extended by future calls of InstallProcs >> RegisterAndInstall: PROC [prop: REF, new: PropertyProcsRec _ [properties: NIL], registrationKey: REF _ NIL] RETURNS [first: BOOLEAN]; <<--Short cut for conveniance>> <<--Registers property and, if this was the first registration then installs procedures.>> <<--Parameters and raised exceptions are the same as in RegisterProperty and InstallProcs>> PropertyProcs: TYPE = REF PropertyProcsRec; PropertyProcsRec: TYPE = RECORD [ makeCopy: MakeCopyProc _ NIL, internalWrite: InternalPWriteProc _ NIL, internalRead: InternalPReadProc _ NIL, exclusive: BOOL _ FALSE, --the implementation requests others not too fool with key: REF _ NIL, --the prop field of registration properties: PropList _ NIL ]; MakeCopyProc: TYPE = PROC [prop: REF, val: REF, purpose: REF_NIL] RETURNS [valCopy: REF]; <<--valCopy: may be NIL if property should not be copied>> <<--purpose:>> <<-- copy procs will not recognize most purposes...>> <<-- but a particular property might want a particular handling from some tool>> InternalPWriteProc: TYPE = PROC [prop: REF, val: REF]; InternalPReadProc: TYPE = PROC [prop: ATOM] RETURNS [val: REF]; <<--The procedure types of PropertyProcs will be called within CDProperties monitor lock.>> <<--They must not call any other procedure from CDProperties (wedges!!); But they may>> <<--call Properties directly.>> CopyProps: PROC [propList: PropList, putOnto: REF, purpose: REF_NIL]; <<--Copies properties individually using their MakeCopyProc's and defaults for some types >> <<--The resulting propList is put on putOnto >> AppendProps: PROC [winner, looser: PropList_NIL, putOnto: REF, purpose: REF_NIL]; <<--Copies properties individually using their MakeCopyProc's and defaults for some types. >> <<--Works like first copying looser, then copying winner. >> <<--copy is a different list from both, looser and winner>> <<--The resulting propList copy is put on putOnto >> <<>> DangerousCopyProps: PROC [propList: PropList, purpose: REF_NIL] RETURNS [copy: PropList]; <<--Like CopyProps, but returns PropList;>> <<--Consider: if you assign the copy to somewhere, the previous PropList might have been >> <<--changed after making the copy and before the assignment is finished. >> DangerousAppendProps: PROC [winner, looser: PropList_NIL, purpose: REF_NIL] RETURNS [copy: PropList]; <<--Like AppendProps, but returns PropList;>> <<--Consider: if you assign the copy to somewhere, the previous PropList might have been >> <<--changed after making the copy and before the assignment is finished. >> <<>> DoWithinLock: PRIVATE PROC [p: PROC]; <<--Executes arbitrary code within CDProperties monitor lock. Dangerous.>> <<--Must not call any other procedure from CDProperties (wedges!!)>> <<--May call Properties directly>> <<>> <<>> <<--particular property procedures for implementors>> DontCopy: PROC [prop: REF, val: REF, purpose: REF_NIL] RETURNS [nil: REF]; <<--to be shure that no copy is made; trivial procedure>> CopyVal: PROC [prop: REF, val: REF, purpose: REF_NIL] RETURNS [valCopy: REF]; <<--copy of val; trivial procedure; is for some types a default anyway>> <<>> RopePWrite: PROC [prop: REF, val: REF]; RopePRead: PROC [prop: ATOM] RETURNS [val: REF]; IntPWrite: PROC [prop: REF, val: REF]; IntPRead: PROC [prop: ATOM] RETURNS [val: REF]; AtomPWrite: PROC [prop: REF, val: REF]; AtomPRead: PROC [prop: ATOM] RETURNS [val: REF]; SomePWrite: PROC [prop: REF, val: REF]; SomePRead: PROC [prop: ATOM] RETURNS [val: REF]; END. <> <> <> <> <<>> <> <<>>