-- TEditTouchupImpl.mesa, last edit by Paxton on May 23, 1983 11:27 am <> DIRECTORY TEditTouchup, Process USING [Ticks, MsecToTicks, SetTimeout], Rope USING [ROPE], TEditDocument USING [SpinAndLock, TEditDocumentData, Unlock], TextNode USING [Ref], TEditLocks USING [Lock, LockRef, Unlock, WaitingForWrite]; TEditTouchupImpl: CEDAR MONITOR IMPORTS TEditDocument, TEditLocks, Process EXPORTS TEditTouchup = BEGIN fullUpdate: PUBLIC REF ANY _ $Update; refresh: PUBLIC REF ANY _ $Refresh; RefreshOver: PUBLIC ENTRY PROC = { ENABLE UNWIND => NULL; BROADCAST refreshOver }; LockAfterScroll: PUBLIC PROC [tdd: TEditDocument.TEditDocumentData, who: Rope.ROPE] RETURNS [ok: BOOL] = { RETURN [LockAfter[tdd, who, TRUE]] }; LockAfterRefresh: PUBLIC PROC [tdd: TEditDocument.TEditDocumentData, who: Rope.ROPE] RETURNS [ok: BOOL] = { RETURN [LockAfter[tdd, who, FALSE]] }; LockAfter: PROC [tdd: TEditDocument.TEditDocumentData, who: Rope.ROPE, scroll: BOOL] RETURNS [ok: BOOL] = { lock: TEditLocks.LockRef; doc: TextNode.Ref; WaitForRefresh: ENTRY PROC RETURNS [BOOL] = { ENABLE UNWIND => NULL; <> count: NAT _ 0; WHILE tdd.dirty AND (~scroll OR tdd.scroll=no) DO -- wait for refresh to finish IF (count _ count+1) > 5 THEN RETURN [FALSE]; -- don't wait more than 5 seconds IF TEditLocks.WaitingForWrite[lock] THEN RETURN [FALSE]; -- change of plans <> IF tdd.invisible THEN RETURN [FALSE]; <> WAIT refreshOver; -- let refresh complete first ENDLOOP; RETURN [TRUE] }; [] _ TEditDocument.SpinAndLock[tdd, "LockAfterRefresh1"]; -- lock it before read tdd.text doc _ tdd.text; TEditDocument.Unlock[tdd]; -- need to unlock it again so refresh can take place while we wait IF doc=NIL THEN RETURN [FALSE]; -- hasn't been initialized? lock _ TEditLocks.Lock[doc, who, read]; <> IF ~WaitForRefresh[] THEN { TEditLocks.Unlock[doc]; RETURN [FALSE] }; [] _ TEditDocument.SpinAndLock[tdd, "LockAfterRefresh2"]; IF tdd.text # doc THEN { -- it changed while we had tdd unlocked TEditLocks.Unlock[doc]; TEditDocument.Unlock[tdd]; RETURN [FALSE] }; RETURN [TRUE]; }; UnlockAfterRefresh: PUBLIC PROC [tdd: TEditDocument.TEditDocumentData] = { IF tdd.text#NIL THEN TEditLocks.Unlock[tdd.text]; TEditDocument.Unlock[tdd] }; refreshOver: CONDITION; aLittleWhile: Process.Ticks = Process.MsecToTicks[1000]; TRUSTED {Process.SetTimeout[@refreshOver, aLittleWhile]}; -- recheck for refresh over every second END.