CDEnvironmentImpl.mesa (part of ChipNDale)
Copyright © 1984, 1985 by Xerox Corporation. All rights reserved.
by Christian Jacobi, December 18, 1984 12:26:50 pm PST
last edited by Christian Jacobi, April 16, 1985 11:55:52 am PST
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𡤀] 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𡤀, ifNotFound: INT𡤀] 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: BOOLFALSE] =
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.