eve-0.1.7: src/Eve.hs
module Eve
(
-- | This documentation is split into parts based on complexity.
-- For most applications you'll need only the Simple section. You'll
-- find useful tools in the Advanced section once you've got a simple app
-- up and running.
-- * Simple
-- | Eve allows you to build your applications incrementally, adding more
-- complexity as you need it. For this reason, many of the types are more
-- general than you'll likely need. This can be a bit confusing, but here's
-- a few tips:
--
-- * Both 'Action' and 'App' unify with 'ActionT'. You may use them in place of
-- 'ActionT'. When in doubt, use 'App'.
-- * When you see vague references to monads @m@ or @n@, you can use 'App' or 'Action' in its place.
-- * Simple Apps assume that you use the provided 'AppState' and it is
-- "baked in" to the 'Action' and 'App' types. Wherever you see @'HasStates' s@
-- you can mentally replace @s@ with 'AppState'.
-- ** Running your App
eve_
-- ** Working with Actions
, App
, Action
, runApp
, runAction
, exit
-- ** Dispatching Events
, dispatchEvent
, dispatchEvent_
-- ** Event Listeners
, addListener
, addListener_
, removeListener
, Listener
, ListenerId
-- ** Asynchronous Helpers
, asyncEventProvider
, EventDispatcher
-- ** Built-in Event Listeners
, afterInit
, beforeEvent
, beforeEvent_
, afterEvent
, afterEvent_
, onExit
-- ** Working with State
-- | All application-provided states are stored in the same
-- Map; keyed by their 'Data.Typeable.TypeRep'. This means that if more than one state
-- uses the same type then they'll conflict and overwrite each-other (this is less of a
-- problem than you're probably thinking). This is easily solved by simply
-- using a newtype around any types you haven't defined yourself.
-- For example if your application stores a counter as an Int, wrap it in your own custom
-- @Counter@ newtype when storing it. If you wish to store multiple copies of a given state
-- simply store them in a list or map, then store that container as your state.
--
-- Because states are stored by their 'Data.Typeable.TypeRep', they must
-- define an instance of 'Data.Typeable.Typeable', In most cases it's
-- unnecessary, but GHC can derive this for you with @deriving Typeable@.
--
-- It is also required for all states to define an instance of
-- 'Data.Default.Default', this is because accessing an extension which has not
-- yet been stored will result in the default value.
--
-- If there's no default value that makes sense for your type, you can define
-- a default of 'Data.Maybe.Nothing' and pattern-match on its value when you
-- access it.
--
-- Here's an example of defining your own state:
--
-- > data SimpleState = SimpleState
-- > { _myString :: String
-- > }
-- > makeLenses ''SimpleState
-- >
-- > instance Default SimpleState where
-- > def = SimpleState "default"
, makeStateLens
, AppState
-- * Advanced
-- | This section provides tools which become relevant when working on more
-- complex apps. You can customize which states you operate over, embed events
-- in nested states, and choose a custom base monad for the mtl stack.
, eve
-- ** Actions
, AppT
, ActionT
, runActionOver
-- ** States
, HasStates(..)
, States
, stateLens
-- ** Local Events
-- | The local versions of the event functions are the same as the others ('dispatchEvent',
-- 'addListener', 'removeListener') however they operate on a per-state basis.
-- This means that if you define a custom state which implements 'HasEvents'
-- then you may use these functions inside an `Action CustomState` to dispatch events
-- to ONLY the listners within that specific instance of that state. Note that
-- these listeners and events are distinct on the value level, not just the type level,
-- so if you have multiple copies of CustomState in your app, they each have their
-- own disjoint event listeners.
, HasEvents
, dispatchLocalEvent
, dispatchLocalEvent_
, addLocalListener
, addLocalListener_
, removeLocalListener
-- ** Async
, asyncActionProvider
, dispatchEventAsync
, dispatchActionAsync
) where
import Eve.Internal.Run
import Eve.Internal.Actions
import Eve.Internal.Listeners
import Eve.Internal.Async
import Eve.Internal.AppState
import Eve.Internal.States