2019-09-18 12:11:18 +03:00
|
|
|
{-# OPTIONS_GHC -Wwarn #-}
|
|
|
|
|
2019-09-18 09:17:54 +03:00
|
|
|
{-
|
|
|
|
This allows multiple (zero or more) terminal clients to connect to
|
|
|
|
the *same* logical arvo terminal. Terminals that connect will be
|
|
|
|
given full event history since the creation of the demuxer.
|
|
|
|
-}
|
|
|
|
|
|
|
|
module Vere.Term.Demux (Demux, mkDemux, addDemux, useDemux) where
|
|
|
|
|
|
|
|
import UrbitPrelude
|
|
|
|
|
|
|
|
import Arvo (Belt)
|
|
|
|
import Vere.Term.API (Client(Client))
|
|
|
|
|
|
|
|
import qualified Vere.Term.API as Term
|
|
|
|
|
|
|
|
|
|
|
|
--------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
data Demux = Demux
|
|
|
|
{ dConns :: TVar [Client]
|
2019-09-18 12:11:18 +03:00
|
|
|
, dStash :: TVar [[Term.Ev]]
|
2019-09-18 09:17:54 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
mkDemux :: STM Demux
|
|
|
|
mkDemux = Demux <$> newTVar [] <*> newTVar []
|
|
|
|
|
|
|
|
addDemux :: Client -> Demux -> STM ()
|
|
|
|
addDemux conn Demux{..} = do
|
2019-09-18 12:11:18 +03:00
|
|
|
stash <- concat . reverse <$> readTVar dStash
|
2019-09-18 09:17:54 +03:00
|
|
|
modifyTVar' dConns (conn:)
|
2019-09-18 12:11:18 +03:00
|
|
|
Term.give conn stash
|
2019-09-18 09:17:54 +03:00
|
|
|
|
|
|
|
useDemux :: Demux -> Client
|
|
|
|
useDemux d = Client { give = dGive d, take = dTake d }
|
|
|
|
|
|
|
|
|
|
|
|
-- Internal --------------------------------------------------------------------
|
|
|
|
|
2019-09-18 12:11:18 +03:00
|
|
|
dGive :: Demux -> [Term.Ev] -> STM ()
|
2019-09-18 09:17:54 +03:00
|
|
|
dGive Demux{..} ev = do
|
|
|
|
modifyTVar' dStash (ev:)
|
|
|
|
conns <- readTVar dConns
|
|
|
|
for_ conns $ \c -> Term.give c ev
|
|
|
|
|
|
|
|
dTake :: Demux -> STM Belt
|
|
|
|
dTake Demux{..} = do
|
|
|
|
conns <- readTVar dConns
|
|
|
|
asum (Term.take <$> conns)
|