CDVFurtherPaintersImpl.mesa
Copyright © 1984 by Xerox Corporation. All rights reserved.
by Christian Jacobi, August 29, 1984 10:03:32 am PDT
last edited by Christian Jacobi, January 2, 1986 11:58:55 am PST
DIRECTORY
AMBridge,
AMTypes,
CD,
CDDrawQueue,
CDVFurtherPainters,
CDVPrivate,
RefTab,
RuntimeError;
CDVFurtherPaintersImpl: CEDAR PROGRAM
IMPORTS AMBridge, AMTypes, RefTab, RuntimeError
EXPORTS CDVFurtherPainters =
BEGIN
FurtherPaintProc: TYPE = CDVFurtherPainters.FurtherPaintProc;
--PROC [me: CDVPrivate.VRef, key: REF];
valueTable: RefTab.Ref = RefTab.Create[mod: 13];
MyRec: TYPE = RECORD[type: AMTypes.Type, proc: FurtherPaintProc];
TypeList: TYPE = LIST OF REF MyRec;
typeList: TypeList;
InstallFurtherPaint: PUBLIC PROC[
keyReferentType: AMTypes.Type𡤊MTypes.nullType, --default means check value only
keyValue: REFNIL, --default means check type only; you can not install a proc for NIL
proc: FurtherPaintProc
] =
--All errors and signals from proc will be catched.
--Sometimes calls proc with; sometimes without locks, depending on key.
--It is ok to call the viewers-PaintProc recursively, but please
--do not cause wedges, there is no protection.
--Manual registration of key is requested.
--May or may not check if keyValue is of type keyType, if both non NIL
BEGIN
IF proc=NIL THEN ERROR
ELSE {
IF keyValue#NIL THEN
[] ← RefTab.Store[valueTable, keyValue, NEW[FurtherPaintProc←proc]]
ELSE IF keyReferentType=CODE[CDDrawQueue.Request] OR keyReferentType=AMTypes.nullType THEN ERROR
ELSE
typeList ← CONS[NEW[MyRec←[type: keyReferentType, proc: proc]], typeList]
}
END;
CallFurther: PUBLIC PROC[me: CDVPrivate.VRef, key: REF] =
--Catches all errors and signals!
--Called by the viewer paintproc of ChipNDale-design viewers only.
BEGIN
found: BOOLEAN;
val: RefTab.Val;
transmitt: REF ← key;
WITH key SELECT FROM
req: REF CDDrawQueue.Request => key ← req.key
ENDCASE => NULL;
[found, val] ← RefTab.Fetch[valueTable, key];
IF found THEN {
--first check if we know the value of key
p: REF FurtherPaintProc ~ NARROW[val];
p^[me, transmitt ! RuntimeError.UNCAUGHT => GOTO return]
}
ELSE {
--then check if we know the type of key
type: AMTypes.Type;
TRUSTED {
ENABLE RuntimeError.UNCAUGHT => GOTO return;
type ← AMTypes.TVType[AMBridge.TVForReferent[key]]
};
FOR list: TypeList ← typeList, list.rest WHILE list#NIL DO
IF list.first.type=type THEN {
list.first.proc[me, transmitt ! RuntimeError.UNCAUGHT => GOTO return];
EXIT
}
ENDLOOP;
}
EXITS return => NULL
END;
END.