CDLayersImpl.mesa (part of ChipNDale)
Copyright © 1983, 1985 by Xerox Corporation. All rights reserved.
by Christian Jacobi, August 11, 1983 11:32 am
last edited by Christian Jacobi, March 18, 1986 11:33:08 am PST
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] =
BEGIN
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
};
END;
GetLayerRec: PROC [design: Design, layer: Layer] RETURNS [REF LayerRec] =
BEGIN
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
};
END;
CurrentLayer: PUBLIC PROC [design: Design] RETURNS [Layer] =
BEGIN
RETURN [CDValue.FetchInt[design, $CurrentLayer, technology]]
END;
LayerWidth: PUBLIC PROC [design: Design, layer: Layer] RETURNS [Number] =
BEGIN
RETURN [GetLayerRec[design, layer].w]
END;
PlaceholderToAbstract: PUBLIC PROC [design: Design, layer: Layer] RETURNS [Layer] =
BEGIN
IF lKind[layer]=placeholder THEN RETURN [GetLayerRec[design, layer].use];
RETURN [layer];
END;
SetCurrentLayer: PUBLIC PROC [design: REF, layer: Layer] =
BEGIN
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;
END;
--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] =
BEGIN
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;
};
END;
SetPlaceholderToAbstract: PUBLIC PROC [design: Design, placeholder, abstract: Layer] =
BEGIN
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;
};
END;
MakeAbstract: PUBLIC PROC [abstract: CD.Layer, represents: CD.Layer] =
--only technology implementor should call this procedure
BEGIN
IF lKind[abstract]#paint THEN ERROR;
lKind[abstract] ← abstract;
lPaint[abstract] ← represents;
END;
MakePlaceholder: PUBLIC PROC [layer: CD.Layer, defaultsTo: CD.Layer] =
--only technology implementor should call this procedure
BEGIN
IF lKind[layer]#paint THEN ERROR;
lKind[layer] ← placeholder;
lPaint[layer] ← CD.errorLayer;
GetGlobalLayerRec[layer].use ← defaultsTo;
END;
MakePaint: PUBLIC PROC [layer: CD.Layer] =
--only technology implementor should call this procedure
BEGIN
IF lKind[layer]#placeholder THEN ERROR;
lKind[layer] ← paint;
lPaint[layer] ← layer;
GetGlobalLayerRec[layer].use ← layer;
END;
RegisterNotifiers: PUBLIC ENTRY PROC [layer: DesignNotifyProc←NIL, width: LayerNotifyProc←NIL, placeholder: LayerNotifyProc←NIL] =
BEGIN
IF layer#NIL THEN layerPs ← CONS[layer, layerPs];
IF width#NIL THEN widthPs ← CONS[width, widthPs];
IF placeholder#NIL THEN placeholderPs ← CONS[placeholder, placeholderPs];
END;
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.