packages feed

reactive-banana-automation 0.2.0 → 0.3.0

raw patch · 4 files changed

+64/−29 lines, 4 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- Reactive.Banana.Automation: type EventSource a = (AddHandler a, a -> IO ())
+ Reactive.Banana.Automation: automationStepper :: a -> Event a -> MomentAutomation (Behavior a)
+ Reactive.Banana.Automation: data EventSource a v
+ Reactive.Banana.Automation: fromEventSource :: EventSource a v -> v
+ Reactive.Banana.Automation: newEventSource :: v -> IO (EventSource a v)
+ Reactive.Banana.Automation: sensedEventBehavior :: Event (Sensed a) -> MomentAutomation (Behavior (Sensed a))
+ Reactive.Banana.Automation: sensorUnavailable :: EventSource (Sensed a) v -> IO ()
- Reactive.Banana.Automation: (=:) :: EventSource (Sensed a) -> a -> IO ()
+ Reactive.Banana.Automation: (=:) :: EventSource (Sensed a) v -> a -> IO ()
- Reactive.Banana.Automation: clockSignal :: Timestamp t => EventSource (ClockSignal t) -> IO ()
+ Reactive.Banana.Automation: clockSignal :: Timestamp t => EventSource (ClockSignal t) v -> IO ()
- Reactive.Banana.Automation: clockSignalAt :: Timestamp t => t -> EventSource (ClockSignal t) -> IO ()
+ Reactive.Banana.Automation: clockSignalAt :: Timestamp t => t -> EventSource (ClockSignal t) v -> IO ()
- Reactive.Banana.Automation: clockSignalBehavior :: Timestamp t => EventSource (ClockSignal t) -> MomentAutomation (Behavior (Maybe (ClockSignal t)))
+ Reactive.Banana.Automation: clockSignalBehavior :: Timestamp t => EventSource (ClockSignal t) v -> MomentAutomation (Behavior (Maybe (ClockSignal t)))
- Reactive.Banana.Automation: getEventFrom :: EventSource a -> MomentAutomation (Event a)
+ Reactive.Banana.Automation: getEventFrom :: EventSource a v -> MomentAutomation (Event a)
- Reactive.Banana.Automation: gotEvent :: EventSource a -> a -> IO ()
+ Reactive.Banana.Automation: gotEvent :: EventSource a v -> a -> IO ()
- Reactive.Banana.Automation: sensed :: EventSource (Sensed a) -> a -> IO ()
+ Reactive.Banana.Automation: sensed :: EventSource (Sensed a) v -> a -> IO ()
- Reactive.Banana.Automation: sensedAt :: Timestamp t => t -> EventSource (Sensed (Timestamped t a)) -> a -> IO ()
+ Reactive.Banana.Automation: sensedAt :: Timestamp t => t -> EventSource (Sensed (Timestamped t a)) v -> a -> IO ()
- Reactive.Banana.Automation: sensedBehavior :: EventSource (Sensed a) -> MomentAutomation (Behavior (Sensed a))
+ Reactive.Banana.Automation: sensedBehavior :: EventSource (Sensed a) v -> MomentAutomation (Behavior (Sensed a))
- Reactive.Banana.Automation: sensedEvent :: EventSource (Sensed a) -> MomentAutomation (Event a)
+ Reactive.Banana.Automation: sensedEvent :: EventSource (Sensed a) v -> MomentAutomation (Event a)
- Reactive.Banana.Automation: sensedNow :: Timestamp t => EventSource (Sensed (Timestamped t a)) -> a -> IO ()
+ Reactive.Banana.Automation: sensedNow :: Timestamp t => EventSource (Sensed (Timestamped t a)) v -> a -> IO ()
- Reactive.Banana.Automation.Examples: Sensors :: EventSource (Sensed Double) -> EventSource (Sensed (Timestamped POSIXTime Bool)) -> EventSource (ClockSignal LocalTime) -> EventSource (Sensed ()) -> Sensors
+ Reactive.Banana.Automation.Examples: Sensors :: EventSource (Sensed Double) () -> EventSource (Sensed (Timestamped POSIXTime Bool)) () -> EventSource (ClockSignal LocalTime) () -> EventSource (Sensed ()) () -> Sensors
- Reactive.Banana.Automation.Examples: [clock] :: Sensors -> EventSource (ClockSignal LocalTime)
+ Reactive.Banana.Automation.Examples: [clock] :: Sensors -> EventSource (ClockSignal LocalTime) ()
- Reactive.Banana.Automation.Examples: [fridgeTemperature] :: Sensors -> EventSource (Sensed Double)
+ Reactive.Banana.Automation.Examples: [fridgeTemperature] :: Sensors -> EventSource (Sensed Double) ()
- Reactive.Banana.Automation.Examples: [motionSensor] :: Sensors -> EventSource (Sensed (Timestamped POSIXTime Bool))
+ Reactive.Banana.Automation.Examples: [motionSensor] :: Sensors -> EventSource (Sensed (Timestamped POSIXTime Bool)) ()
- Reactive.Banana.Automation.Examples: [rainGaugeTipSensor] :: Sensors -> EventSource (Sensed ())
+ Reactive.Banana.Automation.Examples: [rainGaugeTipSensor] :: Sensors -> EventSource (Sensed ()) ()

Files

CHANGELOG view
@@ -1,3 +1,12 @@+reactive-banana-automation (0.3.0) upstream; urgency=medium++  * EventSource is now a data type with an extra value for expansion.+    (API change)+  * Added newEventSource, sensorUnavailable, sensedEventBehavior,+    and automationStepper.++ -- Joey Hess <id@joeyh.name>  Sat, 05 May 2018 19:27:56 -0400+ reactive-banana-automation (0.2.0) upstream; urgency=medium    * Automation is now a newtype. (API change)
Reactive/Banana/Automation.hs view
@@ -23,6 +23,8 @@ 	observeAutomation, 	-- * Events 	EventSource,+	newEventSource,+	fromEventSource, 	gotEvent, 	getEventFrom, 	onEvent,@@ -32,6 +34,9 @@ 	sensedBehavior, 	sensed, 	(=:),+	sensorUnavailable,+	sensedEventBehavior,+	automationStepper, 	-- * Time 	Timestamped(..), 	Timestamp(..),@@ -72,7 +77,7 @@ -- run as needed to keep the temperature in a safe range, while -- minimizing compressor starts. ----- > data Sensors = Sensors { fridgeTemperature :: EventSource (Sensed Double) }+-- > data Sensors = Sensors { fridgeTemperature :: EventSource (Sensed Double) () } -- > data Actuators = FridgePower PowerChange deriving (Show) -- >  -- > fridge :: Automation Sensors Actuators@@ -138,7 +143,7 @@ -- Continuing the above example of a fridge, here's how to run it: --  -- > mkSensors :: IO Sensors--- > mkSensors = Sensors <$> newAddHandler+-- > mkSensors = Sensors <$> newEventSource () -- >  -- > driveActuators :: Actuators -> IO () -- > driveActuators = print@@ -196,17 +201,29 @@ 	return runner  -- | A source of events.-type EventSource a = (AddHandler a, a -> IO ())+--+-- `v` is unused by this library, but is provided in case you+-- need a way to track some extra data about an EventSource such as, for+-- example, the timestamp of the most recent event.+data EventSource a v = EventSource+	{ getEventSource :: (AddHandler a, a -> IO ())+	, fromEventSource :: v+	-- ^ Get extra data from an EventSource.+	} -addHandler :: EventSource a -> AddHandler a-addHandler = fst+-- | Construct a new EventSource.+newEventSource :: v -> IO (EventSource a v)+newEventSource v = EventSource <$> newAddHandler <*> pure v +addHandler :: EventSource a v -> AddHandler a+addHandler = fst . getEventSource+ -- | Call this to trigger an event.-gotEvent :: EventSource a -> a -> IO ()-gotEvent = snd+gotEvent :: EventSource a v -> a -> IO ()+gotEvent = snd . getEventSource  -- | Get an Event from an EventSource.-getEventFrom :: EventSource a -> MomentAutomation (Event a)+getEventFrom :: EventSource a v -> MomentAutomation (Event a) getEventFrom = MomentAutomation . fromAddHandler . addHandler  -- | Runs an action when an event occurs.@@ -224,7 +241,7 @@ -- -- The Event only contains values when the sensor provided a reading, -- not times when it was unavailable.-sensedEvent :: EventSource (Sensed a) -> MomentAutomation (Event a)+sensedEvent :: EventSource (Sensed a) v -> MomentAutomation (Event a) sensedEvent s = do 	e <- getEventFrom s 	return $ filterJust $ flip fmap e $ \case@@ -232,22 +249,32 @@ 		Sensed a -> Just a  -- | Create a Behavior from sensed values.-sensedBehavior :: EventSource (Sensed a) -> MomentAutomation (Behavior (Sensed a))-sensedBehavior s = -	MomentAutomation . stepper SensorUnavailable =<< getEventFrom s+sensedBehavior :: EventSource (Sensed a) v -> MomentAutomation (Behavior (Sensed a))+sensedBehavior s = sensedEventBehavior =<< getEventFrom s +sensedEventBehavior :: Event (Sensed a) -> MomentAutomation (Behavior (Sensed a))+sensedEventBehavior = automationStepper SensorUnavailable++-- | `stepper` lifted into `MomentAutomation`+automationStepper :: a -> Event a -> MomentAutomation (Behavior a)+automationStepper a e = MomentAutomation $ stepper a e+ -- | Call when a sensor has sensed a value. -- -- > getFridgeTemperature >>= sensed (fridgeTemperature sensors)-sensed :: EventSource (Sensed a) -> a -> IO ()+sensed :: EventSource (Sensed a) v -> a -> IO () sensed s = gotEvent s . Sensed  -- | Same as `sensed` --  -- > fridgeTemperature sensors =: 0-(=:) :: EventSource (Sensed a) -> a -> IO ()+(=:) :: EventSource (Sensed a) v -> a -> IO () (=:) = sensed +-- | Call when a sensor is unavailable.+sensorUnavailable :: EventSource (Sensed a) v -> IO ()+sensorUnavailable s = gotEvent s SensorUnavailable+ -- | A timestamped value. -- -- In reactive-banana, an `Event` is tagged with its time of occurrence,@@ -289,13 +316,13 @@  -- | Call when a sensor has sensed a value, which will be `Timestamped` with -- the current time.-sensedNow :: Timestamp t => EventSource (Sensed (Timestamped t a)) -> a -> IO ()+sensedNow :: Timestamp t => EventSource (Sensed (Timestamped t a)) v -> a -> IO () sensedNow es a = do 	now <- getCurrentTimestamp 	gotEvent es (Sensed (Timestamped now a))  -- | Call when a sensor sensed a value with a particular timestamp.-sensedAt :: Timestamp t => t -> EventSource (Sensed (Timestamped t a)) -> a -> IO ()+sensedAt :: Timestamp t => t -> EventSource (Sensed (Timestamped t a)) v -> a -> IO () sensedAt ts es a = gotEvent es (Sensed (Timestamped ts a))  -- | Given a `Timestamped` `Event` and a function, produces an `Event`@@ -332,16 +359,16 @@  -- | Call repeatedly to feed a clock signal to an `Automation` -- that needs to know what time it is.-clockSignal :: Timestamp t => EventSource (ClockSignal t) -> IO ()+clockSignal :: Timestamp t => EventSource (ClockSignal t) v -> IO () clockSignal es = gotEvent es . ClockSignal =<< getCurrentTimestamp  -- | Call to feed a particular time to an `Automation`.-clockSignalAt :: Timestamp t => t -> EventSource (ClockSignal t) -> IO ()+clockSignalAt :: Timestamp t => t -> EventSource (ClockSignal t) v -> IO () clockSignalAt t es = gotEvent es (ClockSignal t)  -- | Create a Behavior from a ClockSignal. It will initially be Nothing, -- and then updates with each incoming clock signal.-clockSignalBehavior :: Timestamp t => EventSource (ClockSignal t) -> MomentAutomation (Behavior (Maybe (ClockSignal t)))+clockSignalBehavior :: Timestamp t => EventSource (ClockSignal t) v -> MomentAutomation (Behavior (Maybe (ClockSignal t))) clockSignalBehavior s = MomentAutomation . stepper Nothing  	=<< fmap Just <$> getEventFrom s 
Reactive/Banana/Automation/Examples.hs view
@@ -6,7 +6,6 @@ module Reactive.Banana.Automation.Examples where  import Reactive.Banana-import Reactive.Banana.Frameworks import Reactive.Banana.Automation import Data.Time.Clock.POSIX import Data.Time.LocalTime@@ -15,10 +14,10 @@ -- | We'll use a single Sensors type containing all the sensors -- used by the examples below. data Sensors = Sensors-	{ fridgeTemperature :: EventSource (Sensed Double)-	, motionSensor :: EventSource (Sensed (Timestamped POSIXTime Bool))-	, clock :: EventSource (ClockSignal LocalTime)-	, rainGaugeTipSensor :: EventSource (Sensed ())+	{ fridgeTemperature :: EventSource (Sensed Double) ()+	, motionSensor :: EventSource (Sensed (Timestamped POSIXTime Bool)) ()+	, clock :: EventSource (ClockSignal LocalTime) ()+	, rainGaugeTipSensor :: EventSource (Sensed ()) () 	}  -- | And a single Actuators type containing all the actuators used by the@@ -33,10 +32,10 @@ -- | For running the examples, you'll need this, to construct a `Sensors` mkSensors :: IO Sensors mkSensors = Sensors-	<$> newAddHandler-	<*> newAddHandler-	<*> newAddHandler-	<*> newAddHandler+	<$> newEventSource ()+	<*> newEventSource ()+	<*> newEventSource ()+	<*> newEventSource ()  -- | A fridge, containing the `fridgeTemperature` sensor and with -- its power controlled by the `FridgePower` actuator.
reactive-banana-automation.cabal view
@@ -1,5 +1,5 @@ Name: reactive-banana-automation-Version: 0.2.0+Version: 0.3.0 Cabal-Version: >= 1.8 License: AGPL-3 Maintainer: Joey Hess <id@joeyh.name>