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
class ToOutline c o | c -> o where
outline :: c -> o
data Scene mdl pln = Scene
{ _model :: mdl
, _plan :: pln
} deriving (G.Generic)
class HasScene c mdl pln | c -> mdl pln where
scene :: Lens' c (Scene mdl pln)
instance HasScene (Scene mdl pln) mdl pln where
scene = id
instance (CD.Disposing pln, CD.Disposing mdl) => CD.Disposing (Scene mdl pln)
instance HasPlan (Scene mdl pln) pln where
plan f (Scene mdl pln) = fmap (\pln' -> Scene mdl pln') (f pln)
instance HasModel (Scene mdl pln) mdl where
model f (Scene mdl pln) = fmap (\mdl' -> Scene mdl' pln) (f mdl)
instance ToOutline mdl ol => ToOutline (Scene mdl pln) ol where
outline = view (model . to outline)
type Frame mdl pln = MVar (Scene 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 Gizmo mdl pln = Gizmo
{ _scene :: Scene mdl pln
, _frame :: Frame mdl pln
} deriving (G.Generic)
instance CD.Disposing (Scene mdl pln) => CD.Disposing (Gizmo mdl pln) where
disposing s = CD.disposing $ s ^. scene
class (HasScene c mdl pln, HasFrame c mdl pln) => HasGizmo c mdl pln | c -> mdl pln where
gizmo :: Lens' c (Gizmo mdl pln)
instance HasGizmo (Gizmo mdl pln) mdl pln where
gizmo = id
instance HasFrame (Gizmo mdl pln) mdl pln where
frame f (Gizmo scn frm) = fmap (\frm' -> Gizmo scn frm') (f frm)
instance HasScene (Gizmo mdl pln) mdl pln where
scene f (Gizmo scn frm) = fmap (\scn' -> Gizmo scn' frm) (f scn)
instance HasPlan (Gizmo mdl pln) pln where
plan = scene . plan
instance HasModel (Gizmo mdl pln) mdl where
model = scene . model
instance ToOutline mdl o => ToOutline (Gizmo mdl pln) o where
outline = view (model . to outline)