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 August 29, 1984 10:03:35 am PDT
DIRECTORY
AMBridge,
AMTypes,
CD,
CDDraw,
CDVFurtherPainters,
CDVPrivate,
RefTab,
RuntimeError;
CDVFurtherPaintersImpl:
CEDAR
PROGRAM
IMPORTS AMBridge, AMTypes, RefTab, RuntimeError
EXPORTS CDVFurtherPainters =
BEGIN
FurtherPaintProc:
TYPE = CDVFurtherPainters.FurtherPaintProc;
--PROC [me: CDVPrivate.MyGraphicRef, 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: REF←NIL, --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[CDDraw.Comm] OR keyReferentType=AMTypes.nullType THEN ERROR
ELSE
typeList ← CONS[NEW[MyRec←[type: keyReferentType, proc: proc]], typeList]
}
END;
CallFurther:
PUBLIC
PROC[me: CDVPrivate.MyGraphicRef, 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
comm: REF CDDraw.Comm => key ← comm.ref
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.