module Eve.Internal.Run
( eve
, eve_
) where
import Eve.Internal.Actions
import Eve.Internal.Listeners
import Eve.Internal.Events
import Eve.Internal.States()
import Eve.Internal.AppState
import Control.Monad
import Control.Monad.State
import Control.Lens
import Data.Default
import Data.Maybe
import Data.Typeable
import Pipes
import Pipes.Concurrent
import qualified Pipes.Parse as PP
eve :: (MonadIO m, Typeable m) => AppT AppState m () -> m AppState
eve initialize = do
(output, input) <- liftIO $ spawn unbounded
execApp (def & asyncQueue .~ Just output) $ do
initialize
dispatchEvent_ Init
dispatchEvent_ AfterInit
eventLoop $ fromInput input
dispatchEvent_ Exit
eve_ :: (MonadIO m, Typeable m) => AppT AppState m () -> m ()
eve_ = void . eve
eventLoop :: (MonadIO m, HasEvents base, Typeable m) => Producer (AppT base m ()) IO () -> AppT base m ()
eventLoop producer = do
dispatchEvent_ BeforeEvent
(mAction, nextProducer) <- liftIO $ PP.runStateT PP.draw producer
fromMaybe (return ()) mAction
dispatchEvent_ AfterEvent
shouldExit <- isExiting
unless shouldExit $ eventLoop nextProducer