2011-12-25 50 views
14

我目前正試圖通過Heinrich Apfelmus的'reactive-banana來了解FRP,與我看過的其他人相比,這似乎是一個相當有據可查的簡單圖書館。reactive-banana:如何創建一個AddHandler?

但是,我無法將頭圍繞AddHandler類型。假設我想使用GLFW來獲得鼠標按鈕點擊次數,以便我有類似eMouseButton :: Event()的內容。看例子,似乎我不知何故必須使用fromAddHandler,但我不知道如何組裝這個AddHandler的論點。不知怎的,我想我必須使用newAddHandler,但怎麼做?

我猜如何連接reactive-bananawx以外的東西會有很大幫助。

回答

14

newAddHandler使用這樣的:

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

addHandler是AddHandler的傳遞給reactive-banana,和firea -> IO()型(其中一個是您的事件類型)觸發事件的函數。

例如,您可能會安裝fire爲回調GLFW的鼠標按鈕的事件,像這樣:

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

(我不跟GLFW經歷過,所以我不知道什麼是第二參數setMouseButtonCallback的回調是 - 如果它是很重要的,你需要適當地修改這個實現)

AddHandler僅僅是一個函數,它接受一個回調 - a -> IO() - 並將其註冊爲有問題的事件。它然後回報(從內IO)的IO()動作用於註銷此處理,使得complete definition of AddHandler如下:

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

那麼,這是否進來newAddHandler?簡單:newAddHandler維護事件的處理程序列表,並在執行fire x時激活它們。

如果你不需要newAddHandler,像GTK +等多種常見的工具包,您的工具包已經擁有的設施註冊和註銷多個事件處理程序;如果是這樣,你應該自己編寫一個AddHandler。但是,如果它支持的只是一個回調,則應該使用newAddHandler

請注意,您永遠不需要將AddHandlers暴露給使用FRP的代碼;它們只是用於從外部輸入創建Event的內部膠水。

+0

最後點擊!謝謝。 – bzn 2011-12-25 22:26:39

+0

糟糕 - 我最後一次用GUI工具箱使用反應香蕉,我寫了一個短的(約30行)綁定到GTK +,它具有這種功能;我沒有真正使用過wxWidgets,但是認爲它也是如此,因爲爲GTK +實現一個'AddHandler'非常自然:)經過進一步調查,它沒有;我糾正了我的答案。 – ehird 2011-12-25 22:37:52

+0

@bzn:基本上,wxWidgets沒有提供一種方法來再次註銷特定的事件處理程序,這就是爲什麼我必須使用'newAddHandler'實用程序。 – 2011-12-26 08:55:39