Piszę małą aplikację w scala. Aplikacja przetwarza proste pliki dziennika. Ponieważ przetwarzanie zajmuje trochę czasu, postanowiłem, że moja aplikacja rozszerzy się na aktora.Interakcja z aktorami w aplikacjach scala swing
class Application extends Actor {
def react() {
loop {
react {
case Process(file) => // do something interesting with file...
}
}
}
}
Przetwarzanie pliku dziennika jest wyzwalane przez kliknięcie przycisku w gui. Gui używa huśtawki scala.
object Gui extends SimpleSwingApplication {
val application = new Application().start()
def top = new MainFrame {
val startButton = new Button
reactions += {
case ButtonClicked(`startButton`) => application ! Process(file)
}
}
}
Teraz rdzeń aplikacji musi powiadomić GUI o bieżącym postępie.
sender ! Progress(value) // whenever progress is made
Rozwiązałem to, tworząc osobny aktor wewnątrz gui. Aktor jest wykonywany wewnątrz wątku edt. Wysłuchuje wiadomości z rdzenia aplikacji i aktualizuje GUI.
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
}
}
}
}
}
Ponieważ rdzeń aplikacja musi wiedzieć o nadawcy wiadomości, ja też użyć tego aktora do przekazania wiadomości z GUI do rdzenia aplikacji, dzięki czemu moja aktor nowego nadawcę.
reactions += {
case ButtonClicked(`startButton`) => actor ! ForwardToApplication(Process(file))
}
Ten kod działa dobrze. Moje pytanie: czy istnieje prostszy sposób na zrobienie tego? Byłoby miło prostym użyciem mechanizmu reakcji dla moich wiadomości aplikacyjnych:
Jakieś pomysły, jak to osiągnąć?
Myślę, że to dobre rozwiązanie. Może w zamian zasługuję na odwrót;) – gerferra
Myślę, że brakuje ci 'pośrednika! 'W twojej reakcji na' ButtonClicked' – gerferra
@geferra Wywołanie "pośrednika!" Znajduje się w konstruktorze 'case case Send'. 'Pośrednik' jest przekazywany przez niejawny parametr. Uaktualniam twoją odpowiedź, ponieważ stanowi ona inspirację dla mojego własnego rozwiązania. –