DIRECTORY EditNotify; EditNotifyImpl: CEDAR MONITOR 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] _ NEW[NotifyListBody _ [beforeProcs[priority], proc, changeSet]] ELSE afterProcs[priority] _ 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] = { RETURN [IF time=before THEN beforeProcs[p] ELSE afterProcs[p]] }; END. |EditNotifyImpl.mesa Copyright Σ 1985, 1986 by Xerox Corporation. All rights reserved. written by Bill Paxton, March 1981 last edit by Bill Paxton, October 18, 1982 10:42 am Doug Wyatt, March 3, 1985 4:39:51 pm PST Michael Plass, March 29, 1985 2:31:39 pm PST **** Notification Operations **** remove proc from list of notification procedures call notification procedures Κ˜codešœ™KšœB™BKšœ"™"Kšœ4™4K™(K™,—K˜šΟk ˜ K˜ —K˜KšΠblœœ˜Kšœ ˜Kšœœœ ˜K˜Kšœ œœ˜&šœœœ˜K˜K˜K˜K˜—Kšœ œœ œ ˜1K˜K˜K˜Kšœ!™!K˜Kšœ  œ˜K˜Kšœ œ˜K˜KšΟnœœœ˜/K˜šŸœœœ˜Kšœ œ œ ˜N—K˜šŸ œœœœ˜"K˜K˜K˜K˜,Kšœœœ˜Kšœœœ œ˜.K˜šœ ˜˜Kšœ;˜>——šœ˜Kšœ<˜?K˜——šŸœœœ˜#K˜.Kšœ0™0Kšœœœ˜Kšœœœ œ˜.K˜K˜—šŸ œ˜K˜.šœ œ ˜Kšœœ˜šœœ œ˜5Kšœ˜—Kšœœœœ˜šœœ˜Kšœœœ˜ K˜KšœœœΟc˜7Kšœ˜—Kšœœœ˜&Kšœœ œ˜3Kšœ˜Kšœ˜ K˜——š Ÿœœœ œœ˜AKšœ™Kšœœ ˜K˜Kšœœœœ˜K˜K˜šœ œ ˜šœ,œœ˜?Kšœœ˜/Kšœ˜—Kšœ˜—šœ ˜ K˜——šŸœœœ˜=Kš œœœ œœ˜CK˜—Kšœ˜K˜—…—` i