module Csound.Typed.GlobalState.Cache(
    Cache(..), HashKey,    
    -- * Mix
    -- ** Functions
    CacheMix, MixKey(..),
    saveMixKey, getMixKey,
    -- ** Procedures
    CacheMixProc, 
    saveMixProcKey, getMixProcKey,
    -- * Evt
    -- ** Functions
    CacheEvt, EvtKey(..),
    saveEvtKey, getEvtKey,
    -- ** Procedures
    CacheEvtProc, 
    saveEvtProcKey, getEvtProcKey
) where

import qualified Data.Map as M
import Data.Default

import Csound.Dynamic

data Cache m = Cache 
    { Cache m -> CacheMix
cacheMix      :: CacheMix
    , Cache m -> CacheMixProc m
cacheMixProc  :: CacheMixProc m
    , Cache m -> CacheEvt
cacheEvt      :: CacheEvt
    , Cache m -> CacheEvtProc m
cacheEvtProc  :: CacheEvtProc m }

instance Default (Cache m) where
    def :: Cache m
def = CacheMix -> CacheMixProc m -> CacheEvt -> CacheEvtProc m -> Cache m
forall (m :: * -> *).
CacheMix -> CacheMixProc m -> CacheEvt -> CacheEvtProc m -> Cache m
Cache CacheMix
forall a. Default a => a
def CacheMixProc m
forall a. Default a => a
def CacheEvt
forall a. Default a => a
def CacheEvtProc m
forall a. Default a => a
def

type HashKey = Int

type GetKey  m a b = a -> Cache m -> Maybe b
type SaveKey m a b = a -> b -> Cache m -> Cache m

getKeyMap :: (Ord key) => (Cache m -> M.Map key val) -> GetKey m key val
getKeyMap :: (Cache m -> Map key val) -> GetKey m key val
getKeyMap Cache m -> Map key val
f key
key Cache m
x = key -> Map key val -> Maybe val
forall k a. Ord k => k -> Map k a -> Maybe a
M.lookup key
key (Map key val -> Maybe val) -> Map key val -> Maybe val
forall a b. (a -> b) -> a -> b
$ Cache m -> Map key val
f Cache m
x

saveKeyMap :: (Ord key) => (Cache m -> M.Map key val) -> (M.Map key val -> Cache m -> Cache m) -> SaveKey m key val
saveKeyMap :: (Cache m -> Map key val)
-> (Map key val -> Cache m -> Cache m) -> SaveKey m key val
saveKeyMap Cache m -> Map key val
getter Map key val -> Cache m -> Cache m
setter key
key val
val Cache m
cache = Map key val -> Cache m -> Cache m
setter (key -> val -> Map key val -> Map key val
forall k a. Ord k => k -> a -> Map k a -> Map k a
M.insert key
key val
val (Map key val -> Map key val) -> Map key val -> Map key val
forall a b. (a -> b) -> a -> b
$ Cache m -> Map key val
getter Cache m
cache) Cache m
cache

----------------------------------------------------------
-- Mix

-- Mix functions

newtype MixKey = MixKey HashKey
    deriving (MixKey -> MixKey -> Bool
(MixKey -> MixKey -> Bool)
-> (MixKey -> MixKey -> Bool) -> Eq MixKey
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: MixKey -> MixKey -> Bool
$c/= :: MixKey -> MixKey -> Bool
== :: MixKey -> MixKey -> Bool
$c== :: MixKey -> MixKey -> Bool
Eq, Eq MixKey
Eq MixKey
-> (MixKey -> MixKey -> Ordering)
-> (MixKey -> MixKey -> Bool)
-> (MixKey -> MixKey -> Bool)
-> (MixKey -> MixKey -> Bool)
-> (MixKey -> MixKey -> Bool)
-> (MixKey -> MixKey -> MixKey)
-> (MixKey -> MixKey -> MixKey)
-> Ord MixKey
MixKey -> MixKey -> Bool
MixKey -> MixKey -> Ordering
MixKey -> MixKey -> MixKey
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: MixKey -> MixKey -> MixKey
$cmin :: MixKey -> MixKey -> MixKey
max :: MixKey -> MixKey -> MixKey
$cmax :: MixKey -> MixKey -> MixKey
>= :: MixKey -> MixKey -> Bool
$c>= :: MixKey -> MixKey -> Bool
> :: MixKey -> MixKey -> Bool
$c> :: MixKey -> MixKey -> Bool
<= :: MixKey -> MixKey -> Bool
$c<= :: MixKey -> MixKey -> Bool
< :: MixKey -> MixKey -> Bool
$c< :: MixKey -> MixKey -> Bool
compare :: MixKey -> MixKey -> Ordering
$ccompare :: MixKey -> MixKey -> Ordering
$cp1Ord :: Eq MixKey
Ord)

type    MixVal = InstrId

type CacheMix = M.Map MixKey MixVal

getMixKey :: GetKey m MixKey MixVal
getMixKey :: GetKey m MixKey MixVal
getMixKey = (Cache m -> CacheMix) -> GetKey m MixKey MixVal
forall key (m :: * -> *) val.
Ord key =>
(Cache m -> Map key val) -> GetKey m key val
getKeyMap Cache m -> CacheMix
forall (m :: * -> *). Cache m -> CacheMix
cacheMix

saveMixKey :: SaveKey m MixKey MixVal
saveMixKey :: SaveKey m MixKey MixVal
saveMixKey = (Cache m -> CacheMix)
-> (CacheMix -> Cache m -> Cache m) -> SaveKey m MixKey MixVal
forall key (m :: * -> *) val.
Ord key =>
(Cache m -> Map key val)
-> (Map key val -> Cache m -> Cache m) -> SaveKey m key val
saveKeyMap Cache m -> CacheMix
forall (m :: * -> *). Cache m -> CacheMix
cacheMix (\CacheMix
a Cache m
x -> Cache m
x { cacheMix :: CacheMix
cacheMix = CacheMix
a })

-- Mix procedures

type CacheMixProc m = M.Map MixKey (DepT m ())

getMixProcKey :: GetKey m MixKey (DepT m ())
getMixProcKey :: GetKey m MixKey (DepT m ())
getMixProcKey = (Cache m -> Map MixKey (DepT m ())) -> GetKey m MixKey (DepT m ())
forall key (m :: * -> *) val.
Ord key =>
(Cache m -> Map key val) -> GetKey m key val
getKeyMap Cache m -> Map MixKey (DepT m ())
forall (m :: * -> *). Cache m -> CacheMixProc m
cacheMixProc

saveMixProcKey :: SaveKey m MixKey (DepT m ())
saveMixProcKey :: SaveKey m MixKey (DepT m ())
saveMixProcKey = (Cache m -> Map MixKey (DepT m ()))
-> (Map MixKey (DepT m ()) -> Cache m -> Cache m)
-> SaveKey m MixKey (DepT m ())
forall key (m :: * -> *) val.
Ord key =>
(Cache m -> Map key val)
-> (Map key val -> Cache m -> Cache m) -> SaveKey m key val
saveKeyMap Cache m -> Map MixKey (DepT m ())
forall (m :: * -> *). Cache m -> CacheMixProc m
cacheMixProc (\Map MixKey (DepT m ())
a Cache m
x -> Cache m
x { cacheMixProc :: Map MixKey (DepT m ())
cacheMixProc = Map MixKey (DepT m ())
a })

----------------------------------------------------------
-- Evt

-- Evt functions

data EvtKey = EvtKey HashKey HashKey
    deriving (EvtKey -> EvtKey -> Bool
(EvtKey -> EvtKey -> Bool)
-> (EvtKey -> EvtKey -> Bool) -> Eq EvtKey
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: EvtKey -> EvtKey -> Bool
$c/= :: EvtKey -> EvtKey -> Bool
== :: EvtKey -> EvtKey -> Bool
$c== :: EvtKey -> EvtKey -> Bool
Eq, Eq EvtKey
Eq EvtKey
-> (EvtKey -> EvtKey -> Ordering)
-> (EvtKey -> EvtKey -> Bool)
-> (EvtKey -> EvtKey -> Bool)
-> (EvtKey -> EvtKey -> Bool)
-> (EvtKey -> EvtKey -> Bool)
-> (EvtKey -> EvtKey -> EvtKey)
-> (EvtKey -> EvtKey -> EvtKey)
-> Ord EvtKey
EvtKey -> EvtKey -> Bool
EvtKey -> EvtKey -> Ordering
EvtKey -> EvtKey -> EvtKey
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: EvtKey -> EvtKey -> EvtKey
$cmin :: EvtKey -> EvtKey -> EvtKey
max :: EvtKey -> EvtKey -> EvtKey
$cmax :: EvtKey -> EvtKey -> EvtKey
>= :: EvtKey -> EvtKey -> Bool
$c>= :: EvtKey -> EvtKey -> Bool
> :: EvtKey -> EvtKey -> Bool
$c> :: EvtKey -> EvtKey -> Bool
<= :: EvtKey -> EvtKey -> Bool
$c<= :: EvtKey -> EvtKey -> Bool
< :: EvtKey -> EvtKey -> Bool
$c< :: EvtKey -> EvtKey -> Bool
compare :: EvtKey -> EvtKey -> Ordering
$ccompare :: EvtKey -> EvtKey -> Ordering
$cp1Ord :: Eq EvtKey
Ord)

type    EvtVal = InstrId

type CacheEvt = M.Map EvtKey EvtVal

getEvtKey :: GetKey m EvtKey EvtVal
getEvtKey :: GetKey m EvtKey MixVal
getEvtKey = (Cache m -> CacheEvt) -> GetKey m EvtKey MixVal
forall key (m :: * -> *) val.
Ord key =>
(Cache m -> Map key val) -> GetKey m key val
getKeyMap Cache m -> CacheEvt
forall (m :: * -> *). Cache m -> CacheEvt
cacheEvt

saveEvtKey :: SaveKey m EvtKey EvtVal
saveEvtKey :: SaveKey m EvtKey MixVal
saveEvtKey = (Cache m -> CacheEvt)
-> (CacheEvt -> Cache m -> Cache m) -> SaveKey m EvtKey MixVal
forall key (m :: * -> *) val.
Ord key =>
(Cache m -> Map key val)
-> (Map key val -> Cache m -> Cache m) -> SaveKey m key val
saveKeyMap Cache m -> CacheEvt
forall (m :: * -> *). Cache m -> CacheEvt
cacheEvt (\CacheEvt
a Cache m
x -> Cache m
x { cacheEvt :: CacheEvt
cacheEvt = CacheEvt
a })

-- Evt procedures

type CacheEvtProc m = M.Map EvtKey (DepT m ())

getEvtProcKey :: GetKey m EvtKey (DepT m ())
getEvtProcKey :: GetKey m EvtKey (DepT m ())
getEvtProcKey = (Cache m -> Map EvtKey (DepT m ())) -> GetKey m EvtKey (DepT m ())
forall key (m :: * -> *) val.
Ord key =>
(Cache m -> Map key val) -> GetKey m key val
getKeyMap Cache m -> Map EvtKey (DepT m ())
forall (m :: * -> *). Cache m -> CacheEvtProc m
cacheEvtProc

saveEvtProcKey :: SaveKey m EvtKey (DepT m ())
saveEvtProcKey :: SaveKey m EvtKey (DepT m ())
saveEvtProcKey = (Cache m -> Map EvtKey (DepT m ()))
-> (Map EvtKey (DepT m ()) -> Cache m -> Cache m)
-> SaveKey m EvtKey (DepT m ())
forall key (m :: * -> *) val.
Ord key =>
(Cache m -> Map key val)
-> (Map key val -> Cache m -> Cache m) -> SaveKey m key val
saveKeyMap Cache m -> Map EvtKey (DepT m ())
forall (m :: * -> *). Cache m -> CacheEvtProc m
cacheEvtProc (\Map EvtKey (DepT m ())
a Cache m
x -> Cache m
x { cacheEvtProc :: Map EvtKey (DepT m ())
cacheEvtProc = Map EvtKey (DepT m ())
a })