功能性香蕉旅行者 - 输入处ç†

时间:2012-10-16 16:20:05

标签: haskell stm frp reactive-banana

这是我Traveller项目的一个å­é—®é¢˜ã€‚

我把处ç†è¾“入的粗俗代ç æ”¾åœ¨ä¸€èµ·ã€‚它有效,直到我å‘æ··åˆä¸­å¼•å…¥TChan。下é¢æ˜¯å·¥ä½œä»£ç ï¼Œä»¥åŠå¦‚何使用它的示例。然åŽï¼Œæˆ‘将改å˜å®ƒå¹¶è§£é‡Šæˆ‘为什么这样åšã€‚然åŽï¼Œæˆ‘将谈论这个问题。

{-# LANGUAGE ScopedTypeVariables #-}
import Control.Monad (forever)
import Control.Concurrent (forkIO)
import Control.Monad.STM (STM,atomically)
import Control.Concurrent.STM.TChan
import Reactive.Banana
import Reactive.Banana.Frameworks


data Planet = Vulcan
            | Mars
            | Terra
                deriving (Eq,Read,Show)

data Command = Move Planet
             | Look
             | Quit
             | Null
                deriving Show

makeNetworkDescription :: AddHandler (Maybe Command) -> IO EventNetwork
makeNetworkDescription addCommandEvent = compile $ do
   eInput <- fromAddHandler addCommandEvent
   let eCommand = filterJust eInput 
       bCommand = stepper Null eCommand 
   eCommandChanged <- changes bCommand

reactimate $ (\n -> appendFile "output.txt" ("Command is " ++ show n)) <$>  
eCommandChanged

在ghci中执行以下æ“作将è¯æ˜Žè¿™æ˜¯æœ‰æ•ˆçš„。

(addCommandEvent,fireCommand) <- newAddHandler :: IO (AddHandler (Maybe Command),Maybe Command -> IO ())
networkDescr <- makeNetworkDescription addCommandEvent
actuate networkDescr
return (Just $ Look) >>= fireCommand

所以,现在我已ç»æœ‰äº†åŸºæœ¬çš„机制,我想开始构建它。这将是一个多人游æˆã€‚到目å‰ä¸ºæ­¢ï¼Œè¾“入处ç†çš„第一步是从TChan获å–输入。这个想法是,所有玩家都会写入此TChan,并且æ¯ä¸ªå‘½ä»¤éƒ½ä¼šæŒ‰ç…§å®ƒåˆ°è¾¾çš„顺åºè¿›è¡Œå¤„ç†ã€‚

所以我添加了一个新功能'inputFrame'

inputFrame :: TChan Command -> IO ()
inputFrame commandChannel = do
   (addCommandEvent,fireCommand) <- newAddHandler
   networkDescr <- makeNetworkDescription addCommandEvent
   actuate networkDescr
   forkIO $ forever (atomically $ tryReadTChan commandChannel) >>= fireCommand
   return ()

以下是我在ghci中å°è¯•ä½¿ç”¨å®ƒçš„方法。

commandChan <- atomically $ newTChan :: IO (TChan Command)
_ <- atomically $ writeTChan commandChan Look

output.txt无法写入。正在读å–commandChan,因为我检查它是å¦åœ¨å¡«å……åŽå˜ä¸ºç©ºã€‚我åšé”™äº†å¾ˆæ˜Žæ˜¾å—?如果没有,我该如何解决问题呢?å¦å¤–,对于我的预期目的,TChan是正确的选择å—?

1 个答案:

答案 0 :(得分:2)

ä½ å¯èƒ½æƒ³è¦

forkIO $ forever (atomically (tryReadTChan commandChannel) >>= fireCommand)

但我没有测试过这个。å¦å¤–,猜测一下,您å¯èƒ½å¸Œæœ›é¿å…tryReadTChan。åªéœ€ä½¿ç”¨æ™®é€šçš„readTChan,就å¯ä»¥èŽ·å¾—有效的retry而ä¸æ˜¯è½®è¯¢ã€‚