mkEngine :: Double -> IO ([Input] -> IO (), IO [Output])
mkEngine dt = do
    ichan <- CChan.newChan
    (inputS, addInput) <- makeStream
    ochan <- Chan.newChan
    forkOS $ do
        t0 <- utcr
        let state0 = makeState t0
            (outputS, stateS) = unzipS (engine dt (zipS inputS (initS state0 stateS)))
            getInput = CChan.readChanAvailable ichan >>= addInput
            putOutput = Chan.writeChan ochan
            run (inp:inps) (outp:outps) (s:ss) = do
                -- print (inp, outp, s)
                putOutput outp
                -- putStrLn "sent output"
                -- FIXME: `pauseThreadUntil' doesn't seem to work in ghci 7.0.1!
                dtms <- liftM (floor . (*1e6) . (time s -)) utcr
                -- print dtms
                threadDelay dtms
                getInput
                -- putStrLn "recurse"
                run inps outps ss
        getInput
        run (unS inputS) (unS outputS) (unS stateS)
    return (CChan.writeList2Chan ichan, Chan.readChan ochan)

-- engine2 :: Time -> [Input] -> State -> ([Output], State)
-- engine2 dt is state = ([], tick dt state)
-- 
-- mkEngine2 :: Double -> IO ([Input] -> IO (), IO [Output])
-- mkEngine2 dt = do
--     ichan <- CChan.newChan
--     ochan <- Chan.newChan
--     forkOS $ do
--         let getInputs = CChan.readChanAvailable ichan
--             putOutputs = Chan.writeChan ochan
--             run state = do
--                 is <- getInputs
--                 let (os, state') = engine2 dt is state
--                 putOutputs os
--                 dt <- liftM (floor . (*1e6) . (time state' -)) utcr
--                 threadDelay dt
--                 run state'
--         run . makeState =<< utcr
--     return (CChan.writeList2Chan ichan, Chan.readChan ochan)
mkEngine :: Double -> IO ([Input] -> IO (), IO [Output])
mkEngine dt = do
    ichan <- CChan.newChan
    (inputS, addInput) <- makeStream
    ochan <- Chan.newChan
    forkOS $ do
        t0 <- utcr
        let state0 = makeState t0
            (outputS, stateS) = unzipS (engine dt (zipS inputS (initS state0 stateS)))
            getInput = CChan.readChanAvailable ichan >>= addInput
            putOutput = Chan.writeChan ochan
            run (inp:inps) (outp:outps) (s:ss) = do
                -- print (inp, outp, s)
                putOutput outp
                -- putStrLn "sent output"
                -- FIXME: `pauseThreadUntil' doesn't seem to work in ghci 7.0.1!
                dtms <- liftM (floor . (*1e6) . (time s -)) utcr
                -- print dtms
                threadDelay dtms
                getInput
                -- putStrLn "recurse"
                run inps outps ss
        getInput
        run (unS inputS) (unS outputS) (unS stateS)
    return (CChan.writeList2Chan ichan, Chan.readChan ochan)

-- engine2 :: Time -> [Input] -> State -> ([Output], State)
-- engine2 dt is state = ([], tick dt state)
-- 
-- mkEngine2 :: Double -> IO ([Input] -> IO (), IO [Output])
-- mkEngine2 dt = do
--     ichan <- CChan.newChan
--     ochan <- Chan.newChan
--     forkOS $ do
--         let getInputs = CChan.readChanAvailable ichan
--             putOutputs = Chan.writeChan ochan
--             run state = do
--                 is <- getInputs
--                 let (os, state') = engine2 dt is state
--                 putOutputs os
--                 dt <- liftM (floor . (*1e6) . (time state' -)) utcr
--                 threadDelay dt
--                 run state'
--         run . makeState =<< utcr
--     return (CChan.writeList2Chan ichan, Chan.readChan ochan)
mkEngine dt = do
    ichan <- CChan.newChan
    (inputS, addInput) <- makeStream
    ochan <- Chan.newChan
    forkOS $ do
        t0 <- utcr
        let state0 = makeState t0
            (outputS, stateS) = unzipS (engine dt (zipS inputS (initS state0 stateS)))
            getInput = CChan.readChanAvailable ichan >>= addInput
            putOutput = Chan.writeChan ochan
            run (inp:inps) (outp:outps) (s:ss) = do
                -- print (inp, outp, s)
                putOutput outp
                -- putStrLn "sent output"
                -- FIXME: `pauseThreadUntil' doesn't seem to work in ghci 7.0.1!
                dtms <- liftM (floor . (*1e6) . (time s -)) utcr
                -- print dtms
                threadDelay dtms
                getInput
                -- putStrLn "recurse"
                run inps outps ss
        getInput
        run (unS inputS) (unS outputS) (unS stateS)
    return (CChan.writeList2Chan ichan, Chan.readChan ochan)

-- engine2 :: Time -> [Input] -> State -> ([Output], State)
-- engine2 dt is state = ([], tick dt state)
-- 
-- mkEngine2 :: Double -> IO ([Input] -> IO (), IO [Output])
-- mkEngine2 dt = do
--     ichan <- CChan.newChan
--     ochan <- Chan.newChan
--     forkOS $ do
--         let getInputs = CChan.readChanAvailable ichan
--             putOutputs = Chan.writeChan ochan
--             run state = do
--                 is <- getInputs
--                 let (os, state') = engine2 dt is state
--                 putOutputs os
--                 dt <- liftM (floor . (*1e6) . (time state' -)) utcr
--                 threadDelay dt
--                 run state'
--         run . makeState =<< utcr
--     return (CChan.writeList2Chan ichan, Chan.readChan ochan)