-- | -- Module: Control.Wire.Interval -- Copyright: (c) 2013 Ertugrul Soeylemez -- License: BSD3 -- Maintainer: Ertugrul Soeylemez module Control.Wire.Interval ( -- * Basic intervals inhibit, -- * Time intervals after, for, -- * Signal analysis unless, when, -- * Event-based intervals asSoonAs, between, hold, holdFor, until ) where import Control.Arrow import Control.Wire.Core import Control.Wire.Event import Control.Wire.Session import Control.Wire.Unsafe.Event import Data.Monoid import Prelude hiding (until) -- | After the given time period. -- -- * Depends: now after the given time period. -- -- * Inhibits: for the given time period. after :: (HasTime t s, Monoid e) => t -> Wire s e m a a after t' = mkPure $ \ds x -> let t = t' - dtime ds in if t <= 0 then (Right x, mkId) else (Left mempty, after t) -- | Alias for 'hold'. asSoonAs :: (Monoid e) => Wire s e m (Event a) a asSoonAs = hold -- | Start each time the left event occurs, stop each time the right -- event occurs. -- -- * Depends: now when active. -- -- * Inhibits: after the right event occurred, before the left event -- occurs. between :: (Monoid e) => Wire s e m (a, Event b, Event c) a between = mkPureN $ \(x, onEv, _) -> event (Left mempty, between) (const (Right x, active)) onEv where active = mkPureN $ \(x, _, offEv) -> event (Right x, active) (const (Left mempty, between)) offEv -- | For the given time period. -- -- * Depends: now for the given time period. -- -- * Inhibits: after the given time period. for :: (HasTime t s, Monoid e) => t -> Wire s e m a a for t' = mkPure $ \ds x -> let t = t' - dtime ds in if t <= 0 then (Left mempty, mkEmpty) else (Right x, for t) -- | Start when the event occurs for the first time reflecting its -- latest value. -- -- * Depends: now. -- -- * Inhibits: until the event occurs for the first time. hold :: (Monoid e) => Wire s e m (Event a) a hold = mkPureN $ event (Left mempty, hold) (Right &&& holdWith) where holdWith x = mkPureN $ event (Right x, holdWith x) (Right &&& holdWith) -- | Hold each event occurrence for the given time period. Inhibits -- when no event occurred for the given amount of time. New occurrences -- override old occurrences, even when they are still held. -- -- * Depends: now. -- -- * Inhibits: when no event occurred for the given amount of time. holdFor :: (HasTime t s, Monoid e) => t -> Wire s e m (Event a) a holdFor int | int <= 0 = error "holdFor: Non-positive interval." holdFor int = off where off = mkPure $ \_ -> event (Left mempty, off) (Right &&& on int) on t' x' = mkPure $ \ds -> let t = t' - dtime ds in event (if t <= 0 then (Left mempty, off) else (Right x', on t x')) (Right &&& on int) -- | Inhibit forever with the given value. -- -- * Inhibits: always. inhibit :: e -> Wire s e m a b inhibit = mkConst . Left -- | When the given predicate is false for the input signal. -- -- * Depends: now. -- -- * Inhibits: unless the predicate is false. unless :: (Monoid e) => (a -> Bool) -> Wire s e m a a unless p = mkPure_ $ \x -> if p x then Left mempty else Right x -- | Produce until the given event occurs. When it occurs, inhibit with -- its value forever. -- -- * Depends: now until event occurs. -- -- * Inhibits: forever after event occurs. until :: (Monoid e) => Wire s e m (a, Event b) a until = mkPureN . uncurry $ \x -> event (Right x, until) (const (Left mempty, mkEmpty)) -- | When the given predicate is true for the input signal. -- -- * Depends: now. -- -- * Inhibits: when the predicate is false. when :: (Monoid e) => (a -> Bool) -> Wire s e m a a when p = mkPure_ $ \x -> if p x then Right x else Left mempty