| 67802 |      1 | /*  Title:      Pure/System/tty_loop.scala
 | 
|  |      2 |     Author:     Makarius
 | 
|  |      3 | 
 | 
|  |      4 | Line-oriented TTY loop.
 | 
|  |      5 | */
 | 
|  |      6 | 
 | 
|  |      7 | package isabelle
 | 
|  |      8 | 
 | 
|  |      9 | 
 | 
| 67836 |     10 | import java.io.{IOException, Writer, Reader, InputStreamReader, BufferedReader}
 | 
| 67802 |     11 | 
 | 
|  |     12 | 
 | 
| 71713 |     13 | class TTY_Loop(
 | 
|  |     14 |   writer: Writer,
 | 
|  |     15 |   reader: Reader,
 | 
|  |     16 |   writer_lock: AnyRef = new Object)
 | 
| 67802 |     17 | {
 | 
| 71713 |     18 |   private val console_output = Future.thread[Unit]("console_output", uninterruptible = true) {
 | 
| 67802 |     19 |     try {
 | 
| 71713 |     20 |       val result = new StringBuilder(100)
 | 
| 67802 |     21 |       var finished = false
 | 
|  |     22 |       while (!finished) {
 | 
|  |     23 |         var c = -1
 | 
|  |     24 |         var done = false
 | 
| 71383 |     25 |         while (!done && (result.isEmpty || reader.ready)) {
 | 
| 67833 |     26 |           c = reader.read
 | 
| 67802 |     27 |           if (c >= 0) result.append(c.asInstanceOf[Char])
 | 
|  |     28 |           else done = true
 | 
|  |     29 |         }
 | 
| 71383 |     30 |         if (result.nonEmpty) {
 | 
| 67802 |     31 |           System.out.print(result.toString)
 | 
|  |     32 |           System.out.flush()
 | 
| 73367 |     33 |           result.clear()
 | 
| 67802 |     34 |         }
 | 
|  |     35 |         else {
 | 
| 67833 |     36 |           reader.close()
 | 
| 67802 |     37 |           finished = true
 | 
|  |     38 |         }
 | 
|  |     39 |       }
 | 
|  |     40 |     }
 | 
|  |     41 |     catch { case e: IOException => case Exn.Interrupt() => }
 | 
|  |     42 |   }
 | 
|  |     43 | 
 | 
| 71713 |     44 |   private val console_input = Future.thread[Unit]("console_input", uninterruptible = true) {
 | 
| 67802 |     45 |     val console_reader = new BufferedReader(new InputStreamReader(System.in))
 | 
| 71713 |     46 |     try {
 | 
|  |     47 |       var finished = false
 | 
|  |     48 |       while (!finished) {
 | 
|  |     49 |         console_reader.readLine() match {
 | 
|  |     50 |           case null =>
 | 
|  |     51 |             writer.close()
 | 
|  |     52 |             finished = true
 | 
|  |     53 |           case line =>
 | 
|  |     54 |             writer_lock.synchronized {
 | 
|  |     55 |               writer.write(line)
 | 
|  |     56 |               writer.write("\n")
 | 
|  |     57 |               writer.flush()
 | 
|  |     58 |             }
 | 
| 67802 |     59 |         }
 | 
|  |     60 |       }
 | 
|  |     61 |     }
 | 
| 71713 |     62 |     catch { case e: IOException => case Exn.Interrupt() => }
 | 
| 67802 |     63 |   }
 | 
|  |     64 | 
 | 
| 74141 |     65 |   def join(): Unit = { console_output.join; console_input.join }
 | 
| 67802 |     66 | 
 | 
| 73367 |     67 |   def cancel(): Unit = console_input.cancel()
 | 
| 67802 |     68 | }
 |