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:
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;