[Indigo]<Rosemary>®>Rosemary.DF=>RoseEventsImpl.Mesa
Last Edited by: Spreitzer, May 1, 1985 7:44:21 pm PDT
DIRECTORY Asserting, Atom, IO, List, RoseEvents, RoseTypes;
RoseEventsImpl:
CEDAR
PROGRAM
IMPORTS Asserting, Atom, IO, List, RoseTypes
EXPORTS RoseEvents =
BEGIN OPEN RoseTypes;
all: PUBLIC REF ANY ← NEW [ROPE ← "All watcheds"];
watchersKey: ATOM ← Atom.MakeAtom["Spreitzer January 6, 1984 8:07 pm"];
ForWatchers:
PROC [event:
ATOM, watched:
REF
ANY, do:
PROC [WatcherList]
RETURNS [WatcherList], replace:
BOOL] = {
wll: List.AList;
wl: WatcherList;
IF watched #
NIL
THEN
WITH watched
SELECT
FROM
node: Node => {
SELECT event
FROM
$ChangeEarly => node.watchers[high] ← do[node.watchers[high]];
$ChangeLate => node.watchers[ordinary] ← do[node.watchers[ordinary]];
ENDCASE =>
BEGIN
wl ← NARROW[Asserting.FnVal[fn: event, from: node.other]];
wl ← do[wl];
IF replace THEN node.other ← Asserting.AssertFn1[fn: event, val: wl, inAdditionTo: node.other];
END;
RETURN};
cell: Cell => {
SELECT event
FROM
$Schedule => {
IF cell.substantiality = Shadow
THEN
ERROR Error[
IO.PutFR["Cell %g not Real",
IO.rope[cell.name]]];
cell.realCellStuff.schedWatchers ← do[cell.realCellStuff.schedWatchers]};
$Eval => {
IF cell.substantiality = Shadow
THEN
ERROR Error[
IO.PutFR["Cell %g not Real",
IO.rope[cell.name]]];
cell.realCellStuff.evalWatchers ← do[cell.realCellStuff.evalWatchers]};
ENDCASE =>
BEGIN
wl ← NARROW[Asserting.FnVal[fn: event, from: cell.other]];
wl ← do[wl];
IF replace THEN cell.other ← Asserting.AssertFn1[fn: event, val: wl, inAdditionTo: cell.other];
END;
RETURN};
ENDCASE;
wll ← NARROW[Atom.GetProp[atom: event, prop: watchersKey]];
wl ← NARROW[List.Assoc[key: watched, aList: wll]];
wl ← do[wl];
IF replace
THEN {
wll ← List.PutAssoc[key: watched, val: wl, aList: wll];
Atom.PutProp[atom: event, prop: watchersKey, val: wll];
};
};
AddWatcher:
PUBLIC
PROC [event:
ATOM, watcher: Watcher, watched:
REF
ANY ←
NIL] =
BEGIN
Addit:
PROC [ohne: WatcherList]
RETURNS [mit: WatcherList] =
{mit ← CONS[watcher, ohne]};
ForWatchers[event, watched, Addit, TRUE];
END;
RemoveWatcher:
PUBLIC
PROC [event:
ATOM, watcher: Watcher, watched:
REF
ANY ←
NIL] =
BEGIN
RemoveIt:
PROC [watchers: WatcherList]
RETURNS [ohne: WatcherList] = {
cur, prev: WatcherList ← NIL;
ohne ← watchers;
FOR cur ← watchers, cur.rest
WHILE cur #
NIL
DO
IF cur.first = watcher
THEN
{IF prev = NIL THEN ohne ← cur.rest ELSE prev.rest ← cur.rest;
RETURN};
prev ← cur;
ENDLOOP;
};
ForWatchers[event, watched, RemoveIt, TRUE];
END;
Notify:
PUBLIC
PROC [event:
ATOM, watched:
REF
ANY ←
NIL, handleAborted:
BOOL, arg:
REF
ANY ←
NIL] =
BEGIN
abort: BOOLEAN ← FALSE;
abortedWatchers: WatcherList ← NIL;
NotifyEm:
PROC [wl: WatcherList]
RETURNS [same: WatcherList] = {
same ← wl;
FOR wl ← wl, wl.rest
WHILE wl #
NIL
DO
wl.first.Notify[
event: event,
watched: watched,
watcherData: wl.first.watcherData,
arg: arg
!
ABORTED =>
IF handleAborted
THEN {
abort ← TRUE;
abortedWatchers ← CONS[wl.first, abortedWatchers];
CONTINUE}];
ENDLOOP;
};
IF watched = all THEN ERROR;
ForWatchers[event, watched, NotifyEm, FALSE];
ForWatchers[event, all, NotifyEm, FALSE];
IF abort THEN ERROR ABORTED;
END;
END.