123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179 |
- {-# LANGUAGE FlexibleContexts #-}
- {-# LANGUAGE DataKinds #-}
- {-# LANGUAGE RecordWildCards #-}
- module $module_path$.Attr where
- import Ivory.Language
- import Ivory.Tower
- import $types_path$.SequenceNum
- 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 ()
- attrReaderChan :: p a -> ChanOutput a
- instance AttrReadable AttrReader where
- attrState = attrReaderState
- attrHandler = attrReaderHandler
- attrReaderChan = ar_chan
- instance AttrReadable Attr where
- attrState = attrReaderState . attr_reader
- attrHandler p k = attrReaderHandler (attr_reader p) k
- attrReaderChan = attrReaderChan . attr_reader
- 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
- , IvoryArea (Struct b), IvoryZero (Struct b), IvoryStruct b)
- => Label b a
- -> Label b (Stored SequenceNum)
- -> Attr a
- -> ChanOutput (Stored SequenceNum)
- -> Tower e (ChanOutput (Struct b))
- readableAttrServer val_lbl snum_lbl p get = do
- get_response <- channel
- monitor (named "Server") \$ do
- s <- attrState p
- handler get (named "Get") \$ do
- e <- emitter (fst get_response) 1
- callbackV \$ \\snum -> do
- v <- local izero
- refCopy (v ~> val_lbl) s
- store (v ~> snum_lbl) snum
- emit e (constRef v)
- return (snd get_response)
- where
- named n = attrName p ++ n
- writableAttrServer :: (IvoryArea a, IvoryZero a
- , IvoryArea (Struct b), IvoryZero (Struct b), IvoryStruct b)
- => Label b a
- -> Label b (Stored SequenceNum)
- -> Attr a
- -> ChanOutput (Struct b)
- -> Tower e (ChanOutput (Stored SequenceNum))
- writableAttrServer val_lbl snum_lbl p set = do
- set_response <- channel
- monitor (named "Server") \$ do
- handler set (named "Set") \$ do
- e <- attrEmitter p
- r <- emitter (fst set_response) 1
- callback \$ \\v -> do
- emit e (v ~> val_lbl)
- emit r (v ~> snum_lbl)
- return (snd set_response)
- where
- named n = attrName p ++ n
- readwritableAttrServer :: ( IvoryArea a, IvoryZero a
- , IvoryArea (Struct b), IvoryZero (Struct b), IvoryStruct b)
- => Label b a
- -> Label b (Stored SequenceNum)
- -> Attr a
- -> ChanOutput (Stored SequenceNum)
- -> ChanOutput (Struct b)
- -> Tower e (ChanOutput (Struct b), ChanOutput (Stored SequenceNum))
- readwritableAttrServer val_lbl snum_lbl p get set = do
- get_response <- channel
- set_response <- channel
- monitor (named "Server") \$ do
- s <- attrState p
- handler get (named "Get") \$ do
- e <- emitter (fst get_response) 1
- callbackV \$ \\snum -> do
- v <- local izero
- refCopy (v ~> val_lbl) s
- store (v ~> snum_lbl) snum
- emit e (constRef v)
- handler set (named "Set") \$ do
- e <- attrEmitter p
- r <- emitter (fst set_response) 1
- callback \$ \\v -> do
- emit e (v ~> val_lbl)
- emit r (v ~> snum_lbl)
- return (snd get_response, snd set_response)
- where
- named n = attrName p ++ n
- attrProxy :: (AttrWritable w, AttrNamed w, IvoryArea a, IvoryZero a)
- => w a
- -> ChanOutput a
- -> Tower e ()
- attrProxy attr chan = do
- monitor (attrName attr ++ "Proxy") \$ do
- handler chan ("write_" ++ attrName attr) \$ do
- e <- attrEmitter attr
- callback \$ \\v -> emit e v
|