0

これは、私のTravelerプロジェクトのサブ問題です。

入力を処理する初歩的なコードをまとめました。TChanミックスにa を導入するまでは機能します。以下は、実際のコードとその使用方法の例です。次に、それを変更し、なぜそうしているのかを説明します。それから、問題について話します。

{-# 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、正しい選択はありますか?

4

1 に答える 1

2

あなたはおそらく欲しかった

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

しかし、私はこれをテストしていません。また、おそらくここは避けた方がよいでしょうtryReadTChan。ポーリングの代わりにreadTChan効率的になるように、単純な古いものを使用してください。retry

于 2012-10-16T17:52:06.057 に答える