sodium 0.8.0.0 → 0.9.0.0
raw patch · 15 files changed
+116/−102 lines, 15 files
Files
- examples/games/Engine.hs +1/−1
- examples/games/poodle.hs +1/−1
- examples/tests/memory-test-1.hs +1/−1
- examples/tests/memory-test-2.hs +1/−1
- examples/tests/memory-test-3.hs +1/−1
- examples/tests/memory-test-5.hs +1/−1
- examples/tests/memory-test-6.hs +1/−1
- examples/tests/memory-test-7.hs +1/−1
- examples/tests/memory-test-8.hs +3/−3
- examples/tests/memory-test-8a.hs +1/−1
- examples/tests/unit-tests.hs +54/−54
- sodium.cabal +3/−1
- src/FRP/Sodium.hs +6/−3
- src/FRP/Sodium/Context.hs +6/−7
- src/FRP/Sodium/Plain.hs +35/−25
examples/games/Engine.hs view
@@ -80,7 +80,7 @@ unlisten <- sync $ do time <- hold 0 eTime sprites <- game eMouse time- listen (values sprites) (writeIORef spritesRef)+ listen (value sprites) (writeIORef spritesRef) _ <- GLUT.getArgsAndInitialize GLUT.initialDisplayMode $= [GLUT.DoubleBuffered]
examples/games/poodle.hs view
@@ -43,7 +43,7 @@ rec tLast <- hold 0 eAppear interval <- peelList eAppear intervals- let eTime = values time+ let eTime = value time eAppear = filterJust $ snapshotWith (\t (tLast, interval) -> if t >= tLast + interval then Just t else Nothing ) eTime ((,) <$> tLast <*> interval)
examples/tests/memory-test-1.hs view
@@ -18,7 +18,7 @@ out <- sync $ do oout <- hold (((,) 0) <$> t) $ (\tens -> ((,) tens) <$> t) <$> changeTens switch oout- kill <- sync $ listen (values out) $ \x ->+ kill <- sync $ listen (value out) $ \x -> if verbose then print x else (evaluate x >> return ()) timeout 4000000 $ mapM_ (sync . pushT) [0..] kill
examples/tests/memory-test-2.hs view
@@ -29,7 +29,7 @@ let eSwitch = execute $ unSource <$> switchE (snd <$> bPair) return (fst <$> bPair) out <- sync $ switch oout- kill <- sync $ listen (values out) $ \x ->+ kill <- sync $ listen (value out) $ \x -> if verbose then print x else (evaluate x >> return ()) timeout 4000000 $ mapM_ (sync . pushT) [0..] kill
examples/tests/memory-test-3.hs view
@@ -14,7 +14,7 @@ out <- sync $ do oout <- hold t $ (\_ -> t) <$> eChange switch oout- kill <- sync $ listen (values out) $ \x ->+ kill <- sync $ listen (value out) $ \x -> if verbose then print x else (evaluate x >> return ()) timeout 4000000 $ forM_ [0..] $ \i -> do sync $ pushC ()
examples/tests/memory-test-5.hs view
@@ -11,7 +11,7 @@ (et, _) <- sync newEvent (eChange, pushC) <- sync $ newEvent out <- sync $ hold 0 eChange- kill <- sync $ listen (values out) $ \x ->+ kill <- sync $ listen (value out) $ \x -> if verbose then print (x :: Int) else (evaluate x >> return ()) timeout 4000000 $ forM_ [0..] $ \i -> do sync $ pushC i
examples/tests/memory-test-6.hs view
@@ -21,7 +21,7 @@ eInit <- flam e eFlam <- hold eInit (execute ((const $ flam e) <$> e)) switch eFlam- kill <- sync $ listen (values out) $ \x ->+ kill <- sync $ listen (value out) $ \x -> if verbose then print x else (evaluate x >> return ()) timeout 4000000 $ forever $ sync $ push () kill
examples/tests/memory-test-7.hs view
@@ -24,7 +24,7 @@ eInit <- flam e time eFlam <- hold eInit (execute ((const $ flam e time) <$> eFlip)) switch eFlam- kill <- sync $ listen (values out) $ \x ->+ kill <- sync $ listen (value out) $ \x -> if verbose then print x else (evaluate (rnf x) >> return ()) let loop t = do sync $ pushTime t
examples/tests/memory-test-8.hs view
@@ -14,7 +14,7 @@ flam e time = do -- Test that this arrangement... --- -- changes time+ -- updates time -- | -- v -- eStop <-- SNAPSHOT (timer)@@ -38,7 +38,7 @@ case mRunning of Just t0 | (t - t0) >= 5 -> Just Nothing _ -> Nothing- ) (changes time) mRunning+ ) (updates time) mRunning return mRunning main = do@@ -49,7 +49,7 @@ eInit <- flam e time eFlam <- hold eInit (execute ((const $ flam e time) <$> eFlip)) switch eFlam- kill <- sync $ listen (values out) $ \x ->+ kill <- sync $ listen (value out) $ \x -> if verbose then print x else (evaluate (rnf x) >> return ()) let loop t = do sync $ pushTime t
examples/tests/memory-test-8a.hs view
@@ -38,7 +38,7 @@ eInit <- flam e time eFlam <- hold eInit (execute ((const $ flam e time) <$> eFlip)) switch eFlam- kill <- sync $ listen (values out) $ \x ->+ kill <- sync $ listen (value out) $ \x -> if verbose then print x else (evaluate (rnf x) >> return ()) let loop t = do sync $ pushTime t
examples/tests/unit-tests.hs view
@@ -93,7 +93,7 @@ outRef <- newIORef [] (push, unlisten) <- sync $ do (beh, push) <- newBehavior "init"- unlisten <- listen (values beh) $ \a -> modifyIORef outRef (++ [a])+ unlisten <- listen (value beh) $ \a -> modifyIORef outRef (++ [a]) return (push, unlisten) sync $ do push "next"@@ -104,7 +104,7 @@ outRef <- newIORef [] (push, unlisten) <- sync $ do (beh, push) <- newBehavior "init"- unlisten <- listen (values beh) $ \a -> modifyIORef outRef (++ [a])+ unlisten <- listen (value beh) $ \a -> modifyIORef outRef (++ [a]) return (push, unlisten) unlisten sync $ do@@ -115,7 +115,7 @@ outRef <- newIORef [] (push, unlisten) <- sync $ do (beh, push) <- newBehavior "init"- unlisten <- listen (values beh) $ \a -> modifyIORef outRef (++ [a])+ unlisten <- listen (value beh) $ \a -> modifyIORef outRef (++ [a]) return (push, unlisten) sync $ do push "first"@@ -129,7 +129,7 @@ outRef <- newIORef [] (push, unlisten) <- sync $ do (beh, push) <- newBehavior "init"- unlisten <- listen (values beh) $ \a -> modifyIORef outRef (++ [a])+ unlisten <- listen (value beh) $ \a -> modifyIORef outRef (++ [a]) push "other" return (push, unlisten) sync $ do@@ -143,7 +143,7 @@ outRef <- newIORef [] unlisten <- sync $ do beh <- hold "init" ea- unlisten <- listen (map toUpper <$> values beh) $ \a -> modifyIORef outRef (++ [a])+ unlisten <- listen (map toUpper <$> value beh) $ \a -> modifyIORef outRef (++ [a]) push "other" return unlisten sync $ do@@ -154,133 +154,133 @@ behConstant = TestCase $ do outRef <- newIORef []- unlisten <- sync $ listen (values $ pure 'X') $ \a -> modifyIORef outRef (++ [a])+ unlisten <- sync $ listen (value $ pure 'X') $ \a -> modifyIORef outRef (++ [a]) unlisten assertEqual "behConstant" ['X'] =<< readIORef outRef -valuesThenMap = TestCase $ do+valueThenMap = TestCase $ do (b, push) <- sync $ newBehavior 9 outRef <- newIORef []- unlisten <- sync $ listen (values . fmap (+100) $ b) $ \a -> modifyIORef outRef (++ [a])+ unlisten <- sync $ listen (value . fmap (+100) $ b) $ \a -> modifyIORef outRef (++ [a]) sync $ push (2 :: Int) sync $ push 7 unlisten- assertEqual "valuesThenMap" [109,102,107] =<< readIORef outRef + assertEqual "valueThenMap" [109,102,107] =<< readIORef outRef --- | This is used for tests where values() produces a single initial value on listen,+-- | This is used for tests where value() produces a single initial value on listen, -- and then we double that up by causing that single initial event to be repeated. -- This needs testing separately, because the code must be done carefully to achieve doubleUp :: Event a -> Event a doubleUp e = merge e e -valuesTwiceThenMap = TestCase $ do+valueTwiceThenMap = TestCase $ do (b, push) <- sync $ newBehavior 9 outRef <- newIORef []- unlisten <- sync $ listen (doubleUp . values . fmap (+100) $ b) $ \a -> modifyIORef outRef (++ [a])+ unlisten <- sync $ listen (doubleUp . value . fmap (+100) $ b) $ \a -> modifyIORef outRef (++ [a]) sync $ push (2 :: Int) sync $ push 7 unlisten- assertEqual "valuesThenMap" [109,109,102,102,107,107] =<< readIORef outRef + assertEqual "valueThenMap" [109,109,102,102,107,107] =<< readIORef outRef -valuesThenCoalesce = TestCase $ do+valueThenCoalesce = TestCase $ do (b, push) <- sync $ newBehavior 9 outRef <- newIORef []- unlisten <- sync $ listen (coalesce (\_ x -> x) . values $ b) $ \a -> modifyIORef outRef (++ [a])+ unlisten <- sync $ listen (coalesce (\_ x -> x) . value $ b) $ \a -> modifyIORef outRef (++ [a]) sync $ push 2 sync $ push 7 unlisten- assertEqual "valuesThenCoalesce" [9,2,7] =<< readIORef outRef+ assertEqual "valueThenCoalesce" [9,2,7] =<< readIORef outRef -valuesTwiceThenCoalesce = TestCase $ do+valueTwiceThenCoalesce = TestCase $ do (b, push) <- sync $ newBehavior 9 outRef <- newIORef []- unlisten <- sync $ listen (coalesce (+) . doubleUp. values $ b) $ \a -> modifyIORef outRef (++ [a])+ unlisten <- sync $ listen (coalesce (+) . doubleUp. value $ b) $ \a -> modifyIORef outRef (++ [a]) sync $ push 2 sync $ push 7 unlisten- assertEqual "valuesThenCoalesce" [18,4,14] =<< readIORef outRef+ assertEqual "valueThenCoalesce" [18,4,14] =<< readIORef outRef -valuesThenSnapshot = TestCase $ do+valueThenSnapshot = TestCase $ do (bi, pushi) <- sync $ newBehavior (9 :: Int) (bc, pushc) <- sync $ newBehavior 'a' outRef <- newIORef []- unlisten <- sync $ listen (flip snapshot bc . values $ bi) $ \a -> modifyIORef outRef (++ [a])+ unlisten <- sync $ listen (flip snapshot bc . value $ bi) $ \a -> modifyIORef outRef (++ [a]) sync $ pushc 'b' sync $ pushi 2 sync $ pushc 'c' sync $ pushi 7 unlisten- assertEqual "valuesThenSnapshot" ['a','b','c'] =<< readIORef outRef+ assertEqual "valueThenSnapshot" ['a','b','c'] =<< readIORef outRef -valuesTwiceThenSnapshot = TestCase $ do+valueTwiceThenSnapshot = TestCase $ do (bi, pushi) <- sync $ newBehavior (9 :: Int) (bc, pushc) <- sync $ newBehavior 'a' outRef <- newIORef []- unlisten <- sync $ listen (flip snapshot bc . doubleUp . values $ bi) $ \a -> modifyIORef outRef (++ [a])+ unlisten <- sync $ listen (flip snapshot bc . doubleUp . value $ bi) $ \a -> modifyIORef outRef (++ [a]) sync $ pushc 'b' sync $ pushi 2 sync $ pushc 'c' sync $ pushi 7 unlisten- assertEqual "valuesThenSnapshot" ['a','a','b','b','c','c'] =<< readIORef outRef+ assertEqual "valueThenSnapshot" ['a','a','b','b','c','c'] =<< readIORef outRef -valuesThenMerge = TestCase $ do+valueThenMerge = TestCase $ do (bi, pushi) <- sync $ newBehavior (9 :: Int) (bj, pushj) <- sync $ newBehavior (2 :: Int) outRef <- newIORef []- unlisten <- sync $ listen (mergeWith (+) (values bi) (values bj)) $ \a -> modifyIORef outRef (++ [a])+ unlisten <- sync $ listen (mergeWith (+) (value bi) (value bj)) $ \a -> modifyIORef outRef (++ [a]) sync $ pushi 1 sync $ pushj 4 unlisten- assertEqual "valuesThenMerge" [11,1,4] =<< readIORef outRef + assertEqual "valueThenMerge" [11,1,4] =<< readIORef outRef -valuesThenFilter = TestCase $ do+valueThenFilter = TestCase $ do (b, push) <- sync $ newBehavior (9 :: Int) outRef <- newIORef []- unlisten <- sync $ listen (filterE (const True) . values $ b) $ \a -> modifyIORef outRef (++ [a])+ unlisten <- sync $ listen (filterE (const True) . value $ b) $ \a -> modifyIORef outRef (++ [a]) sync $ push 2 sync $ push 7 unlisten- assertEqual "valuesThenFilter" [9,2,7] =<< readIORef outRef+ assertEqual "valueThenFilter" [9,2,7] =<< readIORef outRef -valuesTwiceThenFilter = TestCase $ do+valueTwiceThenFilter = TestCase $ do (b, push) <- sync $ newBehavior (9 :: Int) outRef <- newIORef []- unlisten <- sync $ listen (filterE (const True) . doubleUp . values $ b) $ \a -> modifyIORef outRef (++ [a])+ unlisten <- sync $ listen (filterE (const True) . doubleUp . value $ b) $ \a -> modifyIORef outRef (++ [a]) sync $ push 2 sync $ push 7 unlisten- assertEqual "valuesThenFilter" [9,9,2,2,7,7] =<< readIORef outRef+ assertEqual "valueThenFilter" [9,9,2,2,7,7] =<< readIORef outRef -valuesThenOnce = TestCase $ do+valueThenOnce = TestCase $ do (b, push) <- sync $ newBehavior (9 :: Int) outRef <- newIORef []- unlisten <- sync $ listen (once . values $ b) $ \a -> modifyIORef outRef (++ [a])+ unlisten <- sync $ listen (once . value $ b) $ \a -> modifyIORef outRef (++ [a]) sync $ push 2 sync $ push 7 unlisten- assertEqual "valuesThenOnce" [9] =<< readIORef outRef+ assertEqual "valueThenOnce" [9] =<< readIORef outRef -valuesTwiceThenOnce = TestCase $ do+valueTwiceThenOnce = TestCase $ do (b, push) <- sync $ newBehavior (9 :: Int) outRef <- newIORef []- unlisten <- sync $ listen (once . doubleUp . values $ b) $ \a -> modifyIORef outRef (++ [a])+ unlisten <- sync $ listen (once . doubleUp . value $ b) $ \a -> modifyIORef outRef (++ [a]) sync $ push 2 sync $ push 7 unlisten- assertEqual "valuesThenOnce" [9] =<< readIORef outRef+ assertEqual "valueThenOnce" [9] =<< readIORef outRef --- | Test values being "executed" before listen. Somewhat redundant since this is--- Haskell and "values b" is pure.-valuesLateListen = TestCase $ do+-- | Test value being "executed" before listen. Somewhat redundant since this is+-- Haskell and "value b" is pure.+valueLateListen = TestCase $ do (b, push) <- sync $ newBehavior (9 :: Int) outRef <- newIORef []- let bv = values b+ let bv = value b sync $ push 8 unlisten <- sync $ listen bv $ \a -> modifyIORef outRef (++ [a]) sync $ push 2 unlisten- assertEqual "valuesLateListen" [8,2] =<< readIORef outRef+ assertEqual "valueLateListen" [8,2] =<< readIORef outRef appl1 = TestCase $ do (ea, pusha) <- sync newEvent@@ -289,7 +289,7 @@ bb <- sync $ hold 0 eb let esum = (+) <$> ba <*> bb outRef <- newIORef []- unlisten <- sync $ listen (values esum) $ \sum -> modifyIORef outRef (++ [sum])+ unlisten <- sync $ listen (value esum) $ \sum -> modifyIORef outRef (++ [sum]) sync $ pusha 5 sync $ pushb 100 sync $ pusha 10 >> pushb 200@@ -327,7 +327,7 @@ outRef <- newIORef [] unlisten <- sync $ do count <- count ea- listen (changes count) $ \c -> modifyIORef outRef (++ [c])+ listen (updates count) $ \c -> modifyIORef outRef (++ [c]) sync $ push () sync $ push () sync $ push ()@@ -340,7 +340,7 @@ unlisten <- sync $ do ba <- hold 100 ea sum <- collect (\a s -> (a+s, a+s)) 0 ba- listen (values sum) $ \sum -> modifyIORef outRef (++ [sum])+ listen (value sum) $ \sum -> modifyIORef outRef (++ [sum]) sync $ push 5 sync $ push 7 sync $ push 1@@ -356,7 +356,7 @@ (ba, push) <- newBehavior 100 sum <- collect (\a s -> (a + s, a + s)) 0 ba push 5- unlisten <- listen (values sum) $ \sum -> modifyIORef outRef (++ [sum])+ unlisten <- listen (value sum) $ \sum -> modifyIORef outRef (++ [sum]) return (unlisten, push) sync $ push 7 sync $ push 1@@ -422,7 +422,7 @@ (bb, pushb) <- newBehavior 'a' (bsw, pushsw) <- newBehavior ba bo <- switch bsw- unlisten <- listen (values bo) $ \o -> modifyIORef outRef (++ [o])+ unlisten <- listen (value bo) $ \o -> modifyIORef outRef (++ [o]) return (ba, bb, pusha, pushb, pushsw, unlisten) sync $ pusha 'B' >> pushb 'b' sync $ pushsw bb >> pusha 'C' >> pushb 'c'@@ -470,7 +470,7 @@ bPair <- hold initPair ePage let ePage = execute $ unPage <$> switchE (snd <$> bPair) return (fst <$> bPair)- unlisten <- sync $ listen (values bo) $ \o -> modifyIORef outRef (++ [o])+ unlisten <- sync $ listen (value bo) $ \o -> modifyIORef outRef (++ [o]) sync $ push (Page $ return ('b', ep)) sync $ push (Page $ return ('c', ep)) unlisten@@ -551,9 +551,9 @@ "efgh","ef","e","f","gh","g","h"] =<< readIORef outRef tests = test [ event1, fmap1, merge1, filterJust1, filterE1, gate1, beh1, beh2, beh3, beh4, beh5,- behConstant, valuesThenMap, valuesTwiceThenMap, valuesThenCoalesce, valuesTwiceThenCoalesce,- valuesThenSnapshot, valuesTwiceThenSnapshot, valuesThenMerge, valuesThenFilter,- valuesTwiceThenFilter, valuesThenOnce, valuesTwiceThenOnce, valuesLateListen,+ behConstant, valueThenMap, valueTwiceThenMap, valueThenCoalesce, valueTwiceThenCoalesce,+ valueThenSnapshot, valueTwiceThenSnapshot, valueThenMerge, valueThenFilter,+ valueTwiceThenFilter, valueThenOnce, valueTwiceThenOnce, valueLateListen, holdIsDelayed, appl1, snapshot1, count1, collect1, collect2, collectE1, collectE2, switchE1, switch1, once1, once2, cycle1, split1, split2 {-, mergeWith1, mergeWith2, mergeWith3, coalesce1-} ]
sodium.cabal view
@@ -1,5 +1,5 @@ name: sodium-version: 0.8.0.0+version: 0.9.0.0 synopsis: Sodium Reactive Programming (FRP) System description: A general purpose Reactive Programming (FRP) system. This is part of a project to@@ -43,6 +43,8 @@ * 0.7.0.0 - Add split primitive. . * 0.8.0.0 - Add executeIO primitive.+ .+ * 0.9.0.0 - Rename changes() to updates(). Rename values() to value(). license: BSD3 license-file: LICENSE
src/FRP/Sodium.hs view
@@ -46,8 +46,8 @@ merge, filterJust, hold,- changes,- values,+ updates,+ value, snapshotWith, switchE, switch,@@ -64,7 +64,10 @@ collectE, collect, accum,- count+ count,+ -- * Deprecated+ changes,+ values ) where import FRP.Sodium.Plain
src/FRP/Sodium/Context.hs view
@@ -31,7 +31,7 @@ -- | Listen for firings of this event. The returned @IO ()@ is an IO action -- that unregisters the listener. This is the observer pattern. --- -- To listen to a 'Behavior' use @listen (values b) handler@+ -- To listen to a 'Behavior' use @listen (value b) handler@ listen :: Event r a -> (a -> IO ()) -> Reactive r (IO ()) -- | An event that never fires. never :: Event r a@@ -51,13 +51,13 @@ -- That is, state updates caused by event firings get processed at the end of -- the transaction. hold :: a -> Event r a -> Reactive r (Behavior r a)- -- | An event that gives the updates for the behavior. It doesn't do any equality- -- comparison as the name might imply.- changes :: Behavior r a -> Event r a+ -- | An event that gives the updates for the behavior. If the behavior was created+ -- with 'hold', then 'updates' gives you an event equivalent to the one that was held.+ updates :: Behavior r a -> Event r a -- | An event that is guaranteed to fire once when you listen to it, giving -- the current value of the behavior, and thereafter behaves like 'changes', -- firing for each update to the behavior's value.- values :: Behavior r a -> Event r a+ value :: Behavior r a -> Event r a -- | Sample the behavior at the time of the event firing. Note that the 'current value' -- of the behavior that's sampled is the value as at the start of the transaction -- before any state changes of the current transaction are applied through 'hold's.@@ -167,7 +167,7 @@ -- is passed the input and the old state and returns the new state and output value. collect :: Context r => (a -> s -> (b, s)) -> s -> Behavior r a -> Reactive r (Behavior r b) collect f zs bea = do- let ea = coalesce (flip const) (changes bea)+ let ea = coalesce (flip const) (updates bea) za <- sample bea let (zb, zs') = f za zs rec@@ -185,4 +185,3 @@ -- | Count event occurrences, giving a behavior that starts with 0 before the first occurrence. count :: Context r => Event r a -> Reactive r (Behavior r Int) count = accum 0 . (const (1+) <$>)-
src/FRP/Sodium/Plain.hs view
@@ -73,16 +73,16 @@ } -- | A monad for transactional reactive operations. Execute it from 'IO' using 'sync'.-type Reactive a = R.Reactive Plain a+type Reactive = R.Reactive Plain -- | A stream of events. The individual firings of events are called \'event occurrences\'.-type Event a = R.Event Plain a+type Event = R.Event Plain -- | A time-varying value, American spelling.-type Behavior a = R.Behavior Plain a+type Behavior = R.Behavior Plain -- | A time-varying value, British spelling.-type Behaviour a = R.Behavior Plain a+type Behaviour = R.Behavior Plain -- Must be data not newtype, because we need to attach finalizers to it data Sample a = Sample {@@ -103,8 +103,8 @@ } data Behavior Plain a = Behavior {- changes_ :: Event a, -- ^ An event that gives the updates for the behavior. It doesn't do any equality- -- comparison as the name might imply.+ updates_ :: Event a, -- ^ An event that gives the updates for the behavior. It doesn't do any equality+ -- comparison as the name might imply. -- | Obtain the current value of a behavior. sampleImpl :: Sample a }@@ -116,8 +116,8 @@ merge = merge filterJust = filterJust hold = hold- changes = changes- values = values+ updates = updates + value = value snapshotWith = snapshotWith switchE = switchE switch = switch@@ -128,11 +128,9 @@ split = split -- | An event that gives the updates for the behavior. If the behavior was created--- with 'hold', then 'changes' gives you back the event that was passed to 'hold'.------ (It doesn't do any equality comparison as the name might imply.)-changes :: Behavior a -> Event a-changes = changes_+-- with 'hold', then 'updates' gives you an event equivalent to the one that was held.+updates :: Behavior a -> Event a+updates = updates_ -- | Execute the specified 'Reactive' within a new transaction, blocking the caller -- until all resulting processing is complete and all callbacks have been called.@@ -193,8 +191,8 @@ -- | Listen for firings of this event. The returned @IO ()@ is an IO action -- that unregisters the listener. This is the observer pattern. ----- To listen to a 'Behavior' use @listen (values b) handler@ or--- @listen (changes b) handler@+-- To listen to a 'Behavior' use @listen (value b) handler@ or+-- @listen (updates b) handler@ -- -- NOTE: The callback is called with the transaction held, so you cannot -- use 'sync' inside a listener. You can delegate to another thread and have@@ -261,19 +259,19 @@ sample <- ioReactive $ addCleanup_Sample unlistener (Sample (bsCurrent <$> readIORef bsRef) (dep ea)) let beh = sample `seq` Behavior {- changes_ = ea,+ updates_ = ea, sampleImpl = sample } return beh -- | An event that is guaranteed to fire once when you listen to it, giving--- the current value of the behavior, and thereafter behaves like 'changes',+-- the current value of the behavior, and thereafter behaves like 'updates', -- firing for each update to the behavior's value.-values :: Behavior a -> Event a-values ba = sa `seq` ea `seq` eventify (listenValueRaw ba) (dep (sa, ea))+value :: Behavior a -> Event a+value ba = sa `seq` ea `seq` eventify (listenValueRaw ba) (dep (sa, ea)) where sa = sampleImpl ba- ea = changes ba+ ea = updates ba -- | Sample the behavior at the time of the event firing. Note that the 'current value' -- of the behavior that's sampled is the value as at the start of the transaction@@ -295,7 +293,7 @@ switchE :: Behavior (Event a) -> Event a switchE bea = eea `seq` Event gl cacheRef (dep (eea, depRef)) where- eea = changes bea+ eea = updates bea cacheRef = unsafeNewIORef Nothing bea depRef = unsafeNewIORef undefined bea gl = do@@ -321,7 +319,7 @@ ba <- sample bba depRef <- ioReactive $ newIORef ba za <- sample ba- let eba = changes bba+ let eba = updates bba ioReactive $ evaluate eba (ev, push, nodeRef) <- ioReactive $ newEventLinked (dep (bba, depRef)) unlisten2Ref <- ioReactive $ newIORef Nothing@@ -731,7 +729,7 @@ constant :: a -> Behavior a constant a = Behavior {- changes_ = never,+ updates_ = never, sampleImpl = Sample (return a) undefined } @@ -808,7 +806,7 @@ listenValueRaw ba = lastFiringOnly $ \mNodeRef suppressEarlierFirings handle -> do a <- sample ba handle a- linkedListen (changes ba) mNodeRef suppressEarlierFirings handle+ linkedListen (updates ba) mNodeRef suppressEarlierFirings handle -- | Queue the specified atomic to run at the end of the priority 2 queue schedulePrioritized :: Maybe (MVar Node)@@ -883,7 +881,19 @@ cross :: (Typeable p, Typeable q) => Behavior a -> Reactive (Behavior q a) cross bpa = do a <- sample bpa- ea <- crossE (changes bpa)+ ea <- crossE (updates bpa) ioReactive $ sync $ 3 a ea -} +-- | An event that gives the updates for the behavior. If the behavior was created+-- with 'hold', then 'changes' gives you an event equivalent to the one that was held.+changes :: Behavior a -> Event a+{-# DEPRECATED changes "renamed to 'updates'" #-}+changes = updates++-- | An event that is guaranteed to fire once when you listen to it, giving+-- the current value of the behavior, and thereafter behaves like 'changes',+-- firing for each update to the behavior's value.+values :: Behavior a -> Event a+{-# DEPRECATED values "renamed to 'value'" #-}+values = value