module Ros.Topic.Stats (sendMessageStat, recvMessageStat, statSnapshot,
StatMap, SubStats(..), PubStats(..)) where
import Control.Applicative ((<$>))
import Control.Concurrent.STM.TVar
import Control.Concurrent.STM
import Data.Map (Map)
import qualified Data.Map as M
import Ros.Internal.RosTypes
data SubStats = SubStats { bytesReceived :: !Int
, subConnected :: !Bool }
data PubStats = PubStats { bytesSent :: !Int
, numSent :: !Int
, pubConnected :: !Bool }
type StatMap a = TVar (Map URI (TVar a))
statSnapshot :: (URI, TVar a) -> STM (URI, a)
statSnapshot (uri, stat) = (uri,) <$> readTVar stat
sendMessageStat :: StatMap PubStats -> URI -> Int -> IO ()
sendMessageStat tm uri numBytes =
atomically $ do m <- readTVar tm
let conn = numBytes >= 0
nb = max 0 numBytes
nm = if conn then 1 else 0
case M.lookup uri m of
Nothing -> do stats <- newTVar $ PubStats nb nm conn
writeTVar tm (M.insert uri stats m)
Just ts -> do PubStats nb' nm' _ <- readTVar ts
let stats = PubStats (nb' + nb)
(nm' + nm)
conn
writeTVar ts stats
recvMessageStat :: StatMap SubStats -> URI -> Int -> IO ()
recvMessageStat tm uri numBytes =
atomically $ do m <- readTVar tm
let conn = numBytes >= 0
nb = max 0 numBytes
case M.lookup uri m of
Nothing -> do stats <- newTVar $ SubStats nb conn
writeTVar tm (M.insert uri stats m)
Just ts -> do SubStats nb' _ <- readTVar ts
let stats = SubStats (nb' + nb) conn
writeTVar ts stats