CDEventsImpl.mesa
Copyright © 1983 by Xerox Corporation. All rights reserved.
by Christian Jacobi September 16, 1983 2:11 pm
last edited by Christian Jacobi September 16, 1983 9:52 pm
DIRECTORY
CDEvents,
CD,
RefTab;
CDEventsImpl: CEDAR MONITOR
IMPORTS CD, RefTab
EXPORTS CDEvents =
BEGIN
EventProc: TYPE = CDEvents.EventProc;
EventRegistration: TYPE = REF EventRegistrationRep;
EventRegistrationRep: PUBLIC TYPE = RECORD [
event: REF,
eventProcs: EventProcs←NIL
];
EventProcs: TYPE = LIST OF RECORD [proc: EventProc, filter: CD.Technology];
eventNameTable: RefTab.Ref ~ RefTab.Create[];
RegisterEventType: PUBLIC PROC [eventName: REF] RETURNS [EventRegistration] =
--returns EventRegistration=NIL if eventName is already used.
--the EventRegistration is the key to call ProcessEvent
--if ATOM are used for eventName, include them manual in the list
--on file [ivy]<jacobi>chipndale>CDEvents-registration.txt
BEGIN
ev: EventRegistration←NEW[EventRegistrationRep←[event: eventName]];
IF ~RefTab.Insert[eventNameTable, eventName, ev] THEN ev←NIL;
IF ev=NIL THEN ERROR CD.Error[doubleRegistration];
RETURN [ev]
END;
RegisterEventProc: PUBLIC PROC [event: REF, proc: EventProc, filter: CD.Technology←NIL] =
--registers a procedure which is called each time a specific event occurs
--the procedure might stop certain events with the dont result
--if filter#NIL, proc is only called if event occurs on design of technology=filter
--event must have been previously registered with RegisterEventType
BEGIN
ev: EventRegistration;
x: REF;
found: BOOL;
[found, x] ← RefTab.Fetch[eventNameTable, event];
IF NOT found THEN ERROR CD.Error[missingRegistration];
ev ← NARROW[x];
--insert new proc at end!
--(then first registered procedures are called first)
--application procedures are called after chipndale kernel procedures
IF ev.eventProcs=NIL THEN ev.eventProcs←LIST[[proc, filter]]
ELSE
FOR l: EventProcs ← ev.eventProcs, l.rest DO
IF l.rest=NIL THEN {l.rest←LIST[[proc, filter]]; RETURN}
ENDLOOP
END;
ProcessEvent: PUBLIC PROC [ev: EventRegistration, design: CD.Design, x: REFNIL,
listenToDont: BOOLFALSE]
RETURNS [dont: BOOLFALSE] =
--called on certain events
--can be called only if the EventRegistration is known
BEGIN
IF ev#NIL THEN
FOR l: EventProcs ← ev.eventProcs, l.rest WHILE l#NIL DO
IF l.first.filter#NIL AND
(design=NIL OR l.first.filter#design.technology) THEN LOOP;
dont ← l.first.proc[ev.event, design, x ! ABORTED => CONTINUE].dont;
IF dont AND listenToDont THEN RETURN;
ENDLOOP
END;
END.