2011-12-25 11 views
14

Actualmente estoy tratando de conocer FRP a través de Heinrich Apfelmus 'reactive-banana, que parece ser una biblioteca bastante bien documentada y simple, en comparación con los otros que he visto.reactive-banana: ¿Cómo crear un AddHandler?

Sin embargo, no puedo entender el tipo de AddHandler. Digamos que quiero usar GLFW para obtener clics del botón del mouse para que tenga algo así como eMouseButton :: Event(). Mirando los ejemplos, parece que de alguna manera tengo que usar fromAddHandler, pero no tengo idea de cómo armar ese argumento AddHandler. Creo que tendré que usar newAddHandler de alguna manera, pero ¿cómo?

Supongo que un ejemplo de cómo conectar reactive-banana a algo que no sea wx ayudaría mucho.

Respuesta

14

newAddHandler se utiliza como esto:

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

addHandler es el AddHandler para pasar a reactive-banana y fire es una función del tipo a -> IO() (donde un es su tipo de evento) que desencadena el evento.

Por ejemplo, lo más probable sería instalar fire como la devolución de llamada al evento de botón del ratón de GLFW, así:

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

(yo no tengo experiencia con GLFW, así que no estoy seguro de lo que la segunda argumento para devolución de llamada setMouseButtonCallback 's es - si es importante, tendrá que modificar esta implementación apropiada)

un AddHandler es sólo una función que toma una devolución de llamada - a -> IO() - y la registra para el evento en cuestión.; A continuación, vuelve (desde dentro IO) una acción IO() utiliza para Deregister este controlador, haciendo que el complete definition of AddHandler se lea como sigue:

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

Entonces, ¿dónde newAddHandler entrar? Simple: newAddHandler mantiene una lista de controladores para un evento y los activa cuando se ejecuta fire x.

No necesita newAddHandler si, al igual que GTK + y muchos otros kits de herramientas comunes, su kit de herramientas ya cuenta con instalaciones para registrar y eliminar el registro de múltiples controladores de eventos; si lo hace, debe escribir su propia implementación de AddHandler. Pero si todo lo que admite es una única devolución de llamada, debe usar newAddHandler.

Tenga en cuenta que nunca necesita exponer AddHandler s al código de FRP mismo; solo son pegamento interno utilizado para crear Event desde entradas externas.

+0

¡Finalmente hizo clic! Gracias. – bzn

+0

Vaya, la última vez que utilicé reactivo-banana con un juego de herramientas GUI, escribí un enlace corto (~ 30 líneas) a GTK +, que tiene esta funcionalidad; Realmente no he usado wxWidgets, pero supuse que también lo hizo, porque la implementación de un 'AddHandler' para GTK + era muy natural :) Tras una investigación adicional, no lo hace; He corregido mi respuesta. – ehird

+0

@bzn: Básicamente, wxWidgets no ofrecía una forma de anular el registro de manejadores de eventos específicos otra vez, es por eso que tuve que usar la herramienta 'newAddHandler'. –