diff --git a/app/models/Client.scala b/app/models/Client.scala index ffa995b..34b399e 100644 --- a/app/models/Client.scala +++ b/app/models/Client.scala @@ -22,5 +22,5 @@ class Client(val path: File) { process } - def destroy(): Unit = if (process == null) process.destroy + def destroy(): Unit = if (process != null) process.destroy } diff --git a/app/models/ProgramThread.scala b/app/models/ProgramThread.scala new file mode 100644 index 0000000..861681e --- /dev/null +++ b/app/models/ProgramThread.scala @@ -0,0 +1,35 @@ +package models + +import java.io.{InputStreamReader, BufferedReader} + +class ProgramThread(builder: ProcessBuilder) extends Thread { + private var process: Process = null + private val stringBuilder = new StringBuilder() + private var callback: Option[String => Unit] = None + + def setCallback(acb: String => Unit) = callback = Some(acb) + + override def run() = { + process = builder.start + val streamReader = new InputStreamReader(process.getInputStream) + val bufferedReader = new BufferedReader(streamReader, 1) + var line:String = null + + while({line = bufferedReader.readLine; line != null}){ + stringBuilder.append(line) + stringBuilder.append("\n") + callback.map(_(line)) + } + bufferedReader.close + + process.waitFor + } + + def waitFor: Unit = if (process != null) process.waitFor + + def forceExit: Unit = if (process != null) process.destroy + + def getOutput: String = stringBuilder.toString + + def exitValue: Int = process.exitValue +} diff --git a/app/models/Server.scala b/app/models/Server.scala index 5e4547e..6ec14a6 100644 --- a/app/models/Server.scala +++ b/app/models/Server.scala @@ -1,6 +1,6 @@ package models -import java.io.{File, InputStreamReader, BufferedReader} +import java.io.{File} import play.Logger /** @@ -20,40 +20,33 @@ extends Thread { override def run() = { val builder = new ProcessBuilder(SERVER_PROGRAM.toString, "-p", port.toString, "-t", ROUND_TIMEOUT.toString) - val stringBuilder = new StringBuilder() builder redirectErrorStream true builder directory SERVER_PROGRAM.getParentFile try { - val proc = builder.start - val streamReader = new InputStreamReader(proc.getInputStream) - val bufferedReader = new BufferedReader(streamReader, 1) - var line:String = null - var char: Int = 0 - - challenger.run(port) - - while({line = bufferedReader.readLine; line != null}){ - stringBuilder.append(line) - stringBuilder.append("\n") + val pt = new ProgramThread(builder) + pt.setCallback { line => + if (line == "Waiting connections ... ") { + println("invoking") + challenger.run(port) + Logger.info("challenger's client is started") + } if (line == "One player is registered. Waiting for other player ...") { opponent.run(port) Logger.info("opponent's client is started") } } - bufferedReader.close - - val result = stringBuilder.toString - proc.waitFor + pt.start + pt.join challenger.destroy() opponent.destroy() - if (proc.exitValue == 0) { - BattleRecorder.report(NormalExit(battle, result)) + if (pt.exitValue == 0) { + BattleRecorder.report(NormalExit(battle, pt.getOutput)) } else { - BattleRecorder.report(AbnormalExit(battle, result)) + BattleRecorder.report(AbnormalExit(battle, pt.getOutput)) } } catch { case e: Exception =>