首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Functional Banana Traveller -输入处理

Functional Banana Traveller -输入处理
EN

Stack Overflow用户
提问于 2012-10-17 00:20:05
回答 1查看 171关注 0票数 0

这是我的Traveller项目中的一个子问题。

我已经将处理输入的基本代码组合在一起。它是有效的,直到我将一个TChan引入到混搭中。下面是工作代码,以及如何使用它的示例。然后,我将更改它并解释我为什么要这样做。然后,我将讨论这个问题。

代码语言:javascript
复制
{-# 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中执行以下命令将证明这是可行的。

代码语言:javascript
复制
(addCommandEvent,fireCommand) <- newAddHandler :: IO (AddHandler (Maybe Command),Maybe Command -> IO ())
networkDescr <- makeNetworkDescription addCommandEvent
actuate networkDescr
return (Just $ Look) >>= fireCommand

所以,现在我已经有了基本的机制,我想开始构建它。这将是一个多人游戏。解决这个问题的第一步就是从TChan获取输入。这个想法是,所有的玩家都将写入这个TChan,并且每个命令都将按照它到达的顺序进行处理。

所以我添加了一个新函数'inputFrame‘

代码语言:javascript
复制
inputFrame :: TChan Command -> IO ()
inputFrame commandChannel = do
   (addCommandEvent,fireCommand) <- newAddHandler
   networkDescr <- makeNetworkDescription addCommandEvent
   actuate networkDescr
   forkIO $ forever (atomically $ tryReadTChan commandChannel) >>= fireCommand
   return ()

下面是我在ghci中尝试使用它的方法。

代码语言:javascript
复制
commandChan <- atomically $ newTChan :: IO (TChan Command)
_ <- atomically $ writeTChan commandChan Look

output.txt不会被写入。commandChan正在被读取,因为我检查它在填充后是否为空。我做错了什么是显而易见的吗?如果不是,我该如何解决这个问题?另外,对于我的预期目的,TChan是正确的选择吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-10-17 01:52:06

你可能想要

代码语言:javascript
复制
forkIO $ forever (atomically (tryReadTChan commandChannel) >>= fireCommand)

但是我还没有测试过这个。此外,在这里,您可能会想要避免使用tryReadTChan。只需使用普通的老式readTChan,这样您就可以获得有效的retry,而不是轮询。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12919136

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档