dyna-processing-0.1.0.0: src/Dyna/Proc/Types.hs
module Dyna.Proc.Types where
import Prelude hiding ((<*))
import Control.Applicative (liftA2, liftA3)
import Control.Concurrent.Chan.Unagi
import Control.Monad.Reader
import Control.Monad.Base
import Control.Monad.Random.Class
import Control.Monad.Trans.Control (MonadBaseControl(..))
import Data.IORef
import Data.String
import Data.Boolean
import Data.AdditiveGroup
import Data.AffineSpace
import Data.VectorSpace
import Data.Basis
import Data.Cross
import Temporal.Class
import qualified Dyna as D
import Graphics.Proc hiding ((<*))
-- | Monad that drives the application
newtype Run a = Run { unRun :: ReaderT Env IO a }
deriving (Functor, Applicative, Monad, MonadReader Env,
MonadIO, MonadBase IO, MonadRandom)
newtype StMRun a = StMRun { unStMRun :: StM (ReaderT Env IO) a }
instance MonadBaseControl IO Run where
type StM Run a = StMRun a
liftBaseWith f = Run $ liftBaseWith $ \q -> f (fmap StMRun . q . unRun)
restoreM = Run . restoreM . unStMRun
instance D.Frp Run where
type Ref Run = IORef
runRun :: Run a -> Env -> IO a
runRun (Run act) env = runReaderT act env
------------------------------------------------------------------------------------
-- | Event streams
newtype Evt a = Evt { unEvt :: D.Evt Run a }
deriving (Functor, Semigroup, Monoid, Applicative, Monad,
Melody, Harmony, Compose, Loop)
type instance DurOf (Evt a) = Float
instance Limit (Evt a) where
lim t (Evt evt) = Evt $ lim (realToFrac t) evt
-- | Dynamic values (step-wise continuous process)
newtype Dyn a = Dyn { unDyn :: D.Dyn Run a }
deriving (Functor, Applicative, Num, Fractional, Semigroup, Monoid, IsString,
Boolean, AdditiveGroup, VectorSpace, HasNormal, HasCross2, HasCross3,
AffineSpace, HasBasis)
type instance BooleanOf (Dyn a) = Dyn (BooleanOf a)
instance (IfB a) => IfB (Dyn a) where
ifB = liftA3 ifB
instance (EqB a) => EqB (Dyn a) where
(==*) = liftA2 (==*)
instance (OrdB a) => OrdB (Dyn a) where
(<*) = liftA2 (<*)
(>*) = liftA2 (>*)
(<=*) = liftA2 (<=*)
(>=*) = liftA2 (>=*)
------------------------------------------------------------------------------------
-- environment
-- | All sorts of clicks
data Click = Click (Either Key MouseButton) KeyState Modifiers P2
data KeyState = Up | Down
deriving (Show, Eq)
-- | Applicaition environment
data Env = Env
{ env'resizeChan :: D.UChan (Int, Int)
, env'keyChan :: D.UChan Key
, env'relMousePos :: IORef P2
, env'mousePos :: IORef P2
, env'mouseDif1 :: IORef P2
, env'mouseDif2 :: IORef P2
, env'time :: IORef Float
, env'clicks :: D.UChan Click
}
-- | Create new environment
newEnv :: IO Env
newEnv = do
env'resizeChan <- newChan
env'clicks <- newChan
env'keyChan <- newChan
env'time <- newIORef 0
env'relMousePos <- newIORef (P2 0 0)
env'mousePos <- newIORef (P2 0 0)
env'mouseDif1 <- newIORef (P2 0 0)
env'mouseDif2 <- newIORef (P2 0 0)
pure Env{..}