|
@@ -0,0 +1,138 @@
|
|
|
+{-# LANGUAGE DataKinds #-}
|
|
|
+{-# LANGUAGE RecordWildCards #-}
|
|
|
+
|
|
|
+module $module_path$.Attr where
|
|
|
+
|
|
|
+import Ivory.Language
|
|
|
+import Ivory.Tower
|
|
|
+
|
|
|
+data AttrWriter a =
|
|
|
+ AttrWriter
|
|
|
+ { aw_chan :: ChanInput a
|
|
|
+ , aw_name :: String
|
|
|
+ }
|
|
|
+
|
|
|
+data AttrReader a =
|
|
|
+ AttrReader
|
|
|
+ { ar_chan :: ChanOutput a
|
|
|
+ , ar_name :: String
|
|
|
+ , ar_ival :: Init a
|
|
|
+ }
|
|
|
+
|
|
|
+data Attr a =
|
|
|
+ Attr
|
|
|
+ { attr_writer :: AttrWriter a
|
|
|
+ , attr_reader :: AttrReader a
|
|
|
+ }
|
|
|
+
|
|
|
+attrReaderState :: (IvoryArea a, IvoryZero a)
|
|
|
+ => AttrReader a -> Monitor e (Ref Global a)
|
|
|
+attrReaderState ar@AttrReader{..} = do
|
|
|
+ s <- stateInit ar_name ar_ival
|
|
|
+ attrReaderHandler ar \$ do
|
|
|
+ callback \$ \\v -> refCopy s v
|
|
|
+ return s
|
|
|
+
|
|
|
+attrReaderHandler :: (IvoryArea a, IvoryZero a)
|
|
|
+ => AttrReader a -> Handler a e () -> Monitor e ()
|
|
|
+attrReaderHandler AttrReader{..} k =
|
|
|
+ handler ar_chan (ar_name ++ "_update") k
|
|
|
+
|
|
|
+attrWriterEmitter :: (IvoryArea a, IvoryZero a)
|
|
|
+ => AttrWriter a -> Handler b e (Emitter a)
|
|
|
+attrWriterEmitter AttrWriter{..} = emitter aw_chan 1
|
|
|
+
|
|
|
+towerAttr :: (IvoryArea a) => String -> Init a -> Tower e (Attr a)
|
|
|
+towerAttr n i = do
|
|
|
+ c <- channel
|
|
|
+ return Attr
|
|
|
+ { attr_writer = AttrWriter
|
|
|
+ { aw_chan = fst c
|
|
|
+ , aw_name = n
|
|
|
+ }
|
|
|
+ , attr_reader = AttrReader
|
|
|
+ { ar_chan = snd c
|
|
|
+ , ar_name = n
|
|
|
+ , ar_ival = i
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+class AttrNamed p where
|
|
|
+ attrName :: (IvoryArea a) => p a -> String
|
|
|
+
|
|
|
+instance AttrNamed AttrReader where
|
|
|
+ attrName = ar_name
|
|
|
+
|
|
|
+instance AttrNamed AttrWriter where
|
|
|
+ attrName = aw_name
|
|
|
+
|
|
|
+instance AttrNamed Attr where
|
|
|
+ attrName = attrName . attr_reader
|
|
|
+
|
|
|
+class AttrReadable p where
|
|
|
+ attrState :: (IvoryArea a, IvoryZero a) => p a -> Monitor e (Ref Global a)
|
|
|
+ attrHandler :: (IvoryArea a, IvoryZero a) => p a -> Handler a e () -> Monitor e ()
|
|
|
+
|
|
|
+instance AttrReadable AttrReader where
|
|
|
+ attrState = attrReaderState
|
|
|
+ attrHandler = attrReaderHandler
|
|
|
+
|
|
|
+instance AttrReadable Attr where
|
|
|
+ attrState = attrReaderState . attr_reader
|
|
|
+ attrHandler p k = attrReaderHandler (attr_reader p) k
|
|
|
+
|
|
|
+class AttrWritable p where
|
|
|
+ attrEmitter :: (IvoryArea a, IvoryZero a) => p a -> Handler b e (Emitter a)
|
|
|
+
|
|
|
+instance AttrWritable AttrWriter where
|
|
|
+ attrEmitter = attrWriterEmitter
|
|
|
+
|
|
|
+instance AttrWritable Attr where
|
|
|
+ attrEmitter = attrWriterEmitter . attr_writer
|
|
|
+
|
|
|
+
|
|
|
+readableAttrServer :: (IvoryArea a, IvoryZero a)
|
|
|
+ => Attr a
|
|
|
+ -> ChanOutput (Stored IBool)
|
|
|
+ -> Tower e (ChanOutput a)
|
|
|
+readableAttrServer p get = do
|
|
|
+ val <- channel
|
|
|
+ monitor (named "Server") \$ do
|
|
|
+ s <- attrState p
|
|
|
+ handler get (named "Get") \$ do
|
|
|
+ e <- emitter (fst val) 1
|
|
|
+ callback \$ const \$ emit e (constRef s)
|
|
|
+ return (snd val)
|
|
|
+ where
|
|
|
+ named n = attrName p ++ n
|
|
|
+
|
|
|
+writableAttrServer :: (IvoryArea a, IvoryZero a)
|
|
|
+ => Attr a
|
|
|
+ -> ChanOutput a
|
|
|
+ -> Tower e ()
|
|
|
+writableAttrServer p set = do
|
|
|
+ monitor (named "Server") \$ do
|
|
|
+ handler set (named "Set") \$ do
|
|
|
+ e <- attrEmitter p
|
|
|
+ callback \$ \\v -> emit e v
|
|
|
+ where
|
|
|
+ named n = attrName p ++ n
|
|
|
+
|
|
|
+readwritableAttrServer :: (IvoryArea a, IvoryZero a)
|
|
|
+ => Attr a
|
|
|
+ -> ChanOutput (Stored IBool)
|
|
|
+ -> ChanOutput a
|
|
|
+ -> Tower e (ChanOutput a)
|
|
|
+readwritableAttrServer p get set = do
|
|
|
+ val <- channel
|
|
|
+ monitor (named "Server") \$ do
|
|
|
+ s <- attrState p
|
|
|
+ handler set (named "Set") \$ do
|
|
|
+ e <- attrEmitter p
|
|
|
+ callback \$ \\v -> emit e v
|
|
|
+ handler get (named "Get") \$ do
|
|
|
+ e <- emitter (fst val) 1
|
|
|
+ callback \$ const \$ emit e (constRef s)
|
|
|
+ return (snd val)
|
|
|
+ where
|
|
|
+ named n = attrName p ++ n
|