musicScroll-0.3.0.0: src/MusicScroll/RealMain.hs
{-# language ScopedTypeVariables #-}
module MusicScroll.RealMain (realMain) where
import Control.Concurrent.Async (withAsync, withAsyncBound, waitAnyCancel)
import Control.Concurrent.STM.TBQueue (newTBQueue)
import Control.Concurrent.STM.TVar
import Control.Concurrent.STM.TMVar
import Control.Concurrent.MVar
import Data.Functor (void)
import Control.Exception (bracket)
import Database.SQLite.Simple
import Pipes.Concurrent
import MusicScroll.Pipeline
import MusicScroll.MPRIS
import MusicScroll.UI
import MusicScroll.EventLoop
import MusicScroll.DatabaseUtils (getDBPath, sqlDBCreate)
realMain :: IO ()
realMain = do
appCtxTMvar <- atomically newEmptyTMVar
suplTVar <- atomically (newTVar Nothing)
uiCallbackTB <- atomically (newTBQueue 5)
withAsyncBound (uiThread appCtxTMvar uiCallbackTB suplTVar) $ \uiA -> do
(trackin, errorin, singleProd, trackout, errorout) <- musicSpawn
withAsync (dbusThread trackout errorout) $ \dbusA -> do
dbPath <- getDBPath
bracket (open dbPath) close $ \conn -> do
execute_ conn sqlDBCreate
mconn <- newMVar conn
ctx <- atomically (takeTMVar appCtxTMvar)
let state = AppState ctx mconn suplTVar (trackin, errorin) singleProd
let evState = EventLoopState state uiCallbackTB Nothing
withAsync (staticPipeline state) $ \staticA ->
withAsync (eventLoop evState) $ \evLoopA ->
void $ waitAnyCancel [ staticA, evLoopA, uiA, dbusA ]