package wow.doge.mygame.utils import java.io.ByteArrayOutputStream import java.io.OutputStream import java.io.PrintStream import scalafx.application.Platform import scalafx.scene.control.TextArea trait ConsoleStreamable[T] { def println(inst: T, text: String): Unit def print(inst: T, text: String): Unit } class GenericConsoleStream[T]( outputStream: OutputStream, val config: GenericConsoleStream.Config = GenericConsoleStream.Config.default, // TODO make this atomic ? private var _streamable: Option[T] = None )(implicit cs: ConsoleStreamable[T] ) extends PrintStream(outputStream, true) { private val defaultOut = System.out def printToStreamable(stble: Option[T], text: String) = stble.foreach(s => cs.println(s, text)) override def println(text: String): Unit = if (config.exclusive) printToStreamable(_streamable, text) else { defaultOut.println(text) printToStreamable(_streamable, text) } override def print(text: String): Unit = if (config.exclusive) printToStreamable(_streamable, text) else { defaultOut.println(text) printToStreamable(_streamable, text) } def :=(s: T) = _streamable match { case Some(value) => case None => _streamable = Some(s) } } object GenericConsoleStream { /** * for future use */ case class Config(exclusive: Boolean = false) object Config { val default = Config() } implicit val implJFXConsoleStreamForTextArea = new ConsoleStreamable[TextArea] { override def println( ta: TextArea, text: String ): Unit = Platform.runLater(() => ta.appendText(text + "\n")) override def print( ta: TextArea, text: String ): Unit = Platform.runLater(() => ta.appendText(text)) } def textAreaStream() = new GenericConsoleStream[TextArea]( outputStream = new ByteArrayOutputStream() ) }