% $Id: NewPrintServer.oz,v 1.2 2008/11/17 19:57:34 leavens Exp leavens $ \insert 'NewPortObjectDebug.oz' declare %% This function models a print server (or spooler) with two kinds of clients: %% users and printers. The users send the messages: %% send( ) % the second field is undetermined %% cancel() %% status( ) % the second field is undetermined %% and the printers send the message %% nextToPrint() % the field is undetermined %% fun {NewPrintServer} {NewPortObject % NewPortObjectDebug % for debugging local End in state(nextJob: 0 % the next job number queue: End % the front of the queue (a list of pairs) queueEnd: End % pointer to the end of the queue qsize: 0) % the current size of the queue end fun {$ state(nextJob: JN queue: Q queueEnd: QE qsize: N) Msg} case Msg of send(DocText JobNumVar) then local Z in QE=(DocText#JN)|Z JobNumVar=JN % we forgot this originally in class state(nextJob: JN+1 queue: Q queueEnd:Z qsize: N+1) end [] cancel(JobNum) then local NewQ#NewN = {DeleteFrom Q N JobNum QE} in state(nextJob: JN queue: NewQ queueEnd:QE qsize: NewN) end [] status(JobNum StatusVar) then StatusVar={DetermineStatus Q N JobNum} state(nextJob: JN queue: Q queueEnd: QE qsize: N) [] nextToPrint(DocTextVar) then if N == 0 then DocTextVar="" state(nextJob: JN queue: Q queueEnd: QE qsize: N) else case Q of DT#_|Rest then DocTextVar=DT state(nextJob: JN queue: Rest queueEnd:QE qsize: N-1) end end end end } end % DeleteFrom: }: #> fun {DeleteFrom Q OrigN JobNum QE} fun {Help Q N I} if I > OrigN then Q#N else case Q of DT#JN|Rest then if JN == JobNum then {Help Rest N-1 I+1} else % Note how we have to pattern match the result of Help local NewEnd#NewN = {Help Rest N I+1} in ((DT#JN)|NewEnd)#NewN end end end end end in {Help Q OrigN 1} end %% DetermineStatus: }: > fun {DetermineStatus Q N JobNum} if N =< 0 then notFound else case Q of (_#JN)|Rest then if JN==JobNum then queued else {DetermineStatus Rest N-1 JobNum} end end end end