{-# LANGUAGE RecordWildCards #-}
module Twee.Task(Task, newTask, checkTask) where
import System.CPUTime
import Data.IORef
import Control.Monad.IO.Class
data TaskData m a =
TaskData {
TaskData m a -> Integer
task_start :: !Integer,
TaskData m a -> Integer
task_last :: !Integer,
TaskData m a -> Integer
task_spent :: !Integer,
TaskData m a -> Double
task_frequency :: !Double,
TaskData m a -> Double
task_budget :: !Double,
TaskData m a -> m a
task_what :: m a }
newtype Task m a = Task (IORef (TaskData m a))
newTask :: MonadIO m => Double -> Double -> m a -> m (Task m a)
newTask :: Double -> Double -> m a -> m (Task m a)
newTask Double
freq Double
budget m a
what = IO (Task m a) -> m (Task m a)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Task m a) -> m (Task m a)) -> IO (Task m a) -> m (Task m a)
forall a b. (a -> b) -> a -> b
$ do
Integer
now <- IO Integer
getCPUTime
IORef (TaskData m a) -> Task m a
forall (m :: * -> *) a. IORef (TaskData m a) -> Task m a
Task (IORef (TaskData m a) -> Task m a)
-> IO (IORef (TaskData m a)) -> IO (Task m a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TaskData m a -> IO (IORef (TaskData m a))
forall a. a -> IO (IORef a)
newIORef (Integer
-> Integer -> Integer -> Double -> Double -> m a -> TaskData m a
forall (m :: * -> *) a.
Integer
-> Integer -> Integer -> Double -> Double -> m a -> TaskData m a
TaskData Integer
now Integer
now Integer
0 Double
freq Double
budget m a
what)
checkTask :: MonadIO m => Task m a -> m (Maybe a)
checkTask :: Task m a -> m (Maybe a)
checkTask (Task IORef (TaskData m a)
ref) = do
task :: TaskData m a
task@TaskData{m a
Double
Integer
task_what :: m a
task_budget :: Double
task_frequency :: Double
task_spent :: Integer
task_last :: Integer
task_start :: Integer
task_what :: forall (m :: * -> *) a. TaskData m a -> m a
task_budget :: forall (m :: * -> *) a. TaskData m a -> Double
task_frequency :: forall (m :: * -> *) a. TaskData m a -> Double
task_spent :: forall (m :: * -> *) a. TaskData m a -> Integer
task_last :: forall (m :: * -> *) a. TaskData m a -> Integer
task_start :: forall (m :: * -> *) a. TaskData m a -> Integer
..} <- IO (TaskData m a) -> m (TaskData m a)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (TaskData m a) -> m (TaskData m a))
-> IO (TaskData m a) -> m (TaskData m a)
forall a b. (a -> b) -> a -> b
$ IORef (TaskData m a) -> IO (TaskData m a)
forall a. IORef a -> IO a
readIORef IORef (TaskData m a)
ref
Integer
now <- IO Integer -> m Integer
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO IO Integer
getCPUTime
if Bool -> Bool
not (Integer -> TaskData m a -> Bool
forall (m :: * -> *) a. Integer -> TaskData m a -> Bool
taskDue Integer
now TaskData m a
task) then Maybe a -> m (Maybe a)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe a
forall a. Maybe a
Nothing else do
a
res <- m a
task_what
Integer
after <- IO Integer -> m Integer
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO IO Integer
getCPUTime
IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$ IORef (TaskData m a) -> TaskData m a -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef IORef (TaskData m a)
ref TaskData m a
task {
task_last :: Integer
task_last = Integer
after,
task_spent :: Integer
task_spent = Integer
task_spent Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ (Integer
afterInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
-Integer
now) }
Maybe a -> m (Maybe a)
forall (m :: * -> *) a. Monad m => a -> m a
return (a -> Maybe a
forall a. a -> Maybe a
Just a
res)
taskDue :: Integer -> TaskData m a -> Bool
taskDue :: Integer -> TaskData m a -> Bool
taskDue Integer
now TaskData{m a
Double
Integer
task_what :: m a
task_budget :: Double
task_frequency :: Double
task_spent :: Integer
task_last :: Integer
task_start :: Integer
task_what :: forall (m :: * -> *) a. TaskData m a -> m a
task_budget :: forall (m :: * -> *) a. TaskData m a -> Double
task_frequency :: forall (m :: * -> *) a. TaskData m a -> Double
task_spent :: forall (m :: * -> *) a. TaskData m a -> Integer
task_last :: forall (m :: * -> *) a. TaskData m a -> Integer
task_start :: forall (m :: * -> *) a. TaskData m a -> Integer
..} =
Integer -> Double
forall a. Num a => Integer -> a
fromInteger (Integer
now Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
task_last) Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
>= Double
task_frequency Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
10Double -> Integer -> Double
forall a b. (Num a, Integral b) => a -> b -> a
^Integer
12 Bool -> Bool -> Bool
&&
Integer -> Double
forall a. Num a => Integer -> a
fromInteger (Integer
now Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
task_start) Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
task_budget Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
> Integer -> Double
forall a. Num a => Integer -> a
fromInteger Integer
task_spent