DIRECTORY Schedule; ScheduleImpl: CEDAR MONITOR LOCKS agenda USING agenda: Agenda EXPORTS Schedule ~ BEGIN OPEN Schedule; CreateHistory: PUBLIC PROC [t: ps, v: REAL] RETURNS [newHistory: History] ~ { newHistory _ LIST[[t, v]]; }; KillHistory: PUBLIC PROC [history: History] ~ { h: History; UNTIL history=NIL DO h _ history; history _ history.rest; h.rest _ NIL; ENDLOOP; }; AddToHistory: PUBLIC PROC [oldHistory: History, t: ps, v: REAL] RETURNS [newHistory: History] ~ { last, prev: History; historyPt: HistoryPt _ [t, v]; newHistory _ oldHistory; FOR ih: History _ oldHistory, ih.rest UNTIL ih=NIL DO IF ih.first.t>=t THEN { --if t occurs before the end of the current history then ih.first _ historyPt; -- change the present and delete the "old future". ih.rest _ NIL; IF prev#NIL THEN IF prev.first.v=last.first.v AND prev.first.v=v THEN prev.rest _ last.rest; RETURN; }; prev _ last; last _ ih; ENDLOOP; last.rest _ LIST[historyPt]; IF prev#NIL THEN IF prev.first.v=last.first.v AND prev.first.v=v THEN prev.rest _ last.rest; }; ForgetBeginings: PUBLIC PROC [oldHistory: History, t: ps] RETURNS [newHistory: History] ~ { newHistory _ oldHistory; FOR ih: History _ oldHistory, ih.rest UNTIL ih.rest=NIL DO IF ih.rest.first.t>t THEN { newHistory _ ih; RETURN; }; ENDLOOP; }; FirstTimeOfHistory: PUBLIC PROC [history: History] RETURNS [t: ps] ~ { t _ history.first.t }; NextTimeOfHistory: PUBLIC PROC [history: History, t: ps] RETURNS [tnext: ps _ -1e30] ~ { FOR ih: History _ history, ih.rest UNTIL ih=NIL DO IF ih.first.t>=t THEN RETURN[ih.first.t]; ENDLOOP; }; LastTimeOfHistory: PUBLIC PROC [history: History] RETURNS [t: ps] ~ { FOR ih: History _ history, ih.rest UNTIL ih.rest=NIL DO REPEAT FINISHED => t _ ih.first.t; ENDLOOP; }; LastValueOfHistory: PUBLIC PROC [history: History] RETURNS [v: REAL] ~ { FOR ih: History _ history, ih.rest UNTIL ih.rest=NIL DO REPEAT FINISHED => v _ ih.first.v; ENDLOOP; }; VFromHistory: PUBLIC PROC [history: History, t: ps] RETURNS [v: REAL] ~ { t0: ps; v0: REAL; IF t < history.first.t THEN ERROR; -- Why should you return to the past ? IF t=history.first.t THEN RETURN[history.first.v]; FOR ih: History _ history, ih.rest UNTIL ih=NIL DO IF t<=ih.first.t THEN { v _ v0 + (ih.first.v - v0)*(t-t0) /(ih.first.t - t0); RETURN; }; v0 _ ih.first.v; t0 _ ih.first.t; REPEAT FINISHED => v _ v0; ENDLOOP; }; EnumerateHistory: PUBLIC PROC [history: History, from, to: ps, action: HistoryProc] RETURNS [invalidEnumeration: BOOL _ FALSE] ~ { quit: BOOLEAN _ FALSE; FOR ih: History _ history, ih.rest UNTIL ih=NIL OR quit OR ih.first.t>to DO IF ih.first.t>=from THEN quit _ action[ih.first.t, ih.first.v]; ENDLOOP; }; Schedule: PUBLIC PROC [hList: LIST OF History] RETURNS [lt: LIST OF ps] ~ { t: ps; h: LIST OF History; endlt: LIST OF ps; finished: BOOLEAN _ FALSE; endlt _ lt _ LIST[-1e30]; UNTIL finished DO finished _ TRUE; t _ 1e30; FOR ih: LIST OF History _ hList, ih.rest UNTIL ih=NIL DO IF ih.first#NIL THEN { finished _ FALSE; IF t>=ih.first.first.t THEN { t _ ih.first.first.t; h _ ih; }; }; ENDLOOP; IF ~finished THEN { IF endlt.first#t THEN { endlt.rest _ LIST[t]; endlt _ endlt.rest; }; h.first _ h.first.rest; }; ENDLOOP; lt _ lt.rest; }; CreateAgenda: PUBLIC PROC [execute: ExecuteProc, data: REF ANY] RETURNS [newAgenda: Agenda] ~ { newAgenda _ NEW[AgendaRec _ [execute: execute, data: data]]; }; KillAgenda: PUBLIC PROC [agenda: Agenda] ~ { aList: LIST OF Event; UNTIL agenda.list=NIL DO agenda.list.first.ref _ NIL; aList _ agenda.list; agenda.list _ agenda.list.rest; aList.rest _ NIL; ENDLOOP; agenda.data _ NIL; }; InsertInAgenda: PUBLIC ENTRY PROC [agenda: Agenda, ref: REF ANY, t: ps] ~ { ENABLE UNWIND => NULL; cal: LIST OF Event; IF t=-1e30 THEN RETURN; IF agenda=NIL THEN ERROR; --don't try to insert in an empty ref IF agenda.list=NIL THEN { agenda.list _ LIST[[t, ref]]; agenda.nbOfEvents _ 1; RETURN }; IF t NULL; aList: LIST OF Event _ agenda.list; aList.first.ref _ NIL; agenda.list _ agenda.list.rest; aList.rest _ NIL; agenda.nbOfEvents _ agenda.nbOfEvents-1; }; ExecuteAgenda: PUBLIC PROC [agenda: Agenda] RETURNS [lastTime: ps] ~ { ENABLE UNWIND => NULL; WHILE agenda.list#NIL DO agenda.execute[agenda.list.first.ref, agenda.list.first.t, agenda.data]; lastTime _ agenda.list.first.t; DeleteEvent[agenda]; ENDLOOP; }; END. θScheduleImpl.mesa Copyright c 1986 by Xerox Corporation. All rights reserved. Christian LeCocq January 28, 1987 6:00:12 pm PST History management package ForgetBeginings: PUBLIC PROC [oldHistory: History, t: ps] RETURNS [newHistory: History] ~ { newHistory _ oldHistory; FOR ih: History _ oldHistory, ih.rest UNTIL ih.rest=NIL DO newHistory _ ih; IF ih.rest.first.t>t THEN { v: REAL _ VFromHistory[ih, t]; ih.first.v _ v; ih.first.t _ t; RETURN; }; ENDLOOP; }; Agenda Gestion Κe˜šœ™Icodešœ Οmœ1™Kšžœ˜Kšžœ˜—K˜K˜—š œž œžœžœ˜Hšžœ žœ žœž ˜>Kšžœ˜Kšžœ˜—K˜K˜—š Πbn œžœžœžœžœ˜IK˜Kšœžœ˜ Kšžœžœžœ‘&˜IKšžœžœžœ˜2šžœ žœžœž˜2šžœžœ˜Kšœ5˜5Kšžœ˜Kšœ˜—Kšœ˜Kšœ˜Kšž˜Kšžœ ˜Kšžœ˜—K˜K˜—š  œž œ7žœžœžœ˜‚Kšœžœžœ˜š žœ žœžœžœžœž˜KKšžœžœ'˜?Kšžœ˜—K˜K˜—š œž œ žœžœ žœžœžœ˜KKšœ˜Kšœžœžœ ˜Kšœžœžœ˜Kšœ žœžœ˜Kšœ žœ˜šžœ ž˜Kšœ žœ˜Kšœ ˜ š žœžœžœžœžœž˜8šžœ žœžœ˜Kšœ žœ˜šžœžœ˜Kšœ˜K˜K˜—K˜—Kšžœ˜—šžœ žœ˜šžœžœ˜Kšœ žœ˜Kšœ˜K˜—K˜K˜——Kšžœ˜K˜ K˜K˜——šœ™š  ’œž œžœžœžœ˜_Kšœ žœ-˜