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]; IF oldHistory=NIL THEN RETURN[LIST[historyPt]]; 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 IF action[ih.first.t, ih.first.v] THEN RETURN[TRUE]; 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. LScheduleImpl.mesa Copyright Σ 1986, 1987 by Xerox Corporation. All rights reserved. Christian LeCocq January 28, 1987 6:00:12 pm PST Bertrand Serlet April 15, 1987 4:25:51 pm PDT Christian Le Cocq August 20, 1987 6:02:45 pm PDT 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 Κ˜šœ™IcodešœB™BK™0K™-K™0J™J™—šΟk ˜ Jšœ ˜ J˜—š Οb œœœœœ˜=Jšœ œ ˜'—head™K™šΟn œ œ œœ˜MKšœ œ ˜K˜K˜—šŸ œ œ˜/Kšœ ˜ šœ œ˜Kšœ ˜ Kšœ˜Kšœ œ˜ Kšœ˜—K˜K˜—š Ÿ œœœ!œœ˜aKšœ˜Kšœ˜Kš œ œœœœ ˜/Kšœ˜šœ#œœ˜5šœœΟc8˜PKšœ 2˜HKšœ œ˜Kš œœœœœœ˜\Kšœ˜K˜—Kšœ ˜ Kšœ ˜ Kšœ˜—Kšœ œ ˜Kš œœœœœœ˜\K˜K˜—šŸœ œœ˜[Kšœ˜šœ#œ œ˜:šœœ˜Kšœ˜Kšœ˜K˜—Kšœ˜—K˜K˜—šŸœ œœ™[Kšœ™šœ#œ œ™:Kšœ™šœœ™Kšœœ™Kšœ™Kšœ™Kšœ™K™—Kšœ™—K™K™—šŸœ œœ ˜FKšœ˜K˜K˜—šŸœ œœ˜Xšœ œœ˜2Kšœœœ ˜)Kšœ˜—K˜K˜—šŸœ œœ ˜Ešœ œ œ ˜>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š œœœ œœœ˜MKšœ˜—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šœ œ-˜