vision-0.0.5.0: src/Registry.hs
-- -*-haskell-*-
-- Vision (for the Voice): an XMMS2 client.
--
-- Author: Oleg Belozeorov
-- Created: 13 Jul. 2011
--
-- Copyright (C) 2011 Oleg Belozeorov
--
-- This program is free software; you can redistribute it and/or
-- modify it under the terms of the GNU General Public License as
-- published by the Free Software Foundation; either version 3 of
-- the License, or (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-- General Public License for more details.
--
{-# LANGUAGE MultiParamTypeClasses,
FlexibleInstances,
FlexibleContexts,
OverlappingInstances,
TypeOperators,
DeriveDataTypeable,
UndecidableInstances,
ImplicitParams,
StandaloneDeriving #-}
module Registry
( EnvM
, runIn
, startRegistry
, registryEnv
, RegistryEnvOp
, addEnv
, getEnv
) where
import Control.Monad.Trans
import Control.Monad.EnvIO
import Data.IntMap (IntMap)
import qualified Data.IntMap as IntMap
import Control.Concurrent.STM
import Data.Typeable
import Data.Dynamic
import Data.Env
deriving instance Typeable2 Env
data Ix = Ix deriving Typeable
type EnvMap = TVar (IntMap Dynamic)
registryEnv :: Extract Ix EnvMap
registryEnv = Extract
class (EnvM Ix EnvMap m) => RegistryM m
instance (EnvM Ix EnvMap m) => RegistryM m
startRegistry f = do
v <- newTVarIO $ IntMap.empty
runEnvIO (addEnv Ix v >> f) $ build () $ mkEnv Ix v
class (RegistryM m, Typeable ix, Typeable a) => RegistryEnvOp ix a m
instance (RegistryM m, Typeable ix, Typeable a) => RegistryEnvOp ix a m
addEnv :: RegistryEnvOp ix a m => ix -> a -> m ()
addEnv ix r = do
let val = mkEnv ix r
var <- envx Ix
liftIO $ do
key <- typeRepKey $ typeOf val
atomically $ do
map <- readTVar var
writeTVar var $ IntMap.insert key (toDyn val) map
getEnv :: RegistryEnvOp ix a m => Extract ix a -> m (Maybe (Env ix a))
getEnv spec = do
var <- envx Ix
liftIO $ do
key <- typeRepKey $ typeOf $ env spec
atomically $ do
map <- readTVar var
case IntMap.lookup key map of
Nothing -> return Nothing
Just dv -> return $ fromDynamic dv
where env :: Extract ix a -> Env ix a
env = const undefined