2013-06-26 25 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将帮助我理清缓冲输入的问题。 –