2013-06-26 8 views
4

나는 진드기 이벤트를 구현하려고하는데, 작동하지 않는다는 것을 보여주는 아래의 약간의 테스트가있다. 왜 그것이 작동하지 않는지에 대한 통찰력을 고맙게 생각합니다.Functional Banana Traveler - 틱 이벤트에 어떤 문제가 있습니까?

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 

여기에 몇 가지 테스트 데이터가 있습니다. I 위 Main을 실행할 때

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")) 
    ] 

I는이 출력을 얻는다.

"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

문제는 틱 이벤트와 관련이 없지만 플레이어 명령을 Behavior으로 모델링 한 것 같습니다.

만약 당신이 생각할 때 행동이 시간 변화 값 Behavior a = Time -> a이라고 생각한다면이 방법으로 플레이어 명령을 모델링하는 것이 합리적입니까? 예를 들어 3s4s 사이의 시간 프레임에서 플레이어 명령은 무엇입니까? fromPoll에 전달한 인수가 이러한 의미를 존중합니까?

중요한 것은 grabCommands에 심각한 부작용이 있습니다. 호출하면 채널에서 명령이 제거되므로 멱등수가 아닙니다. 또한 사용할 수있는 명령이 없을 때 블록 블록입니다. 이것이 궁극적으로 틱 이벤트가 작동하지 않는 이유라고 생각합니다. 네트워크가 fromPoll 작업을 실행하려고 시도 할 때 차단되었습니다. 그러나 기본 문제는 더욱 심오합니다. 플레이어 명령을 모델링하는 올바른 방법은 Behavior이 아닌 Event을 사용하는 것입니다.

+0

이렇게하면 버퍼링 된 입력을 도입하는 방법에 대한 질문이 나옵니다. 이에 대해서는 곧 논의 할 것입니다. –

+0

grabCommands가 어떻게 사라져야하는지 알고 있습니다. 그리고 accumE은 버퍼링 된 입력 문제를 해결하는 데 도움이 될 것이라고 생각합니다. –