CDLayersImpl.mesa (part of ChipNDale)
Copyright © 1983, 1985, 1986 by Xerox Corporation. All rights reserved.
Created by Christian Jacobi, August 11, 1983 11:32 am
Last edited by: Christian Jacobi, September 17, 1986 3:28:37 pm PDT
DIRECTORY
CD,
CDLayers,
CDPrivate,
CDValue;
CDLayersImpl:
CEDAR
MONITOR
IMPORTS CDPrivate, CDValue
EXPORTS CDLayers
SHARES CDLayers =
BEGIN
Layer: TYPE = CD.Layer;
Number: TYPE = CD.Number;
Design: TYPE = CD.Design;
DesignNotifyProc: TYPE = CDLayers.DesignNotifyProc;
LayerNotifyProc: TYPE = CDLayers.LayerNotifyProc;
LayerKind: TYPE = CDLayers.LayerKind;
LayerRec: TYPE = RECORD [w: Number, use: Layer];
GetGlobalLayerRec:
PROC [layer: Layer]
RETURNS [
REF LayerRec] = {
WITH CDValue.Fetch[boundTo:
NIL, key: CDPrivate.layers[layer].globalUniqueKey]
SELECT
FROM
lr: REF LayerRec => RETURN [lr];
ENDCASE => {
lr: REF LayerRec ← NEW[LayerRec ← [w: 0, use: layer]];
[] ← CDValue.StoreConditional[NIL, CDPrivate.layers[layer].globalUniqueKey, lr];
RETURN [GetGlobalLayerRec[layer]]; --recursion prevents concurrency problems
};
};
GetLayerRec:
PROC [design: Design, layer: Layer]
RETURNS [
REF LayerRec] = {
WITH CDValue.Fetch[boundTo: design, key: CDPrivate.layers[layer].globalUniqueKey, propagation: design]
SELECT
FROM
lr: REF LayerRec => RETURN [lr];
ENDCASE => {
lr: REF LayerRec ← NEW[LayerRec ← GetGlobalLayerRec[layer]^];
[] ← CDValue.StoreConditional[design, CDPrivate.layers[layer].globalUniqueKey, lr];
RETURN [GetLayerRec[design, layer]]; --recursion prevents concurrency problems
};
};
CurrentLayer:
PUBLIC
PROC [design: Design]
RETURNS [Layer] = {
RETURN [CDValue.FetchInt[design, $CurrentLayer, technology]]
};
LayerWidth:
PUBLIC
PROC [design: Design, layer: Layer]
RETURNS [Number] = {
RETURN [GetLayerRec[design, layer].w]
};
PlaceholderToAbstract:
PUBLIC
PROC [design: Design, layer: Layer]
RETURNS [Layer] = {
IF lKind[layer]=placeholder THEN RETURN [GetLayerRec[design, layer].use];
RETURN [layer];
};
SetCurrentLayer:
PUBLIC
PROC [design:
REF, layer: Layer] = {
CDValue.StoreInt[boundTo: design, key: $CurrentLayer, value: layer];
WITH design
SELECT
FROM
d: Design =>
FOR list:
LIST
OF DesignNotifyProc ← layerPs, list.rest
WHILE list#
NIL
DO
list.first[d];
ENDLOOP;
ENDCASE => NULL;
};
--design can exceptionally be a technology to set default values
--reserve call for CDPanelImpl; otherwise CDPanel gets fooled
SetLayerWidth:
PUBLIC
PROC [design: Design, layer: Layer, width: Number] = {
IF design=NIL THEN GetGlobalLayerRec[layer].w ← width
ELSE {
GetLayerRec[design, layer].w ← width;
FOR list:
LIST
OF LayerNotifyProc ← widthPs, list.rest
WHILE list#
NIL
DO
list.first[design, layer];
ENDLOOP;
};
};
SetPlaceholderToAbstract:
PUBLIC
PROC [design: Design, placeholder, abstract: Layer] = {
IF lKind[placeholder]=placeholder THEN ERROR;
IF design=NIL THEN GetGlobalLayerRec[placeholder].use ← abstract
ELSE {
GetLayerRec[design, placeholder].use ← abstract;
FOR list:
LIST
OF LayerNotifyProc ← placeholderPs, list.rest
WHILE list#
NIL
DO
list.first[design, placeholder];
ENDLOOP;
};
};
MakeAbstract:
PUBLIC
PROC [abstract:
CD.Layer, represents:
CD.Layer] = {
--only technology implementor should call this procedure
IF lKind[abstract]#paint THEN ERROR;
lKind[abstract] ← abstract;
lPaint[abstract] ← represents;
};
MakePlaceholder:
PUBLIC
PROC [layer:
CD.Layer, defaultsTo:
CD.Layer] = {
--only technology implementor should call this procedure
IF lKind[layer]#paint THEN ERROR;
lKind[layer] ← placeholder;
lPaint[layer] ← CD.errorLayer;
GetGlobalLayerRec[layer].use ← defaultsTo;
};
MakePaint:
PUBLIC
PROC [layer:
CD.Layer] = {
--only technology implementor should call this procedure
IF lKind[layer]#placeholder THEN ERROR;
lKind[layer] ← paint;
lPaint[layer] ← layer;
GetGlobalLayerRec[layer].use ← layer;
};
RegisterNotifiers:
PUBLIC
ENTRY
PROC [layer: DesignNotifyProc←
NIL, width: LayerNotifyProc←
NIL, placeholder: LayerNotifyProc←
NIL] = {
IF layer#NIL THEN layerPs ← CONS[layer, layerPs];
IF width#NIL THEN widthPs ← CONS[width, widthPs];
IF placeholder#NIL THEN placeholderPs ← CONS[placeholder, placeholderPs];
};
lKind: REF ARRAY Layer OF LayerKind = NEW[ARRAY Layer OF LayerKind];
layerKind: PUBLIC REF READONLY ARRAY Layer OF LayerKind = lKind;
lPaint: REF ARRAY Layer OF Layer = NEW[ARRAY Layer OF Layer];
layerPaint: PUBLIC REF READONLY ARRAY Layer OF Layer = lPaint;
layerPs: LIST OF DesignNotifyProc ← NIL;
widthPs: LIST OF LayerNotifyProc ← NIL;
placeholderPs: LIST OF LayerNotifyProc ← NIL;
CDValue.RegisterKey[key: $CurrentLayer];
FOR l: Layer
IN Layer
DO
lKind[l] ← placeholder;
lPaint[l] ← l;
[] ← CDValue.RegisterKey[CDPrivate.layers[l].globalUniqueKey];
ENDLOOP;
END.