DIRECTORY CDProperties, CD, CDPrivate, Atom, RefTab, Rope, TokenIO; CDPropertiesImpl: CEDAR MONITOR IMPORTS CD, CDPrivate, CDProperties, Atom, RefTab, TokenIO EXPORTS CDProperties = BEGIN Properties: TYPE = CD.Properties; PropertyProcs: TYPE = CDProperties.PropertyProcs; PropertyProcsRec: TYPE = CDProperties.PropertyProcsRec; atomTab: RefTab.Ref = RefTab.Create[]; -- contains atoms [maybe in future ref's] where properties hang propertyNameTab: RefTab.Ref = RefTab.Create[]; -- key: propertynames; value: PropertyProcs registrationTab: RefTab.Ref = RefTab.Create[]; -- contains registrationKeys RegisterProperty: PUBLIC ENTRY PROC [prop: REF, registrationKey: REF_NIL] RETURNS [first: BOOLEAN_TRUE] = BEGIN val: RefTab.Val; found: BOOL; [found, val] _ RefTab.Fetch[x: registrationTab, key: prop]; -- returns a registration key IF found THEN { IF registrationKey#NIL AND registrationKey=val THEN RETURN [FALSE]; RETURN WITH ERROR CD.Error[doubleRegistration] } ELSE { pp: PropertyProcs _ NEW[PropertyProcsRec]; [] _ RefTab.Insert[propertyNameTab, prop, pp]; -- procs [] _ RefTab.Insert[registrationTab, prop, registrationKey]; -- registration }; END; HasNoCDProperties: ERROR = CODE; PutProp: PUBLIC PROC [onto: REF, prop: REF, val: REF] = BEGIN WITH onto SELECT FROM a: CD.ApplicationPtr => PutPropOnApplication[a, prop, val]; d: CD.Design => PutPropOnDesign[d, prop, val]; t: CD.Technology => PutPropOnTechnology[t, prop, val]; --l: CD.LevelRef => PutPropOnLevelRef[l, prop, val]; at: ATOM => PutPropOnAtom[at, prop, val]; ENDCASE => ERROR HasNoCDProperties END; GetProp: PUBLIC PROC [from: REF, prop: REF] RETURNS [REF] = BEGIN RETURN [WITH from SELECT FROM a: CD.ApplicationPtr => CDProperties.GetPropFromList[a.properties, prop], o: CD.ObPtr => CDProperties.GetPropFromList[o.properties, prop], d: CD.Design => CDProperties.GetPropFromList[d.properties, prop], t: CD.Technology => CDProperties.GetPropFromList[t.properties, prop], --l: CD.LevelRef => CDProperties.GetPropFromList[l.properties, prop], at: ATOM => GetPropFromAtom[at, prop], ENDCASE => ERROR HasNoCDProperties] END; PutPropOnObject: PUBLIC ENTRY PROC [onto: CD.ObPtr, prop: REF, val: REF] = BEGIN IF val#NIL THEN onto.properties _ Atom.PutPropOnList[onto.properties, prop, val] ELSE onto.properties _ Atom.RemPropFromList[onto.properties, prop] END; PutPropOnApplication: PUBLIC ENTRY PROC[onto: CD.ApplicationPtr, prop: REF, val: REF] = BEGIN IF val#NIL THEN onto.properties _ Atom.PutPropOnList[onto.properties, prop, val] ELSE onto.properties _ Atom.RemPropFromList[onto.properties, prop] END; PutPropOnDesign: PUBLIC ENTRY PROC [onto: CD.Design, prop: REF, val: REF] = BEGIN IF val#NIL THEN onto.properties _ Atom.PutPropOnList[onto.properties, prop, val] ELSE onto.properties _ Atom.RemPropFromList[onto.properties, prop] END; PutPropOnTechnology: PUBLIC ENTRY PROC[onto: CD.Technology, prop: REF, val: REF] = BEGIN IF val#NIL THEN onto.properties _ Atom.PutPropOnList[onto.properties, prop, val] ELSE onto.properties _ Atom.RemPropFromList[onto.properties, prop] END; PutPropOnAtom: PUBLIC PROC[onto: ATOM, prop: REF, val: REF] = {PutPropOnRef[onto: onto, prop: prop, val: val]}; PutPropOnLevel: PUBLIC ENTRY PROC[onto: CD.Level, prop: REF, val: REF] = BEGIN CDPrivate.levels[onto].properties _ IF val#NIL THEN Atom.PutPropOnList[CDPrivate.levels[onto].properties, prop, val] ELSE Atom.RemPropFromList[CDPrivate.levels[onto].properties, prop]; END; PutPropOnRef: ENTRY PROC[onto: REF, prop: REF, val: REF] = BEGIN x: REF; found: BOOL; pp: REF CD.Properties; [found, x] _ RefTab.Fetch[x: atomTab, key: onto]; IF found THEN pp _ NARROW[x, REF CD.Properties] ELSE { IF prop=NIL THEN RETURN; pp _ NEW[CD.Properties_NIL]; [] _ RefTab.Store[x: atomTab, key: onto, val: pp]; }; IF prop#NIL THEN pp^ _ Atom.PutPropOnList[propList: pp^, prop: prop, val: val] ELSE { pp^ _ Atom.RemPropFromList[propList: pp^, prop: prop]; IF pp^=NIL THEN [] _ RefTab.Delete[x: atomTab, key: onto] } END; GetPropFromRef: ENTRY PROC [from: REF, prop: REF] RETURNS [REF] = INLINE BEGIN x: REF; found: BOOL; pp: REF CD.Properties; [found, x] _ RefTab.Fetch[x: atomTab, key: from]; IF NOT found THEN RETURN[NIL]; pp _ NARROW[x, REF CD.Properties]; RETURN[Atom.GetPropFromList[propList: pp^, prop: prop]] END; GetPropFromObject: PUBLIC PROC [from: CD.ObPtr, prop: REF] RETURNS [REF] = {RETURN[CDProperties.GetPropFromList[from.properties, prop]]}; GetPropFromApplication: PUBLIC PROC [from: CD.ApplicationPtr, prop: REF] RETURNS [REF] = {RETURN[CDProperties.GetPropFromList[from.properties, prop]]}; GetPropFromDesign: PUBLIC PROC [from: CD.Design, prop: REF] RETURNS [REF] = {RETURN[CDProperties.GetPropFromList[from.properties, prop]]}; GetPropFromTechnology: PUBLIC PROC [from: CD.Technology, prop: REF] RETURNS [REF] = {RETURN[CDProperties.GetPropFromList[from.properties, prop]]}; GetPropFromLevel: PUBLIC PROC [from: CD.Level, prop: REF] RETURNS [REF] = {RETURN[CDProperties.GetPropFromList[CDPrivate.levels[from].properties, prop]]}; GetPropFromAtom: PUBLIC PROC [from: ATOM, prop: REF] RETURNS [REF] = {RETURN[GetPropFromRef[from: from, prop: prop]]}; InstallProcs: PUBLIC ENTRY PROC [prop: REF, new: PropertyProcsRec] = BEGIN p: PropertyProcs _ FetchProcs[prop]; IF p#NIL THEN BEGIN IF new.exclusive THEN p.exclusive_TRUE; IF new.makeCopy#NIL THEN p.makeCopy _ new.makeCopy; IF new.internalWrite#NIL THEN p.internalWrite _ new.internalWrite; IF new.internalRead#NIL THEN p.internalRead _ new.internalRead; IF new.ownersData#NIL THEN p.ownersData _ new.ownersData; END END; FetchProcs: PUBLIC PROC [prop: REF] RETURNS [PropertyProcs] = BEGIN x: REF; found: BOOL; [found: found, val: x] _ RefTab.Fetch[propertyNameTab, prop]; IF found THEN RETURN [NARROW[x, PropertyProcs]] ELSE RETURN [NIL] END; CopyVal: PUBLIC PROC [prop: REF, val: REF] RETURNS [valCopy: REF] = {valCopy _ val}; DontCopy: PUBLIC PROC [prop: REF, val: REF] RETURNS [nil: REF] = {nil _ NIL}; CopyProps: PUBLIC PROC [propList: Properties] RETURNS [copy: Properties_NIL] = BEGIN p: CDProperties.PropertyProcs; FOR l: Properties _ propList, l.rest WHILE l#NIL DO p _ FetchProcs[l.first.key]; IF p#NIL AND p.makeCopy#NIL THEN { copy _ Atom.PutPropOnList[ propList: copy, prop: l.first.key, val: p.makeCopy[prop: l.first.key, val: l.first.val] ]; } ELSE IF ISTYPE[l.first.key, ATOM] THEN WITH l.first.val SELECT FROM r: Rope.ROPE => { copy _ Atom.PutPropOnList[ propList: copy, prop: l.first.key, val: r ]; }; at: ATOM => { copy _ Atom.PutPropOnList[ propList: copy, prop: l.first.key, val: at ]; } ENDCASE => NULL; ENDLOOP; END; RopePWrite: PUBLIC PROC [prop: REF, val: REF] = BEGIN WITH val SELECT FROM r: Rope.ROPE => TokenIO.WriteRope[r]; at: ATOM => TokenIO.WriteRope[Atom.GetPName[at]]; ENDCASE => TokenIO.WriteRope["bad property value"]; END; AtomPWrite: PUBLIC PROC [prop: REF, val: REF] = BEGIN WITH val SELECT FROM at: ATOM => TokenIO.WriteAtom[at]; r: Rope.ROPE => TokenIO.WriteAtom[Atom.MakeAtom[r]]; ENDCASE => TokenIO.WriteAtom[$Bad]; END; IntPWrite: PUBLIC PROC [prop: REF, val: REF] = BEGIN WITH val SELECT FROM ri: REF INT => TokenIO.WriteInt[ri^]; rc: REF CARDINAL => TokenIO.WriteInt[rc^]; rn: REF NAT => TokenIO.WriteInt[rn^]; ENDCASE => TokenIO.WriteInt[0]; END; SomePWrite: PUBLIC PROC [prop: REF, val: REF] = BEGIN WITH val SELECT FROM at: ATOM => TokenIO.WriteAtom[at]; r: Rope.ROPE => TokenIO.WriteRope[r]; ri: REF INT => TokenIO.WriteInt[ri^]; rc: REF CARDINAL => TokenIO.WriteInt[rc^]; rn: REF NAT => TokenIO.WriteInt[rn^]; ENDCASE => TokenIO.WriteAtom[$Unknown]; END; RopePRead: PUBLIC PROC [prop: ATOM] RETURNS [val: REF] = BEGIN val _ TokenIO.ReadRope[] END; AtomPRead: PUBLIC PROC [prop: ATOM] RETURNS [val: REF] = BEGIN val _ TokenIO.ReadAtom[] END; IntPRead: PUBLIC PROC [prop: ATOM] RETURNS [val: REF] = BEGIN val _ NEW[INT_TokenIO.ReadInt[]] END; SomePRead: PUBLIC PROC [prop: ATOM] RETURNS [val: REF] = BEGIN t: TokenIO.Token _ TokenIO.ReadToken[]; SELECT t.kind FROM atom, int, rope => val _ t.ref; ENDCASE => val _ $Error; END; [] _ CDProperties.RegisterProperty[$SignalName]; [] _ CDProperties.RegisterProperty[$InstanceName]; CDProperties.InstallProcs[prop: $SignalName, new: CDProperties.PropertyProcsRec[ makeCopy: CDProperties.CopyVal, internalWrite: CDProperties.RopePWrite, internalRead: CDProperties.RopePRead ]]; CDProperties.InstallProcs[prop: $InstanceName, new: CDProperties.PropertyProcsRec[ makeCopy: CDProperties.CopyVal, internalWrite: CDProperties.RopePWrite, internalRead: CDProperties.RopePRead ]]; END. ZCDPropertiesImpl.mesa a Chipndale module by Ch. Jacobi September 27, 1983 2:06 pm last edited Christian Jacobi February 14, 1984 1:28 pm --Registration --registers "prop" in a table; any program which wants to use an ATOM --as a "prop" gets to know if it is already in use. --Usage --a NIL val removes the property --considered bad: o: CD.ObPtr => PutPropOnObject[o, prop, val]; --NIL if prop is not found --speed ups --a NIL val removes the property --a NIL val removes the property --a NIL val removes the property --a NIL val removes the property --a NIL val removes the property --a NIL val removes the property --a NIL val removes the property --here onto MUST NOT be a Chipndale ref pointing to a record with properties, --since then the properties must be used, not the hash table --NIL if prop is not found --here from MUST NOT be a Chipndale ref pointing to a record with properties, --since then the properties must be used, not the hash table --NIL if prop is not found --NIL if prop is not found --NIL if prop is not found --NIL if prop is not found --NIL if prop is not found --NIL if prop is not found --property procedures --prop must be registered and yours --overwrites values for which new has non NIL entries --never copy PropertyProcs^; it can be extended by future calls of InstallProcs ------------- --now register some properties Ê y˜Jšœ*™*Jšœ*™*Jšœ8™8J˜šÏk ˜ J˜ Jšœ˜J˜ J˜J˜J˜Jšœ˜J˜—šÏnœœœ˜ Jšœ4˜;Jšœ˜—Jš˜J˜Jšœ œœ ˜!Jšœœ˜1Jšœœ!˜7J˜Jšœ'Ïc?˜fJ˜Jšœ™J˜Jšœ/Ÿ+˜ZJšœ/Ÿ˜KJ˜šžœœ œœœœœ œ˜iJšœF™FJšœ4™4Jš˜Jšœ˜Jšœœ˜ Jšœ=Ÿ˜Zšœœ˜Jš œœœœœœ˜CJšœœœœ˜.J˜—šœ˜Jšœœ˜*Jšœ/Ÿ˜7Jšœ<Ÿ˜KJ˜—Jšœ˜J˜J˜—Jšœ™J˜Jšœœœ˜ J˜š žœœœœœœ˜7Jšœ ™ Jš˜šœœ˜Jšœœ6˜;Jšœ?™?Jšœœ)˜.Jšœœ1˜6Jšœœ-˜4Jšœ)˜)Jšœœ˜"—Jšœ˜J˜—šžœœœœœœœ˜;Jšœ™Jš˜šœœœ˜JšœœD˜IJšœœ;˜@Jšœœ<˜AJšœœ@˜EJšœœ>˜EJšœ&˜&Jšœœ˜#—Jšœ˜J˜—Jšœ ™ J˜šžœœœœœœœ˜JJšœ ™ Jš˜JšœœœA˜PJšœ>˜BJšœ˜J˜—šžœœœœœœœ˜WJšœ ™ Jš˜JšœœœA˜PJšœ>˜BJšœ˜J˜—šžœœœœœœœ˜KJšœ ™ Jš˜JšœœœA˜PJšœ>˜BJšœ˜J˜—šžœœœœœœœ˜RJšœ ™ Jš˜JšœœœA˜PJšœ>˜BJšœ˜J˜—š ž œœœœœœ˜=Jšœ ™ Jšœ1˜1J˜—šžœœœœœœœ˜HJšœ ™ Jš˜šœ$˜$JšœœœA˜PJšœ?˜C—Jšœ˜J˜—š ž œœœœœœ˜:Jšœ ™ JšœM™MJšœ<™˜Nšœ˜Jšœ6˜6Jšœœœ*˜9Jšœ˜—Jšœ˜J˜—š žœ œœœœœ˜AJšœ™JšœM™MJšœ<™J˜—šžœœœœœœœ˜XJšœ™Jšœœ7˜>J˜—šžœœœœœœœ˜KJšœ™Jšœœ7˜>J˜—šžœœœœœœœ˜SJšœ™Jšœœ7˜>—J˜šžœœœœœœœ˜IJšœ™JšœœI˜PJ˜—šžœœœœœœœ˜DJšœ™Jšœœ*˜1—J˜Jšœ™J˜š ž œœœœœ˜DJšœ#™#Jšœ5™5Jš˜J˜$šœœ˜ Jš˜Jšœœ œ˜'Jšœœœ˜3Jšœœœ%˜BJšœœœ#˜?Jšœœœ˜9Jš˜—Jšœ˜J˜—š ž œœœœœ˜=JšœO™OJš˜Jšœœ˜Jšœœ˜ J˜=Jšœœœœœœœ˜BJšœ˜J˜—šžœœœœœœ œ˜CJ˜J˜—šžœœœœœœœ˜@Jšœœ˜ J˜—š ž œœœœœ˜NJš˜J˜šœ"œœ˜3Jšœ˜š œœœ œœ˜"˜J˜J˜J˜4J˜—J˜—š œœœœœ˜'šœ œ˜šœœ˜˜J˜J˜J˜J˜—J˜—šœœ˜ ˜J˜J˜Jšœ˜J˜—J˜—Jšœœ˜——Jšœ˜—Jšœ˜J˜—šÏb œ œœœ˜/Jš˜šœœ˜Jšœœ˜%Jšœœ)˜1Jšœ,˜3—Jšœ˜J˜—š  œ œœœ˜/Jš˜šœœ˜Jšœœ˜"Jšœœ(˜4Jšœ˜#—Jšœ˜J˜—š Ðbn œœœœœ˜.Jš˜šœœ˜Jšœœœ˜%Jšœœœ˜*Jšœœœ˜%Jšœ˜—Jšœ˜J˜—š ¡ œœœœœ˜/Jš˜šœœ˜Jšœœ˜"Jšœœ˜%Jšœœœ˜%Jšœœœ˜*Jšœœœ˜%Jšœ ˜'—Jšœ˜J˜—š   œ œœœœ˜8Jš˜J˜Jšœ˜J˜—š   œ œœœœ˜8Jš˜J˜Jšœ˜J˜—š ¡œœœœœœ˜7Jš˜Jšœœœ˜ Jšœ˜J˜—š ¡ œœœœœœ˜8Jš˜Jšœ'˜'šœ˜Jšœ˜Jšœ˜—Jšœ˜J˜—Jšœ ™ Jšœ™Jšœ0˜0Jšœ3˜3šœ2˜2šœ˜Jšœ˜Jšœ'˜'Jšœ$˜$Jšœ˜——šœ4˜4šœ˜Jšœ˜Jšœ'˜'Jšœ$˜$Jšœ˜——Jšœ˜J˜J˜—…—!V4)