DIRECTORY
BasicTime, IO, IODefs, Menus, MessageWindow, Process, Rope, ViewerClasses, ViewerEvents, ViewerIO, ViewerOps;
IODefsImpl:
CEDAR
MONITOR
IMPORTS IO, Menus, MessageWindow, Process, ViewerEvents, ViewerIO, ViewerOps
EXPORTS IODefs =
BEGIN
log: PUBLIC IO.STREAM ← NIL;
WriteString:
PUBLIC
PROC [s: Rope.
ROPE] =
{Log[].PutRope[s ! IO.Error => {ResetLog[]; RETRY}]};
WriteLine:
PUBLIC
PROC [s: Rope.
ROPE] =
{Log[].PutF["%g\n", IO.rope[s] ! IO.Error => {ResetLog[]; RETRY}]};
WriteChar:
PUBLIC
PROC [c:
CHARACTER] =
{Log[].PutChar[c ! IO.Error => {ResetLog[]; RETRY}]};
WriteDecimal:
PUBLIC
PROC [n:
INT] =
{Log[].PutF["%g", IO.int[n] ! IO.Error => {ResetLog[]; RETRY}]};
WriteReal:
PUBLIC
PROC [r:
REAL] =
{Log[].PutF["%g", IO.real[r] ! IO.Error => {ResetLog[]; RETRY}]};
PrintTime:
PUBLIC
PROC [msg: Rope.
ROPE ←
NIL] =
{Log[].PutF["%g %g\n", IO.rope[msg], IO.time[] ! IO.Error => {ResetLog[]; RETRY}]};
PostIt:
PUBLIC
ENTRY
PROC [s: Rope.
ROPE] =
{ENABLE UNWIND => NULL; postee ← s; CheckStop[]};
Log:
PROC
RETURNS [
IO.
STREAM ] =
BEGIN
WHILE log =
NIL
DO
menuEntry: Menus.MenuEntry = Menus.CreateEntry[name: "STOP!", proc: NoticeStop, guarded: TRUE];
viewer: ViewerClasses.Viewer;
doStop ← FALSE;
log ← ViewerIO.CreateViewerStreams[name: "MPC Log", backingFile: "MPC.log"].out;
viewer ← ViewerIO.GetViewerFromStream[log];
[] ← Menus.InsertMenuEntry[menu: viewer.menu, entry: menuEntry];
ViewerOps.PaintViewer[viewer, menu];
[] ← ViewerEvents.RegisterEventProc[proc: CloseOutputStream, event: destroy, filter: viewer];
log.PutF["MPC.log of %g...\n\n", IO.time[]];
ENDLOOP;
CheckStop[];
RETURN[log];
END;
doStop: BOOL ← FALSE;
CheckStop:
PROC = {
IF doStop
THEN {doStop ←
FALSE;
ERROR
ABORTED}};
NoticeStop:
PROC [parent:
REF
ANY, clientData:
REF
ANY ←
NIL,
mouseButton: Menus.MouseButton ← red, shift, control: BOOL ← FALSE] -- Menus.ClickProc -- =
{doStop ← TRUE};
CloseOutputStream:
PROC [viewer: ViewerClasses.Viewer, event: ViewerEvents.ViewerEvent, before:
BOOL]
RETURNS [abort:
BOOL ←
FALSE]
-- ViewerEvents.EventProc -- =
ResetLog: PROC = {IF log # NIL THEN log.Close[ ! IO.Error => CONTINUE ]; log ← NIL};
postee: Rope.ROPE ← NIL;
posteeReady: CONDITION;
Poster:
ENTRY
PROC =
BEGIN
ENABLE UNWIND => NULL;
lastPostee: Rope.ROPE ← NIL;
DO
IF log#NIL THEN log.Flush[ ! IO.Error => CONTINUE ];
IF postee #
NIL
OR lastPostee #
NIL
THEN
BEGIN
MessageWindow.Append[message: postee, clearFirst: TRUE];
lastPostee ← postee;
postee ← NIL;
END;
WAIT posteeReady;
ENDLOOP;
END;
TRUSTED
BEGIN
Process.InitializeCondition[condition: @posteeReady, ticks: Process.SecondsToTicks[2]];
Process.Detach[FORK Poster[]];
END;
END.