DIRECTORY Asserting, Atom, IO, List, RoseEvents, RoseTypes; RoseEventsImpl: CEDAR PROGRAM IMPORTS Asserting, Atom, IO, List EXPORTS RoseEvents, RoseTypes = BEGIN OPEN RoseTypes; Error: PUBLIC ERROR [msg: ROPE, data: REF ANY _ NIL] = CODE; Warning: PUBLIC SIGNAL [msg: ROPE, data: REF ANY _ NIL] = CODE; Stop: PUBLIC SIGNAL [msg: ROPE, data: REF ANY _ NIL] = CODE; watchersKey: ATOM _ Atom.MakeAtom["Spreitzer January 6, 1984 8:07 pm"]; AddWatcher: PUBLIC PROC [event: ATOM, watcher: Watcher, watched: REF ANY _ NIL] = BEGIN wll: List.AList; wl: WatcherList; IF watched # NIL THEN WITH watched SELECT FROM node: Node => { Add: PROC [priority: Priority] = {node.watchers[priority] _ CONS[watcher, node.watchers[priority]]}; SELECT event FROM $ChangeEarly => Add[high]; $ChangeLate => Add[ordinary]; ENDCASE => BEGIN wl _ NARROW[Asserting.FnVal[fn: event, from: node.other]]; wl _ CONS[watcher, wl]; 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 _ CONS[watcher, cell.realCellStuff.schedWatchers]}; $Eval => {IF cell.substantiality = Shadow THEN ERROR Error[IO.PutFR["Cell %g not Real", IO.rope[cell.name]]]; cell.realCellStuff.evalWatchers _ CONS[watcher, cell.realCellStuff.evalWatchers]}; ENDCASE => BEGIN wl _ NARROW[Asserting.FnVal[fn: event, from: cell.other]]; wl _ CONS[watcher, wl]; 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 _ CONS[watcher, wl]; wll _ List.PutAssoc[key: watched, val: wl, aList: wll]; Atom.PutProp[atom: event, prop: watchersKey, val: wll]; END; RemoveWatcher: PUBLIC PROC [event: ATOM, watcher: Watcher, watched: REF ANY _ NIL] = BEGIN wll: List.AList; wl: WatcherList; IF watched # NIL THEN WITH watched SELECT FROM node: Node => { Sub: PROC [priority: Priority] = {node.watchers[priority] _ FilterWatcher[watcher, node.watchers[priority]]}; SELECT event FROM $ChangeEarly => Sub[high]; $ChangeLate => Sub[ordinary]; ENDCASE => BEGIN wl _ NARROW[Asserting.FnVal[fn: event, from: node.other]]; wl _ FilterWatcher[watcher, wl]; node.other _ Asserting.AssertFn1[fn: event, val: wl, inAdditionTo: node.other]; END; RETURN}; cell: Cell => { SELECT event FROM $Schedule => {cell.realCellStuff.schedWatchers _ FilterWatcher[watcher, cell.realCellStuff.schedWatchers]}; $Eval => {cell.realCellStuff.evalWatchers _ FilterWatcher[watcher, cell.realCellStuff.evalWatchers]}; ENDCASE => BEGIN wl _ NARROW[Asserting.FnVal[fn: event, from: cell.other]]; wl _ FilterWatcher[watcher, wl]; 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 _ FilterWatcher[watcher, wl]; wll _ List.PutAssoc[key: watched, val: wl, aList: wll]; Atom.PutProp[atom: event, prop: watchersKey, val: wll]; END; FilterWatcher: PROC [watcher: Watcher, watchers: WatcherList] RETURNS [ohne: WatcherList] = BEGIN 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; END; Notify: PUBLIC PROC [event: ATOM, watched: REF ANY _ NIL, handleAborted: BOOLEAN _ FALSE, arg: REF ANY _ NIL] = BEGIN GetWatchers: PROC RETURNS [wl: WatcherList] = BEGIN wll: List.AList; IF watched # NIL THEN WITH watched SELECT FROM node: Node => { SELECT event FROM $ChangeEarly => RETURN [node.watchers[high]]; $ChangeLate => RETURN [node.watchers[ordinary]]; ENDCASE => RETURN [NARROW[Asserting.FnVal[fn: event, from: node.other]]]}; cell: Cell => { SELECT event FROM $Schedule => RETURN [cell.realCellStuff.schedWatchers]; $Eval => RETURN [cell.realCellStuff.evalWatchers]; ENDCASE => RETURN [NARROW[Asserting.FnVal[fn: event, from: cell.other]]]}; ENDCASE; wll _ NARROW[Atom.GetProp[atom: event, prop: watchersKey]]; wl _ NARROW[List.Assoc[key: watched, aList: wll]]; END; wl: WatcherList _ GetWatchers[]; abort: BOOLEAN _ FALSE; abortedWatchers: WatcherList _ NIL; 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}]; wl _ wl.rest; ENDLOOP; IF abort THEN ERROR ABORTED; END; END. ~[Indigo]Release>Rosemary2.DF=>RoseEventsImpl.Mesa Last Edited by: Spreitzer, September 6, 1984 3:26:31 pm PDT Κ– "cedar" style˜J™;J™;J˜JšΟk œ2˜;J˜codešΠbxœœ˜Kšœ˜!Kšœ˜—K˜Kšœœ ˜K˜KšΠblœœœœœœœœ˜Kšœ˜—K˜ Kšœ˜—Kšœ˜—K˜š œœœ œ œœœœœœœœ˜oKš˜š  œœœ˜-Kš˜Kšœ˜š œ œœœ œ˜.˜šœ˜Kšœœ˜-Kšœœ˜0Kšœœœ1˜J——˜šœ˜Kšœ œ$˜7Kšœ œ#˜2Kšœœœ1˜J——Kšœ˜—Kšœœ/˜;Kšœœ'˜2Kšœ˜—K˜ Kšœœœ˜Kšœœ˜#šœœ˜šœ˜Kšœ ˜ Kšœ˜Kšœ"˜"K˜šœœœ˜#Kšœœ˜ Kšœœ˜2Kšœ˜ ——K˜ Kšœ˜—Kšœœœœ˜Kšœ˜—K˜Kšœ˜—…—0Μ