mainLoop ::
    GLFW.Window -> RefreshScheduler -> Sampler Config ->
    ( Config -> Widget.Size ->
        ( IO (Widget IO)
        , Widget IO -> IO (Widget IO)
        )
    ) -> IO ()
mainLoop win refreshScheduler configSampler iteration =
    do
        lastVersionNumRef <- newIORef 0
        let getAnimHalfLife =
                ConfigSampler.getConfig configSampler <&> Style.anim . snd
            makeWidget size =
                do
                    (_, config) <- ConfigSampler.getConfig configSampler
                    let (makeBaseWidget, addHelp) = iteration config size
                    addHelp =<< makeBaseWidget
            tickHandler =
                do
                    (curVersionNum, _) <- ConfigSampler.getConfig configSampler
                    configChanged <- atomicModifyIORef lastVersionNumRef $ \lastVersionNum ->
                        (curVersionNum, lastVersionNum /= curVersionNum)
                    if configChanged
                        then return True
                        else shouldRefresh refreshScheduler
        mainLoopWidget win tickHandler makeWidget getAnimHalfLife
mainLoop ::
    GLFW.Window -> RefreshScheduler -> Sampler Config ->
    ( Config -> Widget.Size ->
        ( IO (Widget IO)
        , Widget IO -> IO (Widget IO)
        )
    ) -> IO ()
mainLoop win refreshScheduler configSampler iteration =
    do
        lastVersionNumRef <- newIORef 0
        let getAnimHalfLife =
                ConfigSampler.getConfig configSampler <&> Style.anim . snd
            makeWidget size =
                do
                    (_, config) <- ConfigSampler.getConfig configSampler
                    let (makeBaseWidget, addHelp) = iteration config size
                    addHelp =<< makeBaseWidget
            tickHandler =
                do
                    (curVersionNum, _) <- ConfigSampler.getConfig configSampler
                    configChanged <- atomicModifyIORef lastVersionNumRef $ \lastVersionNum ->
                        (curVersionNum, lastVersionNum /= curVersionNum)
                    if configChanged
                        then return True
                        else shouldRefresh refreshScheduler
        mainLoopWidget win tickHandler makeWidget getAnimHalfLife
mainLoop win refreshScheduler configSampler iteration =
    do
        lastVersionNumRef <- newIORef 0
        let getAnimHalfLife =
                ConfigSampler.getConfig configSampler <&> Style.anim . snd
            makeWidget size =
                do
                    (_, config) <- ConfigSampler.getConfig configSampler
                    let (makeBaseWidget, addHelp) = iteration config size
                    addHelp =<< makeBaseWidget
            tickHandler =
                do
                    (curVersionNum, _) <- ConfigSampler.getConfig configSampler
                    configChanged <- atomicModifyIORef lastVersionNumRef $ \lastVersionNum ->
                        (curVersionNum, lastVersionNum /= curVersionNum)
                    if configChanged
                        then return True
                        else shouldRefresh refreshScheduler
        mainLoopWidget win tickHandler makeWidget getAnimHalfLife