2013-06-26 23 views
4

我試圖實現一個tick事件,並在下面進行一些測試,證明它不起作用。我會很高興看到爲什麼它不起作用。功能性香蕉旅行者 - 我的蜱活動有什麼問題?

gameloop :: TChan UAC -> 
      IO() 
gameloop commandChannel = do 
    (tickHandler, tickSink) <- newAddHandler 
    networkDescr <- compile $ makeNetworkDescription commandChannel tickHandler 
    actuate networkDescr 
    forkIO $ forever $ (timer 10) >>= tickSink 
    return() 


makeNetworkDescription :: forall t . Frameworks t => 
          TChan UAC -> 
          AddHandler() -> 
          Moment t() 
makeNetworkDescription commandChannel tickHandler = do 
    eTick <- fromAddHandler tickHandler 
    bCChannel <- fromPoll $ grabCommands commandChannel 

-- test fromPoll 

    test <- initial bCChannel 
    liftIO $ appendFile "testPoll.txt" $ show test 

-- end fromPoll test 

    let eCChannel = bCChannel <@ eTick 
    liftIO $ print "hi there\n" 
    reactimate $ (\n -> appendFile "Commands.txt" (show n)) <$> eCChannel 


grabCommands :: TChan UAC -> IO [UAC] 
grabCommands unval = do 
    result <- (atomically $ readTChan unval) `untilM` (atomically $ isEmptyTChan unval) 
    liftIO $ print $ show result 
    return result 

timer :: TimeOut -> IO() 
timer ms = do 
    threadDelay ms 

這是一些測試數據。

main :: IO() 
main = do 
    commandChan <- atomically $ newTChan :: IO (TChan UAC) 
    forkIO $ gameloop commandChan 
    liftIO $ print "back from fork\n" 
    atomically $ populateCC commandChan playerCommands 
    return() 

populateCC :: TChan UAC -> [UAC] -> STM() 
populateCC pChannel pCommands = mapM_ (writeTChan pChannel) pCommands 

playerCommands = 
    [UAC (PlayerCommand (CommandData (T.pack "1" :: AID) Look) (T.pack "1")), 
    UAC (PlayerCommand (CommandData (T.pack "2" :: AID) (Move Mongo)) (T.pack "2")) 
    ] 

當我執行上述Main我得到這個輸出。

"back from fork\n" 
"[UAC (PlayerCommand (CommandData \"1\" Look) \"1\"),UAC (PlayerCommand (CommandData \"2\" (Move Mongo)) \"2\")]" 
"hi there\n" 

文件Commands.txt從來沒有進入存在。我將此問題歸因於錯誤的滴答事件。

我從this得到了我的計時器實現的想法,但不知道我是否在想這個錯誤的方式。有任何想法嗎?

編輯:我想要一些保證fromPoll是做正確的事情。我添加了上面的測試,它是。

回答

3

在我看來,問題不在於tick事件,而在於你將玩家命令建模爲Behavior

如果你從根本上想象並且想象一個行爲是一個隨時間變化的值Behavior a = Time -> a,以這種方式建模玩家命令是否有意義?玩家的命令是什麼,例如3s4s之間的時間範圍?您給fromPoll的論點是否尊重這些語義?

事情是grabCommands有一個嚴重的副作用:調用它從通道中刪除命令,所以它甚至不是冪等的。另外,當沒有可用的命令時,它。我認爲這最終是tick事件不起作用的原因:網絡被阻止嘗試執行fromPoll操作。但是,潛在的問題更爲深刻:模擬玩家命令的正確方法是使用Event而不是Behavior

+0

這提示瞭如何引入緩衝輸入的問題,我將稍後討論。 –

+0

我看到grabCommands如何消失,我認爲accumE將幫助我理清緩衝輸入的問題。 –