{-# LANGUAGE ScopedTypeVariables #-} -- | Provides common combinators for concurrency in Javascript. -- -- The emulated threading Javascript threading model provided by -- Sunroof is based on cooperative multithreading -- (since Javascript is not multithreaded). module Language.Sunroof.Concurrent ( loop , forkJS , threadDelay , yield ) where import Language.Sunroof.Types import Language.Sunroof.Classes ( Sunroof(..) ) import Language.Sunroof.JS.Ref ( newJSRef, readJSRef, writeJSRef, JSRef ) import Language.Sunroof.JS.Number ( JSNumber ) import Language.Sunroof.JS.Browser ( window, setTimeout ) -- ------------------------------------------------------------- -- General Concurrent Combinators. -- ------------------------------------------------------------- -- | @loop x f@ executes the function @f@ repeatedly. -- After each iteration the result value of the function -- is feed back as input of the next iteration. -- The initial value supplied for the first iteration is @x@. -- This loop will never terminate. loop :: (Sunroof a) => a -> (a -> JSB a) -> JSB () loop start m = do v :: JSRef (JSContinuation ()) <- newJSRef (cast nullJS) s <- newJSRef start f <- continuation $ \ () -> do a <- readJSRef s a' <- m a s # writeJSRef a' f <- readJSRef v _ <- liftJS $ window # setTimeout (\x -> goto f x) 0 return () v # writeJSRef f _ <- goto f () -- and call the function return () -- | Fork of the given computation in a different thread. forkJS :: (SunroofThread t1) => JS t1 () -> JS t2 () forkJS m = do _ <- window # setTimeout (\() -> blockableJS m) 0 return () -- | Delay the execution of all instructions after this one by -- the given amount of milliseconds. threadDelay :: JSNumber -> JSB () threadDelay n = callcc $ \ o -> do _ <- window # setTimeout (\x -> goto o x) n done -- | Give another thread time to execute. yield :: JSB () yield = threadDelay 0