4

我正在尝试实现一个滴答事件,并在下面进行了一个小测试,证明它不起作用。我很欣赏关于为什么它不起作用的洞察力。

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永远不会存在。我将此问题归因于错误的滴答事件。

我从中得到了定时器实现的想法但想知道我是否以错误的方式思考这个问题。有任何想法吗?

编辑:我想要一些保证fromPoll是做正确的事。我添加了上面的测试,它是。

4

1 回答 1

3

在我看来,问题不在于 tick 事件,而在于您将播放器命令建模为Behavior.

如果你从指称上思考并想象一个行为是一个随时间变化的值Behavior a = Time -> a,那么以这种方式对玩家命令建模是否有意义?3s例如,在和之间的时间范围内,玩家命令是什么4s?您给出的论点是否fromPoll尊重这些语义?

事情是grabCommands有一个严重的副作用:调用它会从通道中删除命令,所以它甚至不是幂等的。此外,当没有可用的命令时,它会阻塞。我认为这最终是滴答事件不起作用的原因:网络被阻止试图执行该fromPoll操作。然而,潜在的问题更为深刻:对玩家命令建模的正确方法是使用Event,而不是Behavior

于 2013-06-29T14:40:55.330 回答