glazier-react-0.2.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 HasWidgetPlan c pln | c -> pln where
widgetPlan :: Lens' c pln
class HasWidgetModel c mdl | c -> mdl where
widgetModel :: Lens' c mdl
data Design mdl pln = Design
{ _widgetModel :: mdl
, _widgetPlan :: pln
} deriving (G.Generic)
instance (CD.Disposing pln, CD.Disposing mdl) => CD.Disposing (Design mdl pln)
instance HasWidgetPlan (Design mdl pln) pln where
widgetPlan f (Design mdl pln) = fmap (\pln' -> Design mdl pln') (f pln)
{-# INLINE widgetPlan #-}
instance HasWidgetModel (Design mdl pln) mdl where
widgetModel f (Design mdl pln) = fmap (\mdl' -> Design mdl' pln) (f mdl)
{-# INLINE widgetModel #-}
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 Replica mdl pln = MVar (Design mdl pln)
class HasReplica c mdl pln | c -> mdl pln where
replica :: Lens' c (Replica mdl pln)
instance HasReplica (Replica mdl pln) mdl pln where
replica = id
data SuperModel mdl pln = SuperModel
{ _design :: Design mdl pln
, _replica :: Replica 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, HasReplica 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 HasReplica (SuperModel mdl pln) mdl pln where
replica f (SuperModel dsn rep) = fmap (\rep' -> SuperModel dsn rep') (f rep)
{-# INLINE replica #-}
instance HasDesign (SuperModel mdl pln) mdl pln where
design f (SuperModel dsn rep) = fmap (\dsn' -> SuperModel dsn' rep) (f dsn)
{-# INLINE design #-}
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 WidgetPlan w :: *
type WidgetDesign w = Design (WidgetModel w) (WidgetPlan w)
type WidgetReplica w = Replica (WidgetModel w) (WidgetPlan w)
type WidgetSuperModel w = SuperModel (WidgetModel w) (WidgetPlan w)