gore-and-ash-async-1.1.1.0: Core module for Gore&Ash engine that embeds async IO actions into game loop.

Copyright(c) Anton Gushcha, 2016
LicenseBSD3
Maintainerncrashed@gmail.com
Stabilityexperimental
PortabilityPOSIX
Safe HaskellNone
LanguageHaskell2010

Game.GoreAndAsh.Async

Contents

Description

The core module contains API for embedding concurrent IO actions (async and sync) into main game loop for Gore&Ash.

The module does not depend on any other core modules, so AsyncT could be placed at any place in monad stack.

The module is NOT pure within first phase (see ModuleStack docs), therefore currently only IO end monad can handler the module.

Example of embedding:

-- Language extensions: DataKinds DeriveGeneric GeneralizedNewtypeDeriving MultiParamTypeClasses TypeFamilies
import Control.DeepSeq
import Control.Monad.Catch
import Control.Monad.Fix 
import Control.Monad.IO.Class
import Data.Typeable 
import GHC.Generics (Generic)

import Game.GoreAndAsh.Core
import Game.GoreAndAsh.Async 

-- | Application monad is monad stack build from given list of modules over base monad (IO or Identity)
type AppStack = ModuleStack [AsyncT ... other modules ... ] IO
newtype AppState = AppState (ModuleState AppStack)
  deriving (Generic)

instance NFData AppState 

-- | Wrapper around type family
newtype AppMonad a = AppMonad (AppStack a)
  deriving (Functor, Applicative, Monad, MonadFix, MonadIO, MonadThrow, MonadCatch, MonadAsync ... other modules monads ... )

instance GameModule AppMonad AppState where 
  type ModuleState AppMonad = AppState
  runModule (AppMonad m) (AppState s) = do 
    (a, s') <- runModule m s 
    return (a, AppState s')
  newModuleState = AppState $ newModuleState
  withModule _ = withModule (Proxy :: Proxy AppStack)
  cleanupModule (AppState s) = cleanupModule s 

-- | Arrow that is build over the monad stack
type AppWire a b = GameWire AppMonad a b

Synopsis

Low-level

data AsyncState s Source #

Internal state of asynchronious core module

s
- state of next module, they are chained until bottom, that is usually an empty data type.

Instances

Generic (AsyncState s) Source # 

Associated Types

type Rep (AsyncState s) :: * -> * #

Methods

from :: AsyncState s -> Rep (AsyncState s) x #

to :: Rep (AsyncState s) x -> AsyncState s #

NFData s => NFData (AsyncState s) Source # 

Methods

rnf :: AsyncState s -> () #

Monad m => MonadState (AsyncState s) (AsyncT s m) 

Methods

get :: AsyncT s m (AsyncState s)

put :: AsyncState s -> AsyncT s m ()

state :: (AsyncState s -> (a, AsyncState s)) -> AsyncT s m a

type Rep (AsyncState s) Source # 
type Rep (AsyncState s) = D1 (MetaData "AsyncState" "Game.GoreAndAsh.Async.State" "gore-and-ash-async-1.1.1.0-2OVkZlWWiw2AoycryFpZ3T" False) (C1 (MetaCons "AsyncState" PrefixI True) ((:*:) ((:*:) (S1 (MetaSel (Just Symbol "asyncAValues") NoSourceUnpackedness SourceStrict DecidedStrict) (Rec0 AsyncValueMap)) (S1 (MetaSel (Just Symbol "asyncScheduled") NoSourceUnpackedness SourceStrict DecidedStrict) (Rec0 SyncSheduled))) ((:*:) (S1 (MetaSel (Just Symbol "asyncSValues") NoSourceUnpackedness SourceStrict DecidedStrict) (Rec0 SyncFinished)) ((:*:) (S1 (MetaSel (Just Symbol "asyncNextId") NoSourceUnpackedness SourceStrict DecidedUnpack) (Rec0 Int)) (S1 (MetaSel (Just Symbol "asyncNextState") NoSourceUnpackedness SourceStrict DecidedStrict) (Rec0 s))))))

data AsyncT s m a Source #

Monad transformer of async core module.

s
- State of next core module in modules chain;
m
- Next monad in modules monad stack;
a
- Type of result value;

How to embed module:

type AppStack = ModuleStack [AsyncT, ... other modules ... ] IO

newtype AppMonad a = AppMonad (AppStack a)
  deriving (Functor, Applicative, Monad, MonadFix, MonadIO, MonadThrow, MonadCatch, MonadAsync)

The module is NOT pure within first phase (see ModuleStack docs), therefore currently only IO end monad can handler the module.

Instances

MonadBase IO m => MonadBase IO (AsyncT s m) Source # 

Methods

liftBase :: IO α -> AsyncT s m α

MonadError e m => MonadError e (AsyncT s m) Source # 

Methods

throwError :: e -> AsyncT s m a

catchError :: AsyncT s m a -> (e -> AsyncT s m a) -> AsyncT s m a

MonadTrans (AsyncT s) Source # 

Methods

lift :: Monad m => m a -> AsyncT s m a #

Monad m => MonadState (AsyncState s) (AsyncT s m) Source # 

Methods

get :: AsyncT s m (AsyncState s)

put :: AsyncState s -> AsyncT s m ()

state :: (AsyncState s -> (a, AsyncState s)) -> AsyncT s m a

Monad m => Monad (AsyncT s m) Source # 

Methods

(>>=) :: AsyncT s m a -> (a -> AsyncT s m b) -> AsyncT s m b #

(>>) :: AsyncT s m a -> AsyncT s m b -> AsyncT s m b #

return :: a -> AsyncT s m a #

fail :: String -> AsyncT s m a #

Functor m => Functor (AsyncT s m) Source # 

Methods

fmap :: (a -> b) -> AsyncT s m a -> AsyncT s m b #

(<$) :: a -> AsyncT s m b -> AsyncT s m a #

MonadFix m => MonadFix (AsyncT s m) Source # 

Methods

mfix :: (a -> AsyncT s m a) -> AsyncT s m a #

Monad m => Applicative (AsyncT s m) Source # 

Methods

pure :: a -> AsyncT s m a #

(<*>) :: AsyncT s m (a -> b) -> AsyncT s m a -> AsyncT s m b #

(*>) :: AsyncT s m a -> AsyncT s m b -> AsyncT s m b #

(<*) :: AsyncT s m a -> AsyncT s m b -> AsyncT s m a #

MonadIO m => MonadIO (AsyncT s m) Source # 

Methods

liftIO :: IO a -> AsyncT s m a #

MonadThrow m => MonadThrow (AsyncT s m) Source # 

Methods

throwM :: Exception e => e -> AsyncT s m a

MonadMask m => MonadMask (AsyncT s m) Source # 

Methods

mask :: ((forall a. AsyncT s m a -> AsyncT s m a) -> AsyncT s m b) -> AsyncT s m b

uninterruptibleMask :: ((forall a. AsyncT s m a -> AsyncT s m a) -> AsyncT s m b) -> AsyncT s m b

MonadCatch m => MonadCatch (AsyncT s m) Source # 

Methods

catch :: Exception e => AsyncT s m a -> (e -> AsyncT s m a) -> AsyncT s m a

MonadResource m => MonadResource (AsyncT s m) Source # 

Methods

liftResourceT :: ResourceT IO a -> AsyncT s m a

(MonadIO m, MonadThrow m) => MonadAsync (AsyncT s m) Source # 
type ModuleState (AsyncT s m) Source # 
type ModuleState (AsyncT s m) = AsyncState s

data AsyncId Source #

Id of async value, it is used to poll info about the value

Instances

Eq AsyncId Source # 

Methods

(==) :: AsyncId -> AsyncId -> Bool #

(/=) :: AsyncId -> AsyncId -> Bool #

Show AsyncId Source # 
Generic AsyncId Source # 

Associated Types

type Rep AsyncId :: * -> * #

Methods

from :: AsyncId -> Rep AsyncId x #

to :: Rep AsyncId x -> AsyncId #

NFData AsyncId Source # 

Methods

rnf :: AsyncId -> () #

Hashable AsyncId Source # 

Methods

hashWithSalt :: Int -> AsyncId -> Int

hash :: AsyncId -> Int

type Rep AsyncId Source # 
type Rep AsyncId = D1 (MetaData "AsyncId" "Game.GoreAndAsh.Async.State" "gore-and-ash-async-1.1.1.0-2OVkZlWWiw2AoycryFpZ3T" True) (C1 (MetaCons "AsyncId" PrefixI True) (S1 (MetaSel (Just Symbol "unAsyncId") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 Int)))

class (MonadIO m, MonadThrow m) => MonadAsync m where Source #

Low level monadic API for module.

Note: does not require m to be IO monad.

Methods

asyncActionM :: Typeable a => IO a -> m AsyncId Source #

Start execution of IO action concurrently and return its id

asyncActionBoundM :: Typeable a => IO a -> m AsyncId Source #

Start execution of IO action concurrently and return its id

Note: forks thread within same OS thread.

asyncPollM :: Typeable a => AsyncId -> m (Maybe (Either SomeException a)) Source #

Check state of concurrent value

Could throw MonadAsyncExcepion, AsyncWrongType and AsyncNotFound constructors.

asyncCancelM :: AsyncId -> m () Source #

Stops given async execution

asyncSyncActionM :: Typeable a => IO a -> m SyncId Source #

Schedule action to be executed at the end of frame.

Use asyncSyncPollM to get result at next frame.

Note: order of IO actions is preserved.

asyncSyncPollM :: Typeable a => SyncId -> m (Maybe (Either SomeException a)) Source #

Fires when given synchronious action is completed (at next frame after scheduling)

Could throw MonadAsyncExcepion, SyncWrongType constructor.

asyncSyncCanceM :: SyncId -> m () Source #

Unshedule given action from execution

Actually you can unshedule it until end of frame when corresponding asyncSyncActionM was called.

Arrow API

Not bounded async

asyncAction :: (MonadAsync m, Typeable a) => IO a -> GameWire m b (Event a) Source #

Execute given IO action concurrently. Event fires once when the action is finished. Exceptions are rethrown into main thread.

asyncActionC :: (MonadAsync m, Typeable a) => IO a -> GameWire m (Event b) (Event a) Source #

Execute given IO action concurrently. Event fires once when the action is finished. Exceptions are rethrown into main thread.

The concurrent action can be canceled by input event.

asyncActionEx :: (MonadAsync m, Typeable a) => IO a -> GameWire m b (Event (Either SomeException a)) Source #

Execute given IO action concurrently.

Event fires once when the action is finished. Exceptions in the concurrent action are returned in event payload.

asyncActionExC :: (MonadAsync m, Typeable a) => IO a -> GameWire m (Event b) (Event (Either SomeException a)) Source #

Execute given IO action concurrently.

Event fires once when the action is finished. Exceptions in the concurrent action are returned in event payload.

The concurrent action can be canceled by input event.

asyncActionFactory :: (MonadAsync m, Typeable a) => GameWire m (Event (Seq (IO a))) (Event (Seq a)) Source #

Wire that executes incoming IO actions concurrently and then produces events with results once for each action.

Exceptions are rethrown into main thread.

asyncActionFactoryEx :: (MonadAsync m, Typeable a) => GameWire m (Event (Seq (IO a))) (Event (Seq (Either SomeException a))) Source #

Wire that executes incoming IO actions concurrently and then produces events with results once for each action.

Exceptions are returned in event payload.

Bounded async

asyncActionBound :: (MonadAsync m, Typeable a) => IO a -> GameWire m b (Event a) Source #

Execute given IO action concurrently. Event fires once when the action is finished. Exceptions are rethrown into main thread.

Note: forks thread within same OS thread.

asyncActionBoundC :: (MonadAsync m, Typeable a) => IO a -> GameWire m (Event b) (Event a) Source #

Execute given IO action concurrently. Event fires once when the action is finished. Exceptions are rethrown into main thread.

The concurrent action can be canceled by input event.

Note: forks thread within same OS thread.

asyncActionBoundEx :: (MonadAsync m, Typeable a) => IO a -> GameWire m b (Event (Either SomeException a)) Source #

Execute given IO action concurrently.

Event fires once when the action is finished. Exceptions in the concurrent action are returned in event payload.

Note: forks thread within same OS thread.

asyncActionBoundExC :: (MonadAsync m, Typeable a) => IO a -> GameWire m (Event b) (Event (Either SomeException a)) Source #

Execute given IO action concurrently.

Event fires once when the action is finished. Exceptions in the concurrent action are returned in event payload.

The concurrent action can be canceled by input event.

Note: forks thread within same OS thread.`

asyncActionBoundFactory :: (MonadAsync m, Typeable a) => GameWire m (Event (Seq (IO a))) (Event (Seq a)) Source #

Wire that executes incoming IO actions concurrently and then produces events with results once for each action.

Exceptions are rethrown into main thread.

Note: forks thread within same OS thread.

asyncActionBoundFactoryEx :: (MonadAsync m, Typeable a) => GameWire m (Event (Seq (IO a))) (Event (Seq (Either SomeException a))) Source #

Wire that executes incoming IO actions concurrently and then produces events with results once for each action.

Exceptions are returned in event payload.

Note: forks thread within same OS thread.

Sync actions

asyncSyncAction :: (MonadAsync m, Typeable a) => IO a -> GameWire m b (Event a) Source #

Execute given IO action at end of current frame. Event fires once at next frame.

Exceptions are rethrown into main thread.

asyncSyncActionEx :: (MonadAsync m, Typeable a) => IO a -> GameWire m b (Event (Either SomeException a)) Source #

Execute given IO action at end of current frame. Event fires once at next frame.

Exceptions are returned in event payload.

asyncSyncActionC :: (MonadAsync m, Typeable a) => IO a -> GameWire m (Event b) (Event a) Source #

Execute given IO action at end of current frame. Event fires once at next frame.

Exceptions are rethrown into main thread.

Action can be canceled with input event, although you have only the frame to do this.

asyncSyncActionExC :: (MonadAsync m, Typeable a) => IO a -> GameWire m (Event b) (Event (Either SomeException a)) Source #

Execute given IO action at end of current frame. Event fires once at next frame.

Exceptions are rethrown into main thread.

Action can be canceled with input event, although you have only the frame to do this.

asyncSyncActionFactory :: forall m a. (MonadAsync m, Typeable a) => GameWire m (Event (Seq (IO a))) (Event (Seq a)) Source #

Wire that executes incoming IO actions at end of current frame and then produces events with results once for each action.

Exceptions are rethrown into main thread.

asyncSyncActionFactoryEx :: forall m a. (MonadAsync m, Typeable a) => GameWire m (Event (Seq (IO a))) (Event (Seq (Either SomeException a))) Source #

Wire that executes incoming IO actions at end of current frame and then produces events with results once for each action.

Exceptions are rethrown into main thread.