Skip to content

Commit cc46c04

Browse files
dmjioclaude
andcommitted
Switch back to threadDelay tick; remove rAFSubElapsed
CSS transitions run on the compositor independently of Haskell, so rAFSubElapsed's frame-alignment benefit is already provided by Miso's internal rAF. threadDelay allocates nothing between ticks, avoiding the per-frame syncCallback1 churn and nursery pressure. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent f91ffc9 commit cc46c04

1 file changed

Lines changed: 3 additions & 24 deletions

File tree

Main.hs

Lines changed: 3 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -6,25 +6,23 @@
66
----------------------------------------------------------------------------
77
module Main where
88
----------------------------------------------------------------------------
9-
import Control.Monad (void, when)
9+
import Control.Concurrent (threadDelay)
10+
import Control.Monad (forever, when)
1011
import Data.Foldable (toList)
11-
import Data.IORef
1212
import Data.Sequence (Seq, ViewL(..), ViewR(..))
1313
import qualified Data.Sequence as Seq
1414
import Data.Set (Set)
1515
import qualified Data.Set as Set
1616
----------------------------------------------------------------------------
1717
import Miso hiding (Phase)
1818
import Miso.CSS hiding (ms, background, Phase)
19-
import Miso.DSL (syncCallback1, requestAnimationFrame, fromJSValUnchecked, freeFunction, Function(..))
2019
import qualified Miso.Html as H
2120
import qualified Miso.Html.Property as HP
2221
import qualified Miso.Svg as S
2322
import qualified Miso.Svg.Property as SP
2423
import Miso.Lens
2524
import Miso.Random (replicateRM)
2625
import Miso.Reload
27-
import Miso.Subscription.Util (createSub)
2826
----------------------------------------------------------------------------
2927

3028
gridSize :: Int
@@ -129,29 +127,10 @@ emptyModel = Model
129127
, _prevSnake = initSnake
130128
}
131129

132-
rAFSubElapsed :: Double -> action -> Sub action
133-
rAFSubElapsed interval action sink = createSub acquire release sink
134-
where
135-
acquire = do
136-
cbRef <- newIORef (error "rAFSubElapsed: uninitialized, impossible")
137-
let go lastT elap = do
138-
cb <- syncCallback1 $ \jsval -> do
139-
t <- fromJSValUnchecked jsval
140-
let dt = if lastT == 0 then 0 else min interval (t - lastT)
141-
newElap = elap + dt
142-
if newElap >= interval
143-
then sink action *> go t (newElap - interval)
144-
else go t newElap
145-
writeIORef cbRef cb
146-
void (requestAnimationFrame cb)
147-
go 0 0
148-
pure cbRef
149-
release cbRef = freeFunction . Function =<< readIORef cbRef
150-
151130
app :: App Model Action
152131
app = (component emptyModel updateModel viewModel)
153132
{ subs =
154-
[ rAFSubElapsed tickInterval Tick
133+
[ \sink -> forever (threadDelay (round (tickInterval * 1000)) >> sink Tick)
155134
, \sink -> windowSub "keydown" keycodeDecoder (\case
156135
KeyCode 37 -> Turn DLeft
157136
KeyCode 38 -> Turn DUp

0 commit comments

Comments
 (0)