<> <> <> DIRECTORY ViewerClasses USING [Viewer], ViewerEvents; ViewerEventsImpl: CEDAR PROGRAM EXPORTS ViewerEvents = BEGIN OPEN ViewerEvents; EventProcs: TYPE = LIST OF RECORD[proc: EventProc, filter: REF, before: BOOL] ; eventProcs: ARRAY ViewerEvent OF EventProcs ; RegisterEventProc: PUBLIC PROC [proc: EventProc, event: ViewerEvent, filter: REF ANY _ NIL, before: BOOL _ TRUE] RETURNS [EventRegistration] = BEGIN RETURN [eventProcs[event] _ CONS[[proc, filter, before], eventProcs[event]]]; END; UnRegisterEventProc: PUBLIC PROC [proc: EventRegistration, event: ViewerEvent] = BEGIN prev: EventProcs _ eventProcs[event]; IF prev = NIL THEN RETURN; IF proc=prev THEN { -- its the first one on the list eventProcs[event] _ eventProcs[event].rest; RETURN }; FOR l: EventProcs _ prev.rest, l.rest UNTIL l=NIL DO IF l=proc THEN { prev.rest _ l.rest; RETURN }; prev _ l; ENDLOOP; END; ProcessEvent: PUBLIC PROC [event: ViewerEvent, viewer: ViewerClasses.Viewer, before: BOOL] RETURNS[abort: BOOL _ FALSE] = BEGIN FOR l: EventProcs _ eventProcs[event], l.rest UNTIL l=NIL DO IF l.first.before # before THEN LOOP; IF l.first.filter # NIL AND l.first.filter # viewer AND l.first.filter # viewer.class.flavor THEN LOOP; abort _ l.first.proc[viewer, event, before ! ABORTED => CONTINUE].abort; IF abort THEN RETURN; ENDLOOP; END; END.