{-# LANGUAGE TypeFamilies #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RecordWildCards #-} module Network.OnRmt.AsyncControls ( startupUI, UIControls(..), OnRmtParams(..) , StateCmd(..) , WorkMsg(..) , WorkEntry(..), WorkGroup(..) , resetOutput, showOutput , resetInput , progressText, progressAmount ) where import qualified Data.Text as T import Control.Concurrent import Control.Monad import Control.Monad.Trans.State.Lazy import Graphics.Vty.Widgets.All import Graphics.Vty.Widgets.ItemField import Network.OnRmt.MainScreen -- | The OnRmtParams data structure specifies the operational -- parameters for running OnRmt. These fields can be adjusted by the client as desired. data OnRmtParams = OnRmtParams { appName :: T.Text -- ^ The declared name (and version) of this app for the banner line , maxParallel :: Int -- ^ Number of remotes to run in parallel at any one time } data UIControls = UIControls { scrn :: Screen , showLog :: T.Text -> IO () , updItems :: StateCmd -> IO () , numParallel :: Int , currOutput :: [DispBlk] , queryResponses :: [T.Text] } startupUI params = do scrn <- setupScreen $ appName params logchan <- newChan st8chan <- newChan let uictl = UIControls { scrn = scrn , showLog = (writeChan logchan) , updItems = (writeChan st8chan) , numParallel = maxParallel params , currOutput = [] , queryResponses = [] } forkIO $ itemmgr uictl st8chan forkIO $ logger scrn logchan return uictl takeLast n = reverse . take n . reverse -- ---------------------------------------- logger s c = runLog [] where runLog log = do l <- readChan c schedule $ execStateT (logWrite log [l]) s >> return () runLog $ takeLast 99 log ++ [l] -- keep 100 log lines for display -- ---------------------------------------- data StateCmd = NewItems [Items] ItemIdent | FreeAll | ChgState ItemState Int | SelItem Int itemmgr :: UIControls -> Chan StateCmd -> IO () itemmgr uictl c = let st8s = itemfield $ scrn uictl in forever $ do cmd <- readChan c case cmd of NewItems ns f -> schedule $ setItems st8s ns f FreeAll -> schedule $ freeAll st8s ChgState ns isi -> schedule $ chgItemState st8s ns isi SelItem isi -> schedule $ selectItem st8s isi schedule $ clockTick $ scrn uictl resetOutput :: UIControls -> IO UIControls resetOutput ui = do schedule $ outputSet (scrn ui) [] return $ ui { currOutput = [] } showOutput :: UIControls -> DispBlk -> IO UIControls showOutput ui o = do let oo = currOutput ui no = oo ++ [o] schedule $ outputSet (scrn ui) no return $ ui { currOutput = no } resetInput :: UIControls -> IO UIControls resetInput ui = do schedule $ setEditText (inpRgn $ scrn ui) T.empty return ui progressText :: T.Text -> UIControls -> IO () progressText t ui = schedule $ setProgressText (progress $ scrn ui) t progressAmount :: Int -> UIControls -> IO () progressAmount cmpl ui = schedule $ setProgress (progress $ scrn ui) cmpl -- ---------------------------------------- data WorkMsg = ShowSelInfo Int | ClearAll | StartRun [T.Text] -- command | FinishedErr Int | FinishedGood Int | AddOutput Int DispBlk | TempStatus | StartResponse | AddToResponse T.Text | EndResponse | AbandonResponse class WorkEntry a where name :: a -> T.Text identify :: a -> T.Text rmtaddr :: a -> T.Text class WorkEntry (GroupEntry g) => WorkGroup g where type GroupEntry g getItems :: g -> [Items] numEntries :: g -> Int getEntry :: g -> Int -> GroupEntry g