mischief-ecs-0.2.0.0: src/Mischief/ECS/Tutorial/Guides/Parallelism.hs
{-# OPTIONS_GHC -Wno-unused-imports #-}
-- |
-- Module: Queries Tutorial
-- Description: How To Mischief.
--
-- [Previous Chapter: Keeping Track of Time]("Mischief.ECS.Tutorial.Guides.Time")
--
-- [Next Chapter: Events and Messages]("Mischief.ECS.Tutorial.Guides.Events")
--
-- [Main Page]("Mischief.ECS")
module Mischief.ECS.Tutorial.Guides.Parallelism
( -- * Learn You an ECS for Great Mischief! - 2.9. Parallelism and Asynchronicity
-- $intro
-- * The System Monads
-- $monad
-- * Running Systems in Parallel
-- $par
-- * Iterating in Parallel
-- $parFor
-- * Querying in Parallel
-- $qpar
-- * Asynchronicity
-- $async
-- * [Next Chapter: Events and Messages]("Mischief.ECS.Tutorial.Guides.Events")
)
where
import Mischief.ECS
-- $intro
-- Mischief offers a few primitives for making systems run in parallel or asynchronously.
-- $monad
-- There is another monad that acts similary to @System@. It is called @ParSystem@, and
-- it doesn't allow for immediate mutations of the World.
--
-- Both @ParSystem@ and @System@ instance the @MonadSystem@ class, which you can use to write functions that work with both:
--
-- @
-- f :: (MonadSystem w m) => m ()
-- @
--
-- Functions such as @query@, @query_@, @single@ work with both monads, since they only read data.
--
-- Functions that mutate the world only work with @System@, requiring you to use @defer@ (see previous chapter) when used in @ParSystem@:
--
-- @
-- 'defer' $ 'insert' (Health 100) bob
-- @
-- $par
-- You can run a list of @ParSystems@ in parallel using the @par@ function:
--
-- @
-- par [foo, bar]
-- @
-- $parFor
-- You can iterate over Foldables in parallel using @parFor@:
--
-- @
-- names <- 'query' ['q'|Entity, Name|]
-- 'parFor' names $ \\(entity, Name name) -> do
-- 'defer' $ 'insert' (Name $ name ++ \"2\") entity
-- @
-- $qpar
-- You can parallelize any @Query ParSystem a@ using @qpar@:
--
-- @
-- names <-
-- ['q'|Name / With Player|]
-- & 'qpar'
-- & 'query'
-- @
-- $async
-- Mischief has a couple of primitived that allow running systems asynchronously.
--
-- === runAfter
--
-- Asynchonicity in Mischief can be achieved using the @runAfter@ primtitive.
-- You provide it an 'IO' action that returns an @a@, and a system which consumes that @a@.
--
-- The 'IO' will be ran fully asychrnously and then will add the system to a special async-friendly deferred list that
-- will be applied at the first available sync point.
--
-- We can look at @delay@ as an example of how this may be useful:
--
-- @
-- 'delay' d system = 'runAfter' ('threadDelay' d) ('const' system)
-- @
--
-- Whcih allows delaying any system by an amount of time:
--
-- @
-- 'delay' 0.5 $ 'insert' (Health 100) player
-- @
--
-- === Repeaters
--
-- Repeaters are another way of running async systems.
--
-- A Repeater will run the given system at the given interval of time. This Repeater will
-- print \"Hello!\" once per second:
--
-- @
-- 'spawn_' 'Repeater' 1 ('info' \"Hello!\")
-- @
--
-- Repeaters can be despawned to stop them from running.