| Copyright | (C) 2016-2026 David M. Johnson |
|---|---|
| License | BSD3-style (see the file LICENSE) |
| Maintainer | David M. Johnson <code@dmj.io> |
| Stability | experimental |
| Portability | non-portable |
| Safe Haskell | None |
| Language | Haskell2010 |
Miso.Subscription.Util
Contents
Description
Overview
Miso.Subscription.Util provides createSub, the building block used
by every subscription in Miso.Subscription. It handles the
acquire-use-release lifecycle of an external resource (an event
listener, an animation-frame callback, etc.) using
bracket so the resource is always cleaned up when
the Component unmounts, even if an exception is thrown.
It also provides rAFLoop, a requestAnimationFrame loop built on
createSub whose callback re-schedules itself every frame. It is the
basis of rAFSub,
rAFSubElapsed and
canvasSub. See Note [rAFLoop teardown].
Quick start
Use createSub to build a custom subscription from any pair of
acquire/release actions. The subscription sleeps between polls and
relies entirely on the acquire step to register whatever callbacks
deliver events to the sink:
import Miso.Subscription.Util (createSub) import Miso.Effect (Sub) import qualified Miso.Runtime.Internal as FFI -- Custom subscription: fire an action whenever the window is resized resizeSub :: (Int -> action) ->Subaction resizeSub toAction sink =createSubacquire release sink where acquire = FFI.windowAddEventListener"resize" $ \_ -> do w <- FFI.windowInnerWidthsink (toAction w) release cb = FFI.windowRemoveEventListener"resize" cb
How it works
runs:createSub acquire release sink
bracket acquire release (\_ -> forever (threadDelay 1000_000_000))
The forever loop keeps the subscription thread alive by sleeping in
very long increments. All actual work is done inside callbacks
registered during acquire, which call sink directly. release is
guaranteed to run (via bracket) when the component
teardown kills the thread.
See also
- Miso.Effect —
Sub,Sink - Miso.Runtime.Internal —
windowAddEventListener,windowRemoveEventListener - Miso.Subscription — all built-in subscriptions
Utilities
Utility function to allow resource finalization on Sub.
A self re-scheduling requestAnimationFrame loop, as a Sub.
The IO action runs once, when the Sub starts, and builds the
per-frame handler; it is the place to acquire anything the handler
needs (a canvas context, IORefs for timing state, ...).
The handler then receives the frame's DOMHighResTimeStamp in
milliseconds, every frame, until the Sub is stopped.
A single callback is used for the whole loop; it is freed when the
Sub stops. See Note [rAFLoop teardown].
Since: 1.15.0.0