{-# language TemplateHaskell #-} module Eve.Internal.AppState ( AppState(..) , App , Action , ActionM , AppM , exit , isExiting , asyncQueue ) where import Eve.Internal.Actions import Eve.Internal.States import Control.Lens import Data.Default import Data.Typeable import Control.Concurrent.Chan -- | A basic default state which underlies 'App' Contains only a map of 'States'. data AppState = AppState { _baseStates :: States } makeLenses ''AppState instance Default AppState where def = AppState mempty instance HasStates AppState where states = baseStates instance HasEvents AppState where newtype AsyncQueue base m = AsyncQueue { _asyncQueue' :: Maybe (Chan (AppT base m ())) } deriving Typeable makeLenses ''AsyncQueue instance Default (AsyncQueue base m) where def = AsyncQueue Nothing -- | Accesses a queue for dispatching async actions. asyncQueue :: (HasStates s, Typeable m, Typeable base) => Lens' s (Maybe (Chan (AppT base m ()))) asyncQueue = stateLens.asyncQueue' newtype Exiting = Exiting Bool instance Default Exiting where def = Exiting False -- | Tells the application to quit. This triggers 'onExit' listeners -- following the current event loop. exit :: (Monad m, HasStates s) => ActionT s zoomed m () exit = runApp $ stateLens .= Exiting True -- | Checks whether we're in the process of exiting. isExiting :: (Monad m, HasStates s) => ActionT s zoomed m Bool isExiting = runApp $ do Exiting b <- use stateLens return b -- | An 'App' is a base level monad which operates over your main application -- state. You may call 'runAction' inside an app to run 'Action's over other states. type App a = AppT AppState IO a -- | An 'Action' is a monad over some zoomed in state, they are run inside 'App' using -- 'runAction'. For example an 'Action' which operates over a String somewhere in your app state -- would be written as: -- -- > alterString :: 'Action' String () type Action state a = ActionT AppState state IO a -- | A more general version of 'App' which lets you specify the underlying monad. type AppM m a = AppT AppState m a -- | A more general version of 'Action' which lets you to specify the underlying monad. type ActionM s m a = ActionT AppState s m a