% $Id: Lift.oz,v 1.3 2007/11/14 01:45:50 leavens Exp leavens $ % Figure 5.12 of CTM \insert 'NewPortObject.oz' declare fun {ScheduleLast L N} if L\=nil andthen {List.last L}==N then L else {Append L [N]} end end fun {Lift Num Init Cid Floors} {NewPortObject Init fun {$ state(Pos Sched Moving) Msg} case Msg of call(N) then {Browse 'Lift '#Num#' needed at floor '#N} if N==Pos andthen {Not Moving} then {Wait {Send Floors.Pos arrive($)}} state(Pos Sched false) else Sched2 in Sched2={ScheduleLast Sched N} if {Not Moving} then {Send Cid step(N)} end state(Pos Sched2 true) end [] 'at'(NewPos) then {Browse 'Lift '#Num#' at floor '#NewPos} case Sched of S|Sched2 then if NewPos==S then {Wait {Send Floors.S arrive($)}} if Sched2==nil then state(NewPos nil false) else {Send Cid step(Sched2.1)} state(NewPos Sched2 true) end else {Send Cid step(S)} state(NewPos Sched Moving) end end end end} end