module Glazier.React.Model where
import Control.Concurrent.MVar
import qualified Control.Disposable as CD
import Control.Lens
import qualified GHC.Generics as G
class HasPlan c pln | c -> pln where
plan :: Lens' c pln
class HasModel c mdl | c -> mdl where
model :: Lens' c mdl
data Design mdl pln = Design
{ _model :: mdl
, _plan :: pln
} deriving (G.Generic)
instance (CD.Disposing pln, CD.Disposing mdl) => CD.Disposing (Design mdl pln)
instance HasPlan (Design mdl pln) pln where
plan f (Design mdl pln) = fmap (\pln' -> Design mdl pln') (f pln)
instance HasModel (Design mdl pln) mdl where
model f (Design mdl pln) = fmap (\mdl' -> Design mdl' pln) (f mdl)
class HasDesign c mdl pln | c -> mdl pln where
design :: Lens' c (Design mdl pln)
instance HasDesign (Design mdl pln) mdl pln where
design = id
type Frame mdl pln = MVar (Design mdl pln)
class HasFrame c mdl pln | c -> mdl pln where
frame :: Lens' c (Frame mdl pln)
instance HasFrame (Frame mdl pln) mdl pln where
frame = id
data SuperModel mdl pln = SuperModel
{ _design :: Design mdl pln
, _frame :: Frame mdl pln
} deriving (G.Generic)
instance CD.Disposing (Design mdl pln) => CD.Disposing (SuperModel mdl pln) where
disposing s = CD.disposing $ s ^. design
class (HasDesign c mdl pln, HasFrame c mdl pln) => HasSuperModel c mdl pln | c -> mdl pln where
superModel :: Lens' c (SuperModel mdl pln)
instance HasSuperModel (SuperModel mdl pln) mdl pln where
superModel = id
instance HasFrame (SuperModel mdl pln) mdl pln where
frame f (SuperModel dsn frm) = fmap (\frm' -> SuperModel dsn frm') (f frm)
instance HasDesign (SuperModel mdl pln) mdl pln where
design f (SuperModel dsn frm) = fmap (\dsn' -> SuperModel dsn' frm) (f dsn)
instance HasPlan (SuperModel mdl pln) pln where
plan = design . plan
instance HasModel (SuperModel mdl pln) mdl where
model = design . model