Hello,
while building GUIs using Gtk2HS I always struggled with the following question: how to sync the state of the GUI with the state of the rest application. I usually make several IORefs store the state there. But it's quite easy to forget to update relevant parts of GUI when state changes, especially then it's done in several places, say, by user's request and by some internal event.

Some time ago I realized a pattern which proved to be useful for me several times. I wrapped IORef in a type:

data CBRef a = CBRef {v_ref :: IORef a, callbacks :: IORef [a -> IO()] }

now I add callbacks using

addCB :: CBRef a -> (a -> IO()) -> IO ()
addCB r cb = modifyIORef (callbacks r) (++[cb])

which fires then the value is changed:

writeCBRef :: CBRef a -> a -> IO ()
writeCBRef r v = do
  writeIORef (v_ref r) v
  cbs <- readIORef (callbacks r)
  mapM_ ($ v) cbs

all the remaining IORef-like interface is present too.

By using these callbacks for updating GUI I can be sure all it's parts are in sync.

I suspect it's a special case of more general idea. Can anyone give a hint?

Also, do you think it's useful enough to be uploaded to Hackage? Or maybe something similar is already there?

How do you organize your GUI applications?

Best wishes,
Dmitry

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to