DIRECTORY EditNotify, TextNode; EditNotifyImpl: CEDAR MONITOR IMPORTS TextNode EXPORTS EditNotify = BEGIN OPEN EditNotify; NotifyList: TYPE = REF NotifyListBody; NotifyListBody: TYPE = RECORD [ next: NotifyList, action: EditNotifyProc, changeSet: ChangeSet ]; NotifyArray: TYPE = ARRAY Priority OF NotifyList; beforeProcs: NotifyArray; afterProcs: NotifyArray; unlocked: CONDITION; lockCount: INTEGER _ 0; Lock: ENTRY PROC = { lockCount _ lockCount+1 }; Unlock: ENTRY PROC = { IF (lockCount _ lockCount-1) <= 0 THEN { lockCount _ 0; BROADCAST unlocked }}; AddNotifyProc: PUBLIC ENTRY PROC [ proc: EditNotifyProc, time: When _ after, priority: Priority _ normal, changeSet: ChangeSet _ defaultChangeSet] = { ENABLE UNWIND => NULL; WHILE lockCount > 0 DO WAIT unlocked; ENDLOOP; RemoveNotify[proc, time]; IF time=before THEN beforeProcs[priority] _ TextNode.pZone.NEW[NotifyListBody _ [beforeProcs[priority], proc, changeSet]] ELSE afterProcs[priority] _ TextNode.pZone.NEW[NotifyListBody _ [afterProcs[priority], proc, changeSet]]}; RemoveNotifyProc: PUBLIC ENTRY PROC [proc: EditNotifyProc, time: When _ after] = { ENABLE UNWIND => NULL; WHILE lockCount > 0 DO WAIT unlocked; ENDLOOP; RemoveNotify[proc, time] }; RemoveNotify: PROC [proc: EditNotifyProc, time: When _ after] = { FOR p:Priority IN Priority DO prev: NotifyList _ NIL; list: NotifyList _ IF time=before THEN beforeProcs[p] ELSE afterProcs[p]; IF list=NIL THEN LOOP; UNTIL list=NIL DO IF list.action = proc THEN EXIT; prev _ list; list _ list.next; REPEAT FINISHED => LOOP; -- proc not found on this list ENDLOOP; IF prev#NIL THEN prev.next _ list.next ELSE IF time=before THEN beforeProcs[p] _ list.next ELSE afterProcs[p] _ list.next; ENDLOOP }; Notify: PUBLIC PROC [change: REF READONLY Change, time: When] = { ENABLE UNWIND => Unlock[]; kind: ChangeType; IF change=NIL THEN RETURN; kind _ change.kind; Lock[]; FOR p:Priority IN Priority DO FOR lst:NotifyList _ GetList[p,time], lst.next UNTIL lst=NIL DO IF lst.changeSet[kind] THEN lst.action[change]; ENDLOOP; ENDLOOP; Unlock[] }; GetList: PROC [p:Priority, time:When] RETURNS [NotifyList] = INLINE { RETURN [IF time=before THEN beforeProcs[p] ELSE afterProcs[p]] }; Start: PUBLIC PROC = { }; END. ô-- EditNotifyImpl.mesa -- written by Bill Paxton, March 1981 -- last edit by Bill Paxton, October 18, 1982 10:42 am -- **** Notification Operations **** -- remove proc from list of notification procedures -- call notification procedures Êš˜JšÏc™Jš%™%Jš7™7J˜JšÏk ˜ J˜ J˜ J˜šœž ˜Jšžœ ˜Jšžœ ˜—Jšž˜Jšžœ ˜J˜Jšœ žœžœ˜&šœžœžœ˜J˜J˜J˜—Jšœ žœžœ žœ ˜1J˜J˜J˜Jš$™$J˜Jšœ ž œ˜J˜Jšœ žœ˜J˜JšÏnœžœžœ˜/J˜šŸœžœžœ˜Jšžœ žœž œ ˜N—J˜šŸ œžœžœžœ˜"J˜J˜J˜J˜,Jšžœžœžœ˜Jšžœžœžœ žœ˜.J˜šžœ ž˜˜Jšœžœ;˜M——šžœ˜Jšœžœ<˜NJ˜——šŸœžœžœž˜#J˜.Jš3™3Jšžœžœžœ˜Jšžœžœžœ žœ˜.J˜J˜—šŸ œž˜J˜.šžœ žœ ž˜Jšœžœ˜šœžœ žœ˜5Jšžœ˜—Jšžœžœžœžœ˜šžœžœž˜Jšžœžœžœ˜ J˜Jšžœžœžœ˜7Jšžœ˜—Jšžœžœžœ˜&Jšžœžœ žœ˜3Jšžœ˜Jšžœ˜ J˜——š Ÿœžœžœ žœžœ˜AJš™Jšžœžœ ˜J˜Jšžœžœžœžœ˜J˜J˜šžœ žœ ž˜šžœ,žœžœž˜?Jšžœžœ˜/Jšžœ˜—Jšžœ˜—šœ ˜ J˜——šŸœžœžœž˜CJš œžœžœ žœžœ˜CJ˜—šŸœžœžœ˜J˜J˜—Jšžœ˜J˜—…—º H