Я пишу небольшое приложение на scala. Приложение обрабатывает простые файлы журналов. Поскольку обработка занимает некоторое время, я решил позволить ядру моего приложения расширить Actor.
class Application extends Actor {
def react() {
loop {
react {
case Process(file) => // do something interesting with file...
}
}
}
}
Обработка файла журнала запускается нажатием кнопки в графическом интерфейсе. В графическом интерфейсе используется Scala Swing.
object Gui extends SimpleSwingApplication {
val application = new Application().start()
def top = new MainFrame {
val startButton = new Button
reactions += {
case ButtonClicked(`startButton`) => application ! Process(file)
}
}
}
Теперь ядро приложения должно уведомлять графический интерфейс о текущем прогрессе.
sender ! Progress(value) // whenever progress is made
Я решил эту проблему, создав отдельный актер внутри графического интерфейса. Актер выполняется внутри потока edt. Он слушает сообщения от ядра приложения и обновляет графический интерфейс.
object Gui extends SimpleSwingApplication {
val actor = new Actor {
override val scheduler = new SchedulerAdapter {
def execute(fun: => Unit) { Swing.onEDT(fun) }
}
start()
def act() {
loop {
react {
case ForwardToApplication(message) => application ! message
case Progress(value) => progressBar.value = value
}
}
}
}
}
Поскольку ядро приложения должно знать об отправителе сообщения, я также использую этого актора для пересылки сообщений из графического интерфейса в ядро приложения, делая моего актора новым отправителем.
reactions += {
case ButtonClicked(`startButton`) => actor ! ForwardToApplication(Process(file))
}
Этот код работает отлично. Мой вопрос: Есть способ сделать это попроще? Было бы неплохо просто использовать механизм реакции для сообщений моего приложения:
reactions += {
case Progress(value) => progressBar.value = value
}
Есть идеи, как этого добиться?