glazier-react-0.1.0.0: src/Glazier/React/Widget.hs
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}
module Glazier.React.Widget where
import Control.Concurrent.MVar
import qualified Control.Disposable as CD
import Control.Lens
import qualified GHC.Generics as G
class HasWidgetGasket c gsk | c -> gsk where
widgetGasket :: Lens' c gsk
class HasWidgetModel c mdl | c -> mdl where
widgetModel :: Lens' c mdl
data GModel gsk mdl = GModel
{ _widgetGasket :: gsk
, _widgetModel :: mdl
} deriving (G.Generic)
instance (CD.Disposing gsk, CD.Disposing mdl) => CD.Disposing (GModel gsk mdl)
instance HasWidgetGasket (GModel gsk mdl) gsk where
widgetGasket f (GModel gsk mdl) = fmap (\gsk' -> GModel gsk' mdl) (f gsk)
{-# INLINE widgetGasket #-}
instance HasWidgetModel (GModel gsk mdl) mdl where
widgetModel f (GModel gsk mdl) = fmap (\mdl' -> GModel gsk mdl') (f mdl)
{-# INLINE widgetModel #-}
class HasGModel c gsk mdl | c -> gsk mdl where
gModel :: Lens' c (GModel gsk mdl)
instance HasGModel (GModel gsk mdl) gsk mdl where
gModel = id
type MModel gsk mdl = MVar (GModel gsk mdl)
class HasMModel c gsk mdl | c -> gsk mdl where
mModel :: Lens' c (MModel gsk mdl)
instance HasMModel (MModel gsk mdl) gsk mdl where
mModel = id
data SuperModel gsk mdl = SuperModel
{ _mModel :: MModel gsk mdl
, _gModel :: GModel gsk mdl
} deriving (G.Generic)
instance CD.Disposing (GModel gsk mdl) => CD.Disposing (SuperModel gsk mdl) where
disposing s = CD.disposing $ s ^. gModel
class (HasMModel c gsk mdl, HasGModel c gsk mdl) => HasSuperModel c gsk mdl | c -> gsk mdl where
superModel :: Lens' c (SuperModel gsk mdl)
instance HasSuperModel (SuperModel gsk mdl) gsk mdl where
superModel = id
instance HasMModel (SuperModel gsk mdl) gsk mdl where
mModel f (SuperModel mm gm) = fmap (\mm' -> SuperModel mm' gm) (f mm)
{-# INLINE mModel #-}
instance HasGModel (SuperModel gsk mdl) gsk mdl where
gModel f (SuperModel mm gm) = fmap (\gm' -> SuperModel mm gm') (f gm)
{-# INLINE gModel #-}
class IsWidget w where
-- The input to Gadget
type WidgetAction w :: *
-- The output of Gadget
type WidgetCommand w :: *
-- The pure model for state and rendering
type WidgetModel w :: *
-- Callbacks and data required for interfacing with react.
type WidgetGasket w :: *
type WidgetGModel w = GModel (WidgetGasket w) (WidgetModel w)
type WidgetMModel w = MModel (WidgetGasket w) (WidgetModel w)
type WidgetSuperModel w = SuperModel (WidgetGasket w) (WidgetModel w)