about summary refs log tree commit diff
path: root/lib/Grav2ty/Core.hs
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Grav2ty/Core.hs')
-rw-r--r--lib/Grav2ty/Core.hs52
1 files changed, 44 insertions, 8 deletions
diff --git a/lib/Grav2ty/Core.hs b/lib/Grav2ty/Core.hs
index f4b872c..e4bd9b6 100644
--- a/lib/Grav2ty/Core.hs
+++ b/lib/Grav2ty/Core.hs
@@ -2,6 +2,7 @@
 module Grav2ty.Core
   ( -- * Basic Types
     Id (..)
+  , Tick (..)
   , World (..)
   -- ** Object
   , Object (..)
@@ -19,14 +20,14 @@ module Grav2ty.Core
   , zeroModification
   -- * The Grav2ty Monad
   , Grav2ty (..)
+  -- ** State
+  , Grav2tyState (..)
+  , tick, timePerTick, inputs, graphics, world, highestId
+  -- ** Operations
   , setObject
   , getObject
   , addObject
   , delObject
-  -- ** State
-  , Grav2tyState (..)
-  , tick, timePerTick, inputs, graphics, world, highestId
-  , Tick (..)
   ) where
 
 import Control.Lens
@@ -35,9 +36,15 @@ import Data.Map.Strict (Map (..))
 import qualified Data.Map.Strict as M
 import Linear.V2
 
+-- | Identifier used for 'Object's in 'World'.
 type Id = Integer
+
+-- | A tick is a simulation step. This type represents the ascending number of simulation steps.
 type Tick = Integer
 
+-- | The 'Object's are stored in a strict 'Map'. We need to access all Objects relatively frequently
+--   and also add 'Object's from time to time as well as access 'Object's by their 'Id'. 'Map'
+--   seems to provide a good compromise in terms of performance for these operations.
 type World a = Map Id (Object a)
 
 data Modifier
@@ -52,10 +59,16 @@ data Modifier
 --   are disabled for the particular 'Object'.
 type Cannon a = Maybe (V2 a, V2 a)
 
+-- | Objects come in two flavors: 'Static' Objects don't change in the course
+--   of the simulation, but will influence other Objects either by collision
+--   or gravity. They also can never be destroyed.
+--
+--   'Dynamic' objects are affected by physics and are destroyed on collision.
+--   They also may be controlled by a player depending on their 'Modifier'.
 data Object a
   = Dynamic
   { objectHitbox :: Hitbox a      -- ^ hitbox of the object. Hitbox points at
-                                  --   (V2 0 0) will always be at the center of
+                                  --   @(V2 0 0)@ will always be at the center of
                                   --   the object
   , objectRot    :: a             -- ^ Radial angle
   , objectMass   :: a             -- ^ mass of the object in kg
@@ -83,6 +96,15 @@ isDynamic :: Object a -> Bool
 isDynamic Dynamic {} = True
 isDynamic _ = False
 
+-- | Hitboxes are the basis for collision detection and also may be
+--   used as a basis for the graphical representation of 'Object's,
+--   although they probably should be replaced by a more appealing
+--   alternative.
+--
+--   They can be combined from lines and circles and are always
+--   centered around position of the corresponding 'Object',
+--   i. e. @V2 0 0@ of the Hitbox is always at the center of
+--   the object. Also they naturally rotate with the object.
 data Hitbox a
   = HCombined [Hitbox a]
   | HLine
@@ -106,18 +128,24 @@ shipHitbox = HCombined
 centeredCircle :: Num a => a -> Hitbox a
 centeredCircle = HCircle (V2 0 0)
 
+-- | A Modification contains the attributes of an Object that can
+--   be controlled by a player: Rotation, acceleration and firing
+--   of projectiles.
 data Modification a
   = Modification
   { _modRot :: a        -- ^ Rotation (angle in radiant) set by the modification
   , _modAcc :: a        -- ^ Acceleration set by the modification
-  , _modFire :: Integer -- ^ Set to tick a projectile should be fired at
+  , _modFire :: Integer -- ^ Tick a projectile should be fired at
   } deriving (Show, Eq, Ord)
 
 makeLenses ''Modification
 
+-- | 'Modification' that represents the default state of an 'Object'.
 zeroModification :: Num a => Modification a
 zeroModification = Modification 0 0 (-1)
 
+-- | Used to store the 'Modification's for every controllable 'Object'
+--   that is being simulated.
 type ModMap a = Map Modifier (Modification a)
 
 data Grav2tyState a g = Grav2tyState
@@ -125,8 +153,9 @@ data Grav2tyState a g = Grav2tyState
   , _timePerTick :: a                  -- ^ The time between two 'Tick's.
   , _inputs      :: ModMap a           -- ^ 'Modification's that have to be processed in the next tick.
   , _graphics    :: g                  -- ^ Graphics state. Use @()@ if non-graphical.
-  , _world       :: World a
-  , _highestId   :: Id
+  , _world       :: World a            -- ^ All objects.
+  , _highestId   :: Id                 -- ^ Highest 'Id' used in 'World'. This is updated by 'addObject'
+                                       --   in Order to prevent accidental overwrites.
   } deriving (Show, Eq)
 
 makeLenses ''Grav2tyState
@@ -134,9 +163,13 @@ makeLenses ''Grav2tyState
 -- | The 'Grav2ty' Monad is a renamed 'StateT' holding a 'Grav2tyState'.
 type Grav2ty p g m a = StateT (Grav2tyState p g) m a
 
+-- | Shortcut for @'setObject' Nothing@.
 addObject :: Monad m => Object a -> Grav2ty a g m ()
 addObject = setObject Nothing
 
+-- | setObject overwrites or sets the 'Object' at the given 'Id'.
+--   If no 'Id' is given it picks a new 'Id' using '_highestId'
+--   that is guaranteed to be unused (if nothing messed with the 'World').
 setObject :: Monad m => Maybe Id -> Object a -> Grav2ty a g m ()
 setObject id obj = do
   id <- case id of
@@ -146,8 +179,11 @@ setObject id obj = do
             use highestId
   world %= M.insert id obj
 
+-- | Returns the 'Object' at 'Id'.
 getObject :: Monad m => Id -> Grav2ty a g m (Maybe (Object a))
 getObject id = use (world.at id)
 
+-- | Deletes the 'Object' at 'Id'. Note: This doesn't influence '_highestId'
+--   which only ever increases.
 delObject :: Monad m => Id -> Grav2ty a g m ()
 delObject id = world %= M.delete id