module System.Taffybar.Widget.Generic.ChannelGraph where

import Control.Concurrent
import Control.Concurrent.STM.TChan
import Control.Monad
import Control.Monad.IO.Class
import Control.Monad.STM (atomically)
import GI.Gtk
import System.Taffybar.Widget.Generic.Graph

-- | Given a broadcast 'TChan' and an action to consume that broadcast chan and
-- turn it into graphable values, build a graph that will update as values are
-- broadcast over the channel.
channelGraphNew
  :: MonadIO m
  => GraphConfig -> TChan a -> (a -> IO [Double]) -> m GI.Gtk.Widget
channelGraphNew :: forall (m :: * -> *) a.
MonadIO m =>
GraphConfig -> TChan a -> (a -> IO [Double]) -> m Widget
channelGraphNew GraphConfig
config TChan a
chan a -> IO [Double]
sampleBuilder = do
  (graphWidget, graphHandle) <- GraphConfig -> m (Widget, GraphHandle)
forall (m :: * -> *).
MonadIO m =>
GraphConfig -> m (Widget, GraphHandle)
graphNew GraphConfig
config
  _ <- onWidgetRealize graphWidget $ do
       ourChan <- atomically $ dupTChan chan
       sampleThread <- forkIO $ forever $
         atomically (readTChan ourChan) >>=
         (graphAddSample graphHandle <=< sampleBuilder)
       void $ onWidgetUnrealize graphWidget $ killThread sampleThread
  return graphWidget