2017-06-19 114 views
1

我正在研究一個基於小型終端的用戶界面,並且我想使用活性香蕉來描述交互。我唯一感興趣的外部事件是用戶是否按下了一個鍵。活性香蕉:綁定

從我從框架文檔中收集到的信息,我可以使用輪詢來獲取終端輸入緩衝區的狀態,或者將「事件處理程序」傳遞給反應香蕉。我寧願選擇後者,但我發現事件處理部分令人困惑。我將如何描述getChar的事件驅動版本?最後,我想在「事件密鑰」流上進行操作。

我已經看過SDL和wx綁定,但是我沒有發現它們很多幫助,因爲它們充斥着與庫相關的特性,我非常感謝一個更簡潔的解釋:事件處理程序,事件循環和反應香蕉混合在一起。

+0

有大量的例子/教程可以在互聯網上找到。你有什麼試過,它是如何不起作用的? (你想要處理用戶輸入事件的函數是''fromAddHandler'](https://hackage.haskell.org/package/reactive-banana-1.1.0.1/docs/Reactive-Banana-Frameworks.html# v:fromAddHandler)) – user2407038

+0

是的,我想我已經想通了,發佈之後。看來我只是需要休息一下。如果有任何興趣,我會發布我的答案,否則問題可能會被關閉。謝謝。 – ftl

+1

沒有必要關閉它 - 編輯問題以包含一些代碼,顯示您最初遇到的問題,然後發佈包含您找到的解決方案的答案。自我回答的問題對於SO來說是完全有效的格式!對於任何有興趣的人,你都不這樣做;它是所有未來讀者的後代。 – user2407038

回答

2

事實證明,使用反應性香蕉處理外部事件非常靈活和簡單。所有需要的是創建一個帶有「newAddHandler」的事件處理程序,該程序由兩部分組成,一個「AddHandler」可以使用reactimate函數創建事件,另一個處理程序必須由膠合代碼調用(綁定)將Reactive Banana連接到框架(在我的情況下,我只是將getChar的結果提供給處理程序)。

這裏是回聲擊鍵的示例代碼:

echo = do 
    (keyEventHandler, fire) <- newAddHandler 

    -- Network Specification (echo keyboard input) 
    let networkDescription = 
     fromAddHandler keyEventHandler >>= -- Create event stream from handler 
     reactimate . fmap print -- Map print over event stream 

    compile networkDescription >>= actuate 

    -- Event Loop 
    hSetBuffering stdin NoBuffering 
    forever $ do 
     ready <- hReady stdin 
     if ready 
      then getChar >>= fire -- Create keyboad event 
      else return() 

有關反應香蕉的好處是,回調函數「火」可以從任何上下文中調用。因此,事件循環可以在線程中運行,也可以從C庫調用。 Heinrich對How to implement a game loop in reactive-banana?的回答可以找到更多關於此的信息。但是,在沒有輪詢的情況下捕獲任意鍵盤輸入事件並不像我想象的那麼容易,POSIX不會允許它(如果我沒有弄錯),並且即使這樣做代碼也不可移植。 另外請注意,在Windows機器上,你必須進入,我仍然必須找到解決這個問題的方法。在這個問題上更多發現at the Haskell bugtracker