我正在尝试实现一个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从未出现过。我将这个问题归因于错误的tick事件。
我是从this得到计时器实现的想法的,但不知道我是不是想错了。有什么想法吗?
编辑:我想要一些保证fromPoll正在做正确的事情。我添加了上面的测试,它确实是。
发布于 2013-06-29 22:40:55
在我看来,问题不在于tick事件,而在于您将播放器命令建模为Behavior。
如果你从外延的角度思考,并想象一个行为是一个时变值的Behavior a = Time -> a,那么以这种方式对播放器命令建模有意义吗?比方说,在3s和4s之间的时间范围内,播放器命令是什么?您给fromPoll的参数是否遵守这些语义?
问题是grabCommands有一个严重的副作用:调用它会从通道中删除命令,因此它甚至不是幂等的。此外,当没有可用的命令时,它会阻塞。我认为这是tick事件无法工作的最终原因:网络在尝试执行fromPoll操作时被阻塞。然而,潜在的问题更加深刻:对播放器命令建模的正确方法是使用Event,而不是Behavior。
https://stackoverflow.com/questions/17323383
复制相似问题