packages feed

blucontrol 0.3.1.0 → 0.3.2.0

raw patch · 10 files changed

+124/−61 lines, 10 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

- Blucontrol.Main.Control: data ControlT c m a
- Blucontrol.Main.Control: instance Control.Monad.Base.MonadBase b m => Control.Monad.Base.MonadBase b (Blucontrol.Main.Control.ControlT c m)
- Blucontrol.Main.Control: instance Control.Monad.Trans.Class.MonadTrans (Blucontrol.Main.Control.ControlT c)
- Blucontrol.Main.Control: instance Control.Monad.Trans.Control.MonadBaseControl b m => Control.Monad.Trans.Control.MonadBaseControl b (Blucontrol.Main.Control.ControlT c m)
- Blucontrol.Main.Control: instance Control.Monad.Trans.Control.MonadTransControl (Blucontrol.Main.Control.ControlT c)
- Blucontrol.Main.Control: instance GHC.Base.Applicative m => GHC.Base.Applicative (Blucontrol.Main.Control.ControlT c m)
- Blucontrol.Main.Control: instance GHC.Base.Functor m => GHC.Base.Functor (Blucontrol.Main.Control.ControlT c m)
- Blucontrol.Main.Control: instance GHC.Base.Monad m => GHC.Base.Monad (Blucontrol.Main.Control.ControlT c m)
- Blucontrol.Main.Control: runControlT :: Monad m => ControlT c m a -> m a
+ Blucontrol.Gamma.Linear: instance (Blucontrol.RGB.RGB Blucontrol.RGB.Temperature.Temperature, Control.Monad.Base.MonadBase GHC.Types.IO m) => Blucontrol.Gamma.MonadGamma (Blucontrol.RGB.Brightness.WithBrightness Blucontrol.RGB.Temperature.Temperature) (Blucontrol.Gamma.Linear.GammaLinearT (Blucontrol.RGB.Brightness.WithBrightness Blucontrol.RGB.Temperature.Temperature) m)
+ Blucontrol.Gamma.Linear: instance (Blucontrol.RGB.RGB Blucontrol.RGB.Trichromaticity, Control.Monad.Base.MonadBase GHC.Types.IO m) => Blucontrol.Gamma.MonadGamma (Blucontrol.RGB.Brightness.WithBrightness Blucontrol.RGB.Trichromaticity) (Blucontrol.Gamma.Linear.GammaLinearT (Blucontrol.RGB.Brightness.WithBrightness Blucontrol.RGB.Trichromaticity) m)
+ Blucontrol.RGB.Brightness: WithBrightness :: Brightness -> a -> WithBrightness a
+ Blucontrol.RGB.Brightness: [brightness] :: WithBrightness a -> Brightness
+ Blucontrol.RGB.Brightness: [rgb] :: WithBrightness a -> a
+ Blucontrol.RGB.Brightness: data Brightness
+ Blucontrol.RGB.Brightness: data WithBrightness a
+ Blucontrol.RGB.Brightness: instance Blucontrol.RGB.RGB a => Blucontrol.RGB.RGB (Blucontrol.RGB.Brightness.WithBrightness a)
+ Blucontrol.RGB.Brightness: instance Control.DeepSeq.NFData Blucontrol.RGB.Brightness.Brightness
+ Blucontrol.RGB.Brightness: instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Blucontrol.RGB.Brightness.WithBrightness a)
+ Blucontrol.RGB.Brightness: instance Data.Default.Class.Default Blucontrol.RGB.Brightness.Brightness
+ Blucontrol.RGB.Brightness: instance Data.Default.Class.Default a => Data.Default.Class.Default (Blucontrol.RGB.Brightness.WithBrightness a)
+ Blucontrol.RGB.Brightness: instance GHC.Classes.Eq Blucontrol.RGB.Brightness.Brightness
+ Blucontrol.RGB.Brightness: instance GHC.Classes.Eq a => GHC.Classes.Eq (Blucontrol.RGB.Brightness.WithBrightness a)
+ Blucontrol.RGB.Brightness: instance GHC.Classes.Ord Blucontrol.RGB.Brightness.Brightness
+ Blucontrol.RGB.Brightness: instance GHC.Classes.Ord a => GHC.Classes.Ord (Blucontrol.RGB.Brightness.WithBrightness a)
+ Blucontrol.RGB.Brightness: instance GHC.Enum.Bounded Blucontrol.RGB.Brightness.Brightness
+ Blucontrol.RGB.Brightness: instance GHC.Enum.Enum Blucontrol.RGB.Brightness.Brightness
+ Blucontrol.RGB.Brightness: instance GHC.Generics.Generic (Blucontrol.RGB.Brightness.WithBrightness a)
+ Blucontrol.RGB.Brightness: instance GHC.Generics.Generic Blucontrol.RGB.Brightness.Brightness
+ Blucontrol.RGB.Brightness: instance GHC.Num.Num Blucontrol.RGB.Brightness.Brightness
+ Blucontrol.RGB.Brightness: instance GHC.Read.Read Blucontrol.RGB.Brightness.Brightness
+ Blucontrol.RGB.Brightness: instance GHC.Read.Read a => GHC.Read.Read (Blucontrol.RGB.Brightness.WithBrightness a)
+ Blucontrol.RGB.Brightness: instance GHC.Real.Fractional Blucontrol.RGB.Brightness.Brightness
+ Blucontrol.RGB.Brightness: instance GHC.Real.Real Blucontrol.RGB.Brightness.Brightness
+ Blucontrol.RGB.Brightness: instance GHC.Real.RealFrac Blucontrol.RGB.Brightness.Brightness
+ Blucontrol.RGB.Brightness: instance GHC.Show.Show Blucontrol.RGB.Brightness.Brightness
+ Blucontrol.RGB.Brightness: instance GHC.Show.Show a => GHC.Show.Show (Blucontrol.RGB.Brightness.WithBrightness a)
- Blucontrol: ConfigControl :: (forall a. m a -> IO a) -> (forall a. g a -> IO (StM g a)) -> (forall a. r a -> g (StM r a)) -> ConfigControl m g r
+ Blucontrol: ConfigControl :: (forall a. m a -> IO a) -> (forall a. g a -> IO (StM g a)) -> (forall a. r a -> IO (StM r a)) -> ConfigControl m g r
- Blucontrol: [runRecolor] :: ConfigControl m g r -> forall a. r a -> g (StM r a)
+ Blucontrol: [runRecolor] :: ConfigControl m g r -> forall a. r a -> IO (StM r a)
- Blucontrol.Main: ConfigControl :: (forall a. m a -> IO a) -> (forall a. g a -> IO (StM g a)) -> (forall a. r a -> g (StM r a)) -> ConfigControl m g r
+ Blucontrol.Main: ConfigControl :: (forall a. m a -> IO a) -> (forall a. g a -> IO (StM g a)) -> (forall a. r a -> IO (StM r a)) -> ConfigControl m g r
- Blucontrol.Main: [runRecolor] :: ConfigControl m g r -> forall a. r a -> g (StM r a)
+ Blucontrol.Main: [runRecolor] :: ConfigControl m g r -> forall a. r a -> IO (StM r a)
- Blucontrol.Main.Control: ConfigControl :: (forall a. m a -> IO a) -> (forall a. g a -> IO (StM g a)) -> (forall a. r a -> g (StM r a)) -> ConfigControl m g r
+ Blucontrol.Main.Control: ConfigControl :: (forall a. m a -> IO a) -> (forall a. g a -> IO (StM g a)) -> (forall a. r a -> IO (StM r a)) -> ConfigControl m g r
- Blucontrol.Main.Control: [runRecolor] :: ConfigControl m g r -> forall a. r a -> g (StM r a)
+ Blucontrol.Main.Control: [runRecolor] :: ConfigControl m g r -> forall a. r a -> IO (StM r a)
- Blucontrol.Main.Control: loopRecolor :: (ControlConstraint m (StM g (StM r ())), MonadBaseControl IO g, MonadBaseControl IO r, MonadControl m, MonadGamma c g, MonadRecolor r) => (forall a. g a -> IO (StM g a)) -> (forall a. r a -> g (StM r a)) -> ControlT c m ()
+ Blucontrol.Main.Control: loopRecolor :: (ControlConstraint m (StM g (StM r ())), MonadBaseControl IO g, MonadBaseControl IO r, MonadControl m, MonadGamma c g, MonadRecolor r) => (forall a. g a -> IO (StM g a)) -> (forall a. r a -> IO (StM r a)) -> m ()

Files

CHANGELOG.md view
@@ -1,5 +1,11 @@ # Revision history for blucontrol +## 0.3.2.0 *04 Jun 2021*++* New module `Blucontrol.RGB.Brightness`.+* Introduce strictness to improve performance.+* Allow `runGamma` to directly run in the `IO` monad instead of `g` with `MonadGamma c g`.+ ## 0.3.1.0 *30 May 2021*  * New module `Blucontrol.Gamma.Modifier`.
blucontrol.cabal view
@@ -1,5 +1,5 @@ name:                blucontrol-version:             0.3.1.0+version:             0.3.2.0 synopsis:            Configurable blue light filter description:         This application is a blue light filter, with the main focus on                      configurability.@@ -41,6 +41,7 @@                        Blucontrol.Recolor.Print                        Blucontrol.Recolor.X                        Blucontrol.RGB+                       Blucontrol.RGB.Brightness                        Blucontrol.RGB.Temperature   other-modules:       Blucontrol.Main.GHC.Internal                        Blucontrol.Recolor.X.Internal@@ -69,7 +70,8 @@   c-sources:           include/XrandrGamma.c                        include/XrandrGamma.h   default-language:    Haskell2010-  default-extensions:  ConstraintKinds+  default-extensions:  BangPatterns+                       ConstraintKinds                        DataKinds                        DeriveGeneric                        FlexibleContexts@@ -106,7 +108,8 @@                      , QuickCheck   >= 2.13.2  && < 2.15                      , time   default-language:    Haskell2010-  default-extensions:  ConstraintKinds+  default-extensions:  BangPatterns+                       ConstraintKinds                        DataKinds                        DeriveGeneric                        FlexibleContexts
src/Blucontrol/Control/Count.hs view
@@ -24,17 +24,11 @@ instance MonadTrans ControlCountT where   lift = ControlCountT . lift . lift --- TODO: workaround for ghc-9.0.1-defaultLiftWith2' :: (Monad m)-                  => (Run ControlCountT -> m a)-                  -> ControlCountT m a-defaultLiftWith2' f = ControlCountT $ liftWith $ \run -> liftWith $ \run' -> f $ run' . run . unControlCountT- instance MonadTransControl ControlCountT where   type StT ControlCountT a = StT (ReaderT ConfigCount) (StT (StateT Natural) a)   -- TODO: workaround for ghc-9.0.1   --liftWith = defaultLiftWith2 ControlCountT unControlCountT-  liftWith = defaultLiftWith2'+  liftWith f = ControlCountT $ liftWith $ \run -> liftWith $ \run' -> f $ run' . run . unControlCountT   restoreT = defaultRestoreT2 ControlCountT  instance MonadBaseControl IO m => MonadControl (ControlCountT m) where@@ -49,7 +43,7 @@                         else return ()  runControlCountT :: Monad m => ConfigCount -> ControlCountT m a -> m a-runControlCountT conf tma = runReaderT (evalStateT (unControlCountT tma) 0) conf+runControlCountT !conf tma = runReaderT (evalStateT (unControlCountT tma) 0) conf  newtype ConfigCount = ConfigCount { maxCount :: Natural                                   }
src/Blucontrol/Control/Wait.hs view
@@ -25,7 +25,7 @@   doInbetween _ = liftBase . threadDelay . interval =<< ControlWaitT ask  runControlWaitT :: ConfigWait -> ControlWaitT m a -> m a-runControlWaitT conf tma = runReaderT (unControlWaitT tma) conf+runControlWaitT !conf tma = runReaderT (unControlWaitT tma) conf  newtype ConfigWait = ConfigWait { interval :: Microseconds                                 }
src/Blucontrol/Gamma/Const.hs view
@@ -25,4 +25,4 @@   gamma = GammaConstT ask  runGammaConstT :: RGB c => c -> GammaConstT c m a -> m a-runGammaConstT rgb tma = runReaderT (unGammaConstT tma) rgb+runGammaConstT !rgb tma = runReaderT (unGammaConstT tma) rgb
src/Blucontrol/Gamma/Linear.hs view
@@ -26,6 +26,7 @@  import Blucontrol.Gamma import Blucontrol.RGB+import Blucontrol.RGB.Brightness import Blucontrol.RGB.Temperature  newtype GammaLinearT c m a = GammaLinearT { unGammaLinearT :: ReaderT (M.Map TimeOfDay c) m a }@@ -42,6 +43,20 @@ instance MonadBase IO m => MonadGamma Temperature (GammaLinearT Temperature m) where   gamma = calculateRGB weightedAverageTemperature . zonedTimeToLocalTime =<< liftBase getZonedTime +instance (RGB Trichromaticity, MonadBase IO m) => MonadGamma (WithBrightness Trichromaticity) (GammaLinearT (WithBrightness Trichromaticity) m) where+  gamma = calculateRGB weightedAverage . zonedTimeToLocalTime =<< liftBase getZonedTime+    where weightedAverage w WithBrightness { brightness = b1, rgb = tc1 } WithBrightness { brightness = b2, rgb = tc2 } =+            WithBrightness { brightness = weightedAverageBrightness w b1 b2+                           , rgb = weightedAverageTrichromaticity w tc1 tc2+                           }++instance (RGB Temperature, MonadBase IO m) => MonadGamma (WithBrightness Temperature) (GammaLinearT (WithBrightness Temperature) m) where+  gamma = calculateRGB weightedAverage . zonedTimeToLocalTime =<< liftBase getZonedTime+    where weightedAverage w WithBrightness { brightness = b1, rgb = tc1 } WithBrightness { brightness = b2, rgb = tc2 } =+            WithBrightness { brightness = weightedAverageBrightness w b1 b2+                           , rgb = weightedAverageTemperature w tc1 tc2+                           }+ nextTimeRGB :: M.Map TimeOfDay c -> LocalTime -> Maybe (LocalTime,c) nextTimeRGB m time = catchError (toLocalTimeToday <$> M.lookupGT (localTimeOfDay time) m) $                      const (toLocalTimeTomorrow <$> M.lookupMin m)@@ -86,9 +101,12 @@ weightedAverageTemperature :: Rational -> Temperature -> Temperature -> Temperature weightedAverageTemperature w t1 t2 = fromRational $ toRational t1 + w * (toRational t2 - toRational t1) +weightedAverageBrightness :: Rational -> Brightness -> Brightness -> Brightness+weightedAverageBrightness w b1 b2 = fromRational $ toRational b1 + w * (toRational b2 - toRational b1)+ -- TODO: maybe remove RGB constraint runGammaLinearT' :: RGB c => M.Map TimeOfDay c -> GammaLinearT c m a -> m a-runGammaLinearT' rgbs tma = runReaderT (unGammaLinearT tma) rgbs+runGammaLinearT' !rgbs tma = runReaderT (unGammaLinearT tma) rgbs  -- TODO: maybe remove RGB constraint runGammaLinearT :: RGB c => N.NonEmpty (TimeOfDay,c) -> GammaLinearT c m a -> m a
src/Blucontrol/Main.hs view
@@ -15,4 +15,4 @@            => ConfigControl m g r            -> IO () blucontrol c = do launch-                  runControl c . runControlT $ loopRecolor (runGamma c) (runRecolor c)+                  runControl c $ loopRecolor (runGamma c) (runRecolor c)
src/Blucontrol/Main/Control.hs view
@@ -1,9 +1,5 @@-{-# LANGUAGE UndecidableInstances #-}- module Blucontrol.Main.Control (-  ControlT-, runControlT-, loopRecolor+  loopRecolor , ConfigControl (..) ) where @@ -17,40 +13,44 @@ import Blucontrol.Recolor import Blucontrol.RGB -newtype ControlT c m a = ControlT { unControlT :: m a }-  deriving (Applicative, Functor, Monad, MonadBase b, MonadBaseControl b)--instance MonadTrans (ControlT c) where-  lift = ControlT--instance MonadTransControl (ControlT c) where-  type StT (ControlT c) a = a-  liftWith inner = ControlT $ inner unControlT-  restoreT = ControlT--runControlT :: Monad m-            => ControlT c m a-            -> m a-runControlT = unControlT-+-- | Run the loop, using `gamma`, `recolor` and `doInbetween`.+-- The arguments are the actual monad runners. loopRecolor :: (ControlConstraint m (StM g (StM r ())), MonadBaseControl IO g, MonadBaseControl IO r, MonadControl m, MonadGamma c g, MonadRecolor r)             => (forall a. g a -> IO (StM g a))-            -> (forall a. r a -> g (StM r a))-            -> ControlT c m ()-loopRecolor runG runR = do-  a <- liftBase doRecolorGamma-  ControlT $ evalStateT doLoopRecolor a-  where doRecolorGamma = runG $ do-          rgb <- toRGB <$> gamma-          runR $ recolor rgb-        doLoopRecolor = do-          a' <- get-          lift $ doInbetween a'-          a'' <- liftBase doRecolorGamma-          put a''-          doLoopRecolor+            -> (forall a. r a -> IO (StM r a))+            -> m ()+loopRecolor runG runR = void $+  liftBaseWith $ \ runCIO ->+    runR $ liftBaseWith $ \ runRIO ->+      runG $ liftBaseWith $ \ runGIO -> do+        firstResult <- doRecolorGamma runGIO runRIO+        evalStateT (doLoopRecolor runCIO runGIO runRIO) firstResult +-- | Use `gamma` and give the result to `recolor`.+-- The arguments are runners from `liftBaseWith`.+doRecolorGamma :: (MonadBaseControl IO g, MonadBaseControl IO r, MonadGamma c g, MonadRecolor r)+               => (forall a. g a -> IO (StM g a))+               -> (forall a. r a -> IO (StM r a))+               -> IO (StM g (StM r ()))+doRecolorGamma runGIO runRIO = runGIO $ do+  rgb <- toRGB <$> gamma+  liftBase $ runRIO $ recolor rgb++-- | A single iteration of `loopRecolor`.+-- The arguments are runners from `liftBaseWith`.+doLoopRecolor :: (ControlConstraint m (StM g (StM r ())), MonadBaseControl IO g, MonadBaseControl IO r, MonadControl m, MonadGamma c g, MonadRecolor r)+              => (forall a. m a -> IO (StM m a))+              -> (forall a. g a -> IO (StM g a))+              -> (forall a. r a -> IO (StM r a))+              -> StateT (StM g (StM r ())) IO ()+doLoopRecolor runCIO runGIO runRIO = do+  lastResult <- get+  void $ liftBase $ runCIO $ doInbetween lastResult+  nextResult <- liftBase $ doRecolorGamma runGIO runRIO+  put nextResult+  doLoopRecolor runCIO runGIO runRIO+ data ConfigControl m g r = ConfigControl { runControl :: forall a. m a -> IO a                                          , runGamma   :: forall a. g a -> IO (StM g a)-                                         , runRecolor :: forall a. r a -> g (StM r a)+                                         , runRecolor :: forall a. r a -> IO (StM r a)                                          }
+ src/Blucontrol/RGB/Brightness.hs view
@@ -0,0 +1,49 @@+{-# LANGUAGE RecordWildCards #-}++module Blucontrol.RGB.Brightness (+  Brightness+, WithBrightness (..)+) where++import Control.DeepSeq+import Data.Default+import GHC.Generics++import Blucontrol.RGB++-- | Arbitrary precision brightness between 0 and 1+newtype Brightness = Brightness Rational+  deriving (Enum, Eq, Fractional, Generic, Num, Ord, Read, Real, RealFrac, Show)++instance NFData Brightness++instance Bounded Brightness where+  minBound = 0+  maxBound = 1++instance Default Brightness where+  def = 1++-- | Parametric RGB value with an associated brightness+data WithBrightness a = WithBrightness { brightness :: Brightness+                                       , rgb :: a+                                       }+  deriving (Eq, Generic, Ord, Read, Show)++instance NFData a => NFData (WithBrightness a)++instance Default a => Default (WithBrightness a) where+  def = WithBrightness { brightness = def+                       , rgb = def+                       }++-- TODO: maybe create separate instances for Trichromaticity and Temperature+instance RGB a => RGB (WithBrightness a) where+  toRGB WithBrightness {..} = mapChromaticity applyBrightness $ toRGB rgb+      where applyBrightness = truncate . (toRational brightness *) . toRational++mapChromaticity :: (Chromaticity -> Chromaticity) -> Trichromaticity -> Trichromaticity+mapChromaticity f rgb = Trichromaticity { red = f $ red rgb+                                        , green = f $ green rgb+                                        , blue = f $ blue rgb+                                        }
src/Blucontrol/Recolor/X.hs view
@@ -31,18 +31,11 @@ instance MonadTrans RecolorXT where   lift = RecolorXT . lift . lift --- TODO: ghc-9.0.1 can't unify 'Run RecolorXT' and 'RunDefault2 RecolorXT n n'', when using 'defaultLiftWith2'--- current solution is the exact same on the value level, but uses 'Run RecolorXT' on the type level-defaultLiftWith2' :: Monad n-                  => (Run RecolorXT -> n a)-                  -> RecolorXT n a-defaultLiftWith2' f = RecolorXT $ liftWith $ \run -> liftWith $ \run' -> f $ run' . run . unRecolorXT- instance MonadTransControl RecolorXT where   type StT RecolorXT a = StT (ReaderT Display) (StT (ExceptT XError) a)   -- TODO: broken by ghc-9.0.1-  -- liftWith = defaultLiftWith2' RecolorXT unRecolorXT-  liftWith = defaultLiftWith2'+  -- liftWith = defaultLiftWith2 RecolorXT unRecolorXT+  liftWith f = RecolorXT $ liftWith $ \run -> liftWith $ \run' -> f $ run' . run . unRecolorXT   restoreT = defaultRestoreT2 RecolorXT  instance MonadBaseControl IO m => MonadRecolor (RecolorXT m) where@@ -83,7 +76,7 @@   where throwXError (SomeException _) = throwError xError  runRecolorXTIO :: MonadBaseControl IO m => ConfigX -> RecolorXT m a -> m (Either XError a)-runRecolorXTIO conf tma = runExceptT $ bracket open close run+runRecolorXTIO !conf tma = runExceptT $ bracket open close run   where open = liftXIO XErrorOpenDisplay $ openDisplay $ showDisplay conf         close display = liftXIO XErrorCloseDisplay $ closeDisplay display         run display = restoreT $ runRecolorXT display tma