<!--
  - Author:
  -   Leif Kornstaedt <kornstae@ps.uni-sb.de>
  -
  - Copyright:
  -   Leif Kornstaedt, 1998-2003
  -
  - Last change:
  -   $Date$ by $Author$
  -   $Revision$
  -
  - This file is part of Mozart, an implementation of Oz 3:
  -   http://www.mozart-oz.org
  -
  - See the file "LICENSE" or
  -   http://www.mozart-oz.org/LICENSE.html
  - for information on usage and redistribution
  - of this file, and for a DISCLAIMER OF ALL
  - WARRANTIES.
  -
  -->

<Appendix id="appendix.narrator">
  <Title/Narrators and Listeners/
  <P>
    This appendix documents some supporting classes required to
    observe a running compiler.  These classes implement a general
    producer&emdash;consumer pattern for the status of a running
    computation and the error messages generated by it.  They can
    be used independently of the compiler (actually, they are also
    used by the <File/ozdoc/ tool that generated this documentation).
  <P>
    A <Def/narrator/, presented in <Ptr to="appendix.narrator.narrator">,
    is a producer of status and error messages.  Conversely, a <Def/Listener/,
    presented in <Ptr to="appendix.narrator.listener">, is a consumer of such
    messages.  Each listener is connected to exactly one narrator; every
    narrator may have a number of listeners (you can observe this if you
    open compiler panels in the Oz Programming Interface).
  <P>
    Typically, the result (from, say, a compilation) one will want to
    programmatically check for is success or failure, and the list of
    error messages generated.  An <Def/error listener/ provides easy
    access to precisely that information, and is presented in <Ptr
    to="appendix.narrator.errorlistener">.
  <Section id="appendix.narrator.narrator">
    <Title/The <<Narrator>> Module/
    <P>
      The <<Narrator>> module, located at <File>x-oz://system/Narrator</File>,
      exports a class <<Narrator.'class'>> which is the superclass of all
      narrators.  It manages a number of connected listeners (which are
      simply ports for the purpose of narrators) and provides for broadcasting
      messages to all registered listeners.  The constructor returns a
      <Def/private narrator/ instance, used by the running computation to
      send well-defined status messages.  Both of these classes are described
      in the following.
    <SubSection class=unnumbered>
      <Title/The class <<Narrator.'class'>>/
      <Para class=apropos><Title/Methods/
	<List>
	  <Entry><<init(??{PrivateNarratorO})>>
	  <Item>
	    initializes a narrator that initially has no listeners attached,
	    and returns the corresponding private narrator.
	  <Entry><<register(?+{Port})>>
	  <Item>
	    registers a new listener ?{Port}.  All subsequently told
	    messages will be forwarded to ?{Port}.
	  <Entry><<newListener(?+{Port})>>
	  <Item>
	    is invoked on every new listener ?{Port} that is registered.
	    The default action is a no-op; subclasses may override this
	    for example to provide the new Listener with a summary of
	    the current state (as a batch of messages).
	  <Entry><<unregister(?+{Port})>>
	  <Item>
	    unregisters a listener ?{Port}.  No more messages will
	    subsequently be forwarded to ?{Port}.
	  <Entry><<tell(?_{X})>>
	  <Item>
	    broadcasts the message&nbsp;?{X} to all registered listeners.
        </List>
    <SubSection class=unnumbered>
      <Title/Private Narrators/
      <Para class=apropos><Title/Methods/
	<List>
	  <Entry><<setLogPhases(?+{B})>>
	  <Item>
	    determines whether messages about phases of the underlying
	    computations should be broadcasted to listeners (if ?{B} is
	    <<true>>) or not (if ?{B} is <<false>>).  The default is <<false>>.
	  <Entry><<setMaxNumberOfErrors(?+{I})>>
	  <Item>
	    sets the number of error messages to report before interrupting
	    the underlying computation with a <<tooManyErrors>> exception.
	    The default is <<17>>.  If ?{I} is less than or equal to zero,
	    infinitely many errors are acceptable.
	  <Entry><<tell(?_{X})>>
	  <Item>
	    broadcasts the message&nbsp;?{X} to all registered listeners.
	  <Entry><<startBatch()>>
	  <Item>
	    resets internal state (in particular, the error count).
	  <Entry><<startPhase(?+{V})>>
	  <Item>
	    broadcasts an <<info(...)>> message to all registered listeners,
	    to the effect that phase&nbsp;<<V>> has started.
	  <Entry><<startSubPhase(?+{V})>>
	  <Item>
	    broadcasts an <<info(...)>> message to all registered listeners,
	    to the effect that sub-phase&nbsp;<<V>> has started.
	  <Entry><<endBatch(?+{A})>>
	  <Item>
	    broadcasts messages to all registered listeners about the outcome
	    of the underlying computation.  ?{A} can be one of <<accepted>>,
	    <<rejected>>, <<aborted>>, <<crashed>>, or <<interrupted>>.
	    For any but <<accepted>> or <<interrupted>>, an <<attention>>
	    message is broadcast.  Causes an <<info(...)>> message to be
	    broadcast.
	  <Entry><<error(coord: ?+{Coord} &lt;= unit
      kind:  ?+{KindV} &lt;= unit
      msg:   ?+{MsgV}  &lt;= unit
      items: ?+{Ts}    &lt;= unit
      abort: ?+{B}     &lt;= true)>>
	  <Item>
	    broadcasts a <<message(error(...) ...)>>.  Raises <<tooManyErrors>>
	    if the maximum allowed error count is exceeded.
	  <Entry><<warn(coord: ?+{Coord} &lt;= unit
     kind:  ?+{KindV} &lt;= unit
     msg:   ?+{MsgV}  &lt;= unit
     items: ?+{Ts}    &lt;= unit)>>
	  <Item>
	    broadcasts a <<message(warn(...) ...)>>.
	  <Entry><<hasSeenError(??{B})>>
	  <Item>
	    returns <<true>> iff an error message has been broadcast.
	</List>      
  <Section id="appendix.narrator.listener">
    <Title/The <<Listener>> Module/
    <P>
      The <<Listener>> module, located at <File>x-oz://system/Listener</File>,
      exports the class <<Listener.'class'>> with the following methods.
    <Para class=apropos><Title/Methods/
      <List>
	<Entry><<init(?+{NarratorO} ?+{ServeL})>>
	<Item>
	  initializes a listener with a narrator and the label of a
	  unary method.  The listener creates a port, registers this with
	  ?_{NarratorO}, and creates a thread in which the ?_{ServeL} method
	  is applied to the port's stream.
	<Entry><<close()>>
	<Item>
	  undoes all effects of the <<init>> method:  The server thread
	  is terminated and the listener's port is unregistered.
	<Entry><<getNarrator(??{NarratorO})>>
	<Item>
	  returns the narrator with which the listener's port is currently
	  registered.
	<Entry><<getPort(??{Port})>>
	<Item>
	  returns the associated port.
      </List>
  <Section id="appendix.narrator.errorlistener">
    <Title/The <<ErrorListener>> Module/
    <P>
      The <<ErrorListener>> module, located at <File
      >x-oz://system/ErrorListener</File>, exports the class
      <<ErrorListener.'class'>> with the following methods.
    <Para class=apropos><Title/Methods/
      <List>
	<Entry>
	  <<init(?+{NarratorO} ?+{ServeOneL} &lt;= unit ??{VerboseL} &lt;= false)>>
	<Item>
	  initializes an error listener.  If ?{ServeOneL} is different from
	  <<unit>>, it should be the label of a method of a subclass.  If
	  an unrecognized message is received from the narrator, the method
	  is invoked with the message as its single parameter.  ?{VerboseL}
	  can be one of <<true>> (print all received messages to standard
	  error), <<false>> (print none of the messages), and <<auto>> (print
	  all messages if some error message is among them).
	<Entry><<reset()>>
	<Item>
	  is a no-op, intended to be overriden by derived classes.  Invoked
	  when a <<close()>> message is received.
	<Entry><<setVerbosity(?+{L})>>
	<Item>
	  sets the verbosity to ?{L}, which can be one of <<true>> (print all
	  received messages to standard error), <<false>> (print none of the
	  messages), and <<auto>> (print all messages if some error message
	  is among them).
	<Entry><<hasErrors(??{B})>>
	<Item>
	  returns <<true>> iff some error message was received since the
	  last <<close()>> message.
	<Entry><<isActive(??{B})>>
	<Item>
	  returns <<true>> iff some error or warning message has been received
	  since the last <<close()>> message.
	<Entry><<getVS(??{V})>>
	<Item>
	  returns the history of messages as a virtual string.
	<Entry><<getMessages(??{Xs})>>
	<Item>
	  returns the history of messages as a list.
	<Entry><<formatMessages(?+{Xs} ??{V})>>
	<Item>
	  takes a list of messages&nbsp;?{Xs} and returns them as a virtual
	  string.
      </List>
</Appendix>
