From 887868b64465aeb1dbe0aef20ad756a3c24684ac Mon Sep 17 00:00:00 2001
From: Jens Nolte <git@queezle.net>
Date: Fri, 11 Feb 2022 16:15:26 +0100
Subject: [PATCH] Add constructor and accessors for Quasar fields

---
 src/Quasar/Monad.hs | 51 +++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 47 insertions(+), 4 deletions(-)

diff --git a/src/Quasar/Monad.hs b/src/Quasar/Monad.hs
index 833f7b6..2d0ff67 100644
--- a/src/Quasar/Monad.hs
+++ b/src/Quasar/Monad.hs
@@ -3,25 +3,58 @@ module Quasar.Monad (
   newQuasar,
 
   MonadQuasar(..),
+  askIOWorker,
+  askExceptionChannel,
+  askResourceManager,
 
   QuasarT,
   QuasarIO,
   QuasarSTM,
-
 ) where
 
 import Control.Concurrent.STM
+import Control.Monad.Reader
+import GHC.Records (HasField(..))
 import Quasar.Async.STMHelper
 import Quasar.Exceptions
 import Quasar.Prelude
-import Quasar.Resources
-import Control.Monad.Reader
+import Quasar.Resources.Disposer
 
 
+-- Invariant: the resource manager is disposed as soon as an exception is thrown to the channel
 data Quasar = Quasar TIOWorker ExceptionChannel ResourceManager
 
+instance Resource Quasar where
+  getDisposer (Quasar _ _ rm) = getDisposer rm
+
+instance HasField "ioWorker" Quasar TIOWorker where
+  getField = quasarIOWorker
+
+instance HasField "exceptionChannel" Quasar ExceptionChannel where
+  getField = quasarExceptionChannel
+
+instance HasField "resourceManager" Quasar ResourceManager where
+  getField = quasarResourceManager
+
+quasarIOWorker :: Quasar -> TIOWorker
+quasarIOWorker (Quasar worker _ _) = worker
+
+quasarExceptionChannel :: Quasar -> ExceptionChannel
+quasarExceptionChannel (Quasar _ exChan _) = exChan
+
+quasarResourceManager :: Quasar -> ResourceManager
+quasarResourceManager (Quasar _ _ rm) = rm
+
 newQuasar :: TIOWorker -> ExceptionChannel -> ResourceManager -> STM Quasar
-newQuasar = undefined
+newQuasar worker parentExChan parentRM = do
+  rm <- newResourceManagerSTM worker parentExChan
+  attachResource parentRM rm
+  pure $ Quasar worker (ExceptionChannel (disposeOnException rm)) rm
+  where
+    disposeOnException :: ResourceManager -> SomeException -> STM ()
+    disposeOnException rm ex = do
+      disposeEventuallySTM_ rm
+      throwToExceptionChannel parentExChan ex
 
 
 class Monad m => MonadQuasar m where
@@ -49,3 +82,13 @@ instance {-# OVERLAPPABLE #-} MonadQuasar m => MonadQuasar (ReaderT r m) where
   runSTM t = lift (runSTM t)
 
 -- TODO MonadQuasar instances for StateT, WriterT, RWST, MaybeT, ...
+
+
+askIOWorker :: MonadQuasar m => m TIOWorker
+askIOWorker = quasarIOWorker <$> askQuasar
+
+askExceptionChannel :: MonadQuasar m => m ExceptionChannel
+askExceptionChannel = quasarExceptionChannel <$> askQuasar
+
+askResourceManager :: MonadQuasar m => m ResourceManager
+askResourceManager = quasarResourceManager <$> askQuasar
-- 
GitLab