5

Ho problemi a scrivere codice GUI basato su evento in uno stile funzionale, utilizzando Clojure e Altalena. Nello specifico, non riesco a capire come passare lo stato del programma senza utilizzare globals, o qualche altro spiacevole trucco. Il mio approccio attuale è qualcosa di simile:Programmazione guidata evento funzionale

(defn event-handler [gui-state event] 
    (update-gui! (get-new-state gui-state event))) 

(defn update-gui! [gui-state] 
    (remove-all-listeners (gui-state :button)) 
    (seesaw.core/listen (gui-state :button) 
         :action 
         (partial event-handler gui-state))) 

Si imposta un listener di eventi sul componente rilevante, con una funzione parzialmente applicata per far avanzare lo stato e aggiornare l'interfaccia grafica, tra cui la rimozione del vecchio ascoltatore. Anche se sembra funzionare, non mi piace molto, in parte perché non riesco a passare lo stesso listener nello stato (dal momento che non è stato costruito fino a dopo aver già definito lo stato), quindi la rimozione del vecchio listener richiede rimuovendo tutti gli ascoltatori, che potrebbero causare problemi man mano che il programma cresce.

La soluzione più vicina che ho trovato online è in this answer, ma non so come gestire gli eventi come un flusso come mostra. Sono sicuro che ci deve essere una soluzione migliore del mio attuale approccio, ma non riesco a capire cosa.

Qualcuno può mostrarmi come posso rispondere agli eventi di input dell'utente pur seguendo uno stile funzionale?

risposta

1

Gli stream della risposta collegata sembrano un analogo dei canali core.async.

Invece di rimuovere tutti gli ascoltatori, ogni evento può passare in un canale che contiene i dettagli dell'evento. Lo stesso canale dovrebbe andare al gestore logico del pulsante da cui verrà ripetutamente prelevato.

+0

Sembra funzionare, ed è piuttosto semplice. Grazie. – resueman