<> <> <> <> DIRECTORY CD USING [ApplicationPtr, DrawRef, ObPtr], CDDirectory, CDEnvironment, CDConditions, CDProperties; CDEnvironmentImpl: CEDAR PROGRAM IMPORTS CDConditions, CDDirectory, CDProperties EXPORTS CDEnvironment = BEGIN <<-- Accessing the nesting environment of objects while drawing.>> GetProp: PUBLIC PROC [environment: CD.DrawRef, prop: REF, skipInnerMost: NAT_0] RETURNS [REF] = <<-- Access propertylists of nesting applications while a draw process...>> <<-- Finds nested-most occurance of property prop.>> <<-- skipInnerMost: the "skipInnerMost" most nested occurences of the property are ignored.>> <<-- Returns NIL if prop is not found.>> <<-- Does not return properties from the environment of an object which does not propagate.>> BEGIN IF environment.nestDepth>0 THEN { FOR c: INT _ environment.nestDepth-1, c-1 WHILE c>=0 DO ap: CD.ApplicationPtr = environment.nesting.table[c]; x: REF _ CDProperties.GetPropFromApplication[ap, prop]; IF x#NIL THEN IF skipInnerMost=0 THEN RETURN [x] ELSE skipInnerMost _ skipInnerMost-1; IF ~InlinePropagates[ap.ob] THEN EXIT; ENDLOOP; }; RETURN [NIL] END; GetIntProp: PUBLIC PROC[environment: CD.DrawRef, prop: REF, skipInnerMost: NAT_0, ifNotFound: INT_0] RETURNS [INT] = <<-- it is good practice to use an impossible value for "ifNotFound"; defaulting is >> <<-- dangerous because it could hide bugs.>> BEGIN x: INT _ ifNotFound; WITH GetProp[environment: environment, prop: prop, skipInnerMost: skipInnerMost] SELECT FROM intP: REF INT => x _ intP^; ENDCASE => NULL; RETURN [x] END; Propagates: PUBLIC PROC [ob: CD.ObPtr] RETURNS [BOOL] = BEGIN RETURN [InlinePropagates[ob]]; END; InlinePropagates: PROC [ob: CD.ObPtr] RETURNS [BOOL] = INLINE <<-- propagates TRUE means GetProp (et al) will access properties of outer levels.>> <<-- propagates FALSE means GetProp (et al) will not access properties of outer levels.>> BEGIN RETURN [ ob.p.reservedForCDEnvironment AND ( CDConditions.IsCondition[ob] OR CDProperties.GetPropFromObject[ob, $CDxPropagate]=$CDxPropagate ) ]; END; AllowPropagation: PUBLIC PROC [ob: CD.ObPtr, propagates: BOOL] = <<-- default if not called at all is FALSE>> <<-- Only allowed to objects with "inDirectory" TRUE>> BEGIN IF ~ob.p.inDirectory THEN ERROR; CDProperties.PutPropOnObject[ onto: ob, prop: $CDxPropagate, val: (IF propagates THEN $CDxPropagate ELSE NIL) ]; IF propagates THEN ob.p.reservedForCDEnvironment _ TRUE; CDDirectory.PropagateChange[ob, NIL]; END; SomeChildPropagates: PUBLIC PROC [ob: CD.ObPtr] RETURNS [yes: BOOL_FALSE] = BEGIN CheckAChild: CDDirectory.EnumerateObjectsProc = { IF me.p.inDirectory AND InlinePropagates[me] THEN yes _ TRUE }; CDDirectory.EnumerateChildObjects[me: ob, p: CheckAChild, x: NIL]; RETURN [yes] END; <<>> END.