2011-12-25 11 views
14

Attualmente sto cercando di conoscere FRP tramite lo reactive-banana di Heinrich Apfelmus, che sembra essere una libreria abbastanza ben documentata e semplice, rispetto alle altre che ho visto.reactive-banana: come creare un AddHandler?

Tuttavia, non riesco a capovolgere il tipo AddHandler. Diciamo che voglio usare GLFW per fare clic sul pulsante del mouse in modo da avere qualcosa come eMouseButton :: Event(). Guardando gli esempi, sembra che in qualche modo dovrei usare fromAddHandler, ma non ho idea di come assemblare l'argomento AddHandler. Penso che dovrò usare lo newAddHandler in qualche modo, ma come?

Immagino che un esempio di come collegare reactive-banana a qualcosa di diverso da wx sarebbe di grande aiuto.

risposta

14

newAddHandler viene usato in questo modo:

do (addHandler, fire) <- newAddHandler 
    ... 

addHandler è l'AddHandler per passare a reactive-banana, e fire è una funzione di tipo a -> IO() (dove un è il vostro tipo di evento), che attiva l'evento.

Per esempio, si sarebbe probabilmente l'installazione fire come il callback evento del mouse il pulsante di GLFW, in questo modo:

registerMouseButton :: IO (Event MouseButton) 
registerMouseButton = do 
    (addHandler, fire) <- newAddHandler 
    setMouseButtonCallback $ \button _ -> fire button 
    fromAddHandler addHandler 

(non sto sperimentato con GLFW, quindi non sono sicuro di quello che il secondo argomento di callback setMouseButtonCallback s' è - se è importante, è necessario modificare questa implementazione in modo appropriato)

un AddHandler è solo una funzione che prende un callback - a -> IO() - e la registra per l'evento in questione.; poi rendimenti (dall'interno di IO) un IO() azione utilizzato per della disdetta questo gestore, rendendo il complete definition of AddHandler come segue:

type AddHandler a = (a -> IO()) -> IO (IO()) 

Così dove newAddHandler entrare? Semplice: newAddHandler mantiene un elenco di gestori per un evento e li attiva quando viene eseguito fire x.

Non è necessario newAddHandler se, come GTK + e molti altri toolkit comuni, il proprio kit di strumenti dispone già di funzionalità per registrare e annullare la registrazione di più gestori di eventi; se lo fa, dovresti scrivere la tua implementazione di un AddHandler. Ma se tutto ciò che supporta è un singolo callback, dovresti usare newAddHandler.

Nota che non è mai necessario esporre AddHandler s al codice che utilizza FRP; sono solo colla interna utilizzata per creare Event da input esterni.

+0

Infine ha fatto clic! Grazie. – bzn

+0

Oops: l'ultima volta che ho usato la banana reattiva con un toolkit GUI, ho scritto un breve binding (~ 30 line) a GTK +, che ha questa funzionalità; Non ho davvero usato wxWidgets, ma ho pensato che lo fosse anche perché implementare un 'AddHandler' per GTK + era così naturale :) Dopo ulteriori indagini, non lo è; Ho corretto la mia risposta. – ehird

+0

@bzn: Fondamentalmente, wxWidgets non ha offerto un modo per annullare la registrazione di gestori di eventi specifici, ecco perché ho dovuto usare l'utility 'newAddHandler'. –