packages feed

sodium 0.7.0.0 → 0.8.0.0

raw patch · 5 files changed

+82/−6 lines, 5 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- FRP.Sodium.Context: ioReactive :: Context r => IO a -> Reactive r a
+ FRP.Sodium.Context: class Context r => ContextIO r
+ FRP.Sodium.Context: executeAsyncIO :: ContextIO r => Event r (IO a) -> Event r a
+ FRP.Sodium.Context: executeSyncIO :: ContextIO r => Event r (IO a) -> Event r a
+ FRP.Sodium.IO: executeAsyncIO :: Event Plain (IO a) -> Event Plain a
+ FRP.Sodium.IO: executeSyncIO :: Event Plain (IO a) -> Event Plain a
+ FRP.Sodium.Internal: data Plain
+ FRP.Sodium.Internal: dep :: a -> Dep
+ FRP.Sodium.Internal: unsafeNewIORef :: a -> b -> IORef a

Files

sodium.cabal view
@@ -1,5 +1,5 @@ name:                sodium-version:             0.7.0.0+version:             0.8.0.0 synopsis:            Sodium Reactive Programming (FRP) System description:            A general purpose Reactive Programming (FRP) system. This is part of a project to@@ -41,6 +41,8 @@    * 0.6.0.2 - Fix memory leak - see memory-test-8 & memory-test-8a;   .    * 0.7.0.0 - Add split primitive.+  .+   * 0.8.0.0 - Add executeIO primitive.  license:             BSD3 license-file:        LICENSE@@ -145,8 +147,12 @@  library   hs-source-dirs:      src-  exposed-modules:     FRP.Sodium, FRP.Sodium.Internal, FRP.Sodium.Context+  exposed-modules:     FRP.Sodium,+                       FRP.Sodium.Internal,+                       FRP.Sodium.Context,+                       FRP.Sodium.IO   other-modules:       FRP.Sodium.Plain   build-depends:       base >= 4.3.0.0 && < 4.8.0.0,                        containers >= 0.4.0.0 && < 0.6.0.0,                        mtl >= 2.0.0.0 && < 2.2.0.0+  ghc-options:         -O2
src/FRP/Sodium/Context.hs view
@@ -26,8 +26,6 @@     --     -- State changes to 'hold' values occur after processing of the transaction is complete.     sync          :: Reactive r a -> IO a-    -- Lift an arbitrary IO action into a 'Reactive'.-    ioReactive    :: IO a -> Reactive r a     -- | Returns an event, and a push action for pushing a value into the event.     newEvent      :: Reactive r (Event r a, a -> Reactive r ())     -- | Listen for firings of this event. The returned @IO ()@ is an IO action@@ -88,6 +86,28 @@     -- a block of input data into frames. We obviously want each frame to have     -- its own transaction so that state is updated separately each frame.     split         :: Event r [a] -> Event r a++class Context r => ContextIO r where+    -- | Execute the specified IO operation asynchronously on a separate thread, and+    -- signal the output event in a new transaction upon its completion.+    --+    -- Caveat: Where 'switch' or 'switchE' is used, when some reactive logic has been+    -- switched away, we rely on garbage collection to actually disconnect this logic+    -- from any input it may be listening to. With normal Sodium code, everything is+    -- pure, so before garbage collection happens, the worst we will get is some wasted+    -- CPU cycles. If you are using 'executeAsyncIO'/'executeSyncIO' inside a 'switch'+    -- or 'switchE', however, it is possible that logic that has been switched away+    -- hasn't been garbage collected yet. This logic /could/ still run, and if it has+    -- observable effects, you could see it running after it is supposed to have been+    -- switched out. One way to avoid this is to pipe the source event for IO out of the+    -- switch, run the 'executeAsyncIO'/'executeSyncIO' outside the switch, and pipe its+    -- output back into the switch contents.+    executeAsyncIO :: Event r (IO a) -> Event r a+    -- | Execute the specified IO operation synchronously and fire the output event+    -- in the same transaction.+    --+    -- Caveat: See 'executeAsyncIO'.+    executeSyncIO  :: Event r (IO a) -> Event r a  -- | A time-varying value, British spelling. type Behaviour r a = Behavior r a
+ src/FRP/Sodium/IO.hs view
@@ -0,0 +1,48 @@+module FRP.Sodium.IO where++import FRP.Sodium.Context+import FRP.Sodium.Internal++import Control.Concurrent (forkIO)+++-- | Execute the specified IO operation asynchronously on a separate thread, and+-- signal the output event in a new transaction upon its completion.+--+-- Caveat: Where 'switch' or 'switchE' is used, when some reactive logic has been+-- switched away, we rely on garbage collection to actually disconnect this logic+-- from any input it may be listening to. With normal Sodium code, everything is+-- pure, so before garbage collection happens, the worst we will get is some wasted+-- CPU cycles. If you are using 'executeAsyncIO'/'executeSyncIO' inside a 'switch'+-- or 'switchE', however, it is possible that logic that has been switched away+-- hasn't been garbage collected yet. This logic /could/ still run, and if it has+-- observable effects, you could see it running after it is supposed to have been+-- switched out. One way to avoid this is to pipe the source event for IO out of the+-- switch, run the 'executeAsyncIO'/'executeSyncIO' outside the switch, and pipe its+-- output back into the switch contents.+executeAsyncIO :: Event Plain (IO a) -> Event Plain a+executeAsyncIO ev = Event gl cacheRef (dep ev)+  where+    cacheRef = unsafeNewIORef Nothing ev+    gl = do+        (l, push, nodeRef) <- ioReactive newEventImpl+        unlistener <- later $ linkedListen ev (Just nodeRef) False $ \action -> do+            ioReactive $ do+                _ <- forkIO $ sync . push =<< action+                return ()+        addCleanup_Listen unlistener l++-- | Execute the specified IO operation synchronously and fire the output event+-- in the same transaction.+--+-- Caveat: See 'executeAsyncIO'.+executeSyncIO :: Event Plain (IO a) -> Event Plain a+executeSyncIO ev = Event gl cacheRef (dep ev)+  where+    cacheRef = unsafeNewIORef Nothing ev+    gl = do+        (l, push, nodeRef) <- ioReactive newEventImpl+        unlistener <- later $ linkedListen ev (Just nodeRef) False $ \action -> do+            push =<< ioReactive action+        addCleanup_Listen unlistener l+
src/FRP/Sodium/Internal.hs view
@@ -19,7 +19,10 @@         addCleanup_Listen,         Sample(..),         addCleanup_Sample,-        later+        later,+        dep,+        unsafeNewIORef,+        Plain     ) where  import qualified FRP.Sodium.Context as C
src/FRP/Sodium/Plain.hs view
@@ -110,7 +110,6 @@         }      sync = sync-    ioReactive = ioReactive     newEvent = newEvent     listen = listen     never = never