essence-of-live-coding-0.1.0.0: src/LiveCoding/Preliminary/LiveProgram/HotCodeSwap.lhs
\begin{comment}
\begin{code}
{-# LANGUAGE RecordWildCards #-}
module LiveCoding.Preliminary.LiveProgram.HotCodeSwap where
-- base
import Control.Concurrent
import Control.Monad (forever)
-- essence-of-live-coding
import LiveCoding.Preliminary.LiveProgram.LiveProgramPreliminary
\end{code}
\end{comment}
\begin{figure}
\begin{code}
hotCodeSwap
:: (s -> s')
-> LiveProgram m s'
-> LiveProgram m s
-> LiveProgram m s'
hotCodeSwap migrate newProgram oldProgram
= LiveProgram
{ liveState = migrate $ liveState oldProgram
, liveStep = liveStep newProgram
}
\end{code}
\caption{\texttt{Preliminary/HotCodeSwap.lhs}}
\label{fig:hot code swap}
\end{figure}
\fxwarning{The thing with the MVar doesn't work on the spot anymore. But it can still work with a "typed" handle. Every time you swap, you get a new handle that carries the currently saved type. Worth commenting upon?
It's somewhat complicated: We have to kill the old MVar and create a new one every time we update. Then we also have to update the ticking function}
\begin{comment}
\begin{code}
type LiveRef s = (MVar (LiveProgram IO s), MVar (IO ()))
launch :: LiveProgram IO s -> IO (LiveRef s)
launch liveProg = do
progVar <- newMVar liveProg
tickVar <- newMVar $ tick progVar
forkIO $ forever $ do
action <- takeMVar tickVar
action
tryPutMVar tickVar action
return (progVar, tickVar)
tick :: MVar (LiveProgram IO s) -> IO ()
tick var = do
LiveProgram {..} <- takeMVar var
liveState' <- liveStep liveState
putMVar var LiveProgram { liveState = liveState', .. }
swapWith :: (s -> s') -> LiveProgram IO s' -> LiveRef s -> IO (LiveRef s')
swapWith migrate (LiveProgram _newState newStep) (progVar, actionVar) = do
_ <- takeMVar actionVar
LiveProgram oldState oldStep <- takeMVar progVar
let newProg = LiveProgram (migrate oldState) newStep
newProgVar <- newMVar newProg
putMVar actionVar $ tick newProgVar
return (newProgVar, actionVar)
\end{code}
\end{comment}