Переключение между обработчиками событий в gtk2hs

Я хотел бы сделать что-то вроде этого:

handlerOn = do
  cid <- canvas `on` buttonPressEvent $ tryEvent do
    signalDisconnect cid
    handlerOff
  putStrLn "handlerOn"

handlerOff = do
  cid <- canvas `on` buttonPressEvent $ tryEvent do
    signalDisconnect cid
    handlerOn
  putStrLn "handlerOff"

Это, конечно, не сработает, потому что я пытаюсь использовать cid внутри блока кода, где cid еще не назначен.

Идея состоит в том, чтобы зарегистрировать прослушиватель событий, который, когда он получит событие, отменит регистрацию и зарегистрирует другой прослушиватель событий, который будет делать то же самое, туда и обратно.


person mentics    schedule 24.02.2011    source источник


Ответы (1)


GHC поддерживает рекурсивный do.

handlerOn = do
  rec cid <- canvas `on` buttonPressEvent $ tryEvent do
    signalDisconnect cid
    handlerOff
  putStrLn "handlerOn"

Вы также можете использовать Control.Monad.Fix.

handlerOff = do
  mfix $ \cid -> canvas `on` buttonPressEvent $ tryEvent do
    signalDisconnect cid
    handlerOn
  putStrLn "handlerOff"

Или управлять обработчиком самостоятельно.

do ...
    h <- newIORef undefined
    let handlerOn = do
            ...
            writeIORef h handlerOff
        handlerOff = do
            ...
            writeIORef h handlerOn
    writeIORef h handlerOn
    canvas `on` buttonPressEvent $ tryEvent =<< readIORef h

Или просто сделать все в один обработчик.

do ...
    ms <- newIORef False
    canvas `on` buttonPressEvent $ tryEvent do
        s <- readIORef ms
        if s
            then ...
            else ...
person ephemient    schedule 24.02.2011
comment
Спасибо! Я использую первый вариант, и, по крайней мере, мне пришлось добавить фигурные скобки, например: rec { cid ... handlerOff }, чтобы он работал. - person mentics; 25.02.2011