wxhaskell asynchronous updates

I am using WxHaskell to graphically show the state of a program that advertises state updates using TCP (which I decode using Data.Binary). When an update is received, I want to update the display. So I want the GUI to update its display asynchronously. I know that processExecAsync runs a command line process asynchronously, but I don't think this is what I want.

--------------Solutions-------------

This is rough code using transactional variables (i.e. software transactional memory). You could use an IORef, MVar, or numerous other constructs.

main = do
recvFunc <- initNetwork
cntTV <- newTVarIO 0
forkIO $ threadA recvFunc cntTV
runGUI cntTV 0

Above you start the program, initialize the network and a shared variable cntTV

threadA recvCntFromNetwork cntTVar = forever $ do
cnt <- recvCntFromNetwork
atomically (writeTVar cntTVar cnt)

threadA receives data from the network and writes the new value of the counter to the shared variable.

runGUI cntTVar currentCnt = do
counter <- initGUI
cnt <- atomically $ do
cnt <- readTVar cntTVar
if (cnt == currentCnt)
then retry
else return cnt
updateGUICounter counter cnt
runGUI cntTVar cnt

runGUI reads the shared variable and if there is a change will update the GUI counter. FYI, the runGUI thread won't wake up on retry until cntTVar is modified, so this isn't a CPU hogging polling loop.

In this code I've assumed you have functions named updateGUICounter, initGUI, and initNetwork. I advise you use Hoogle to find the location of any other functions you don't already know and learn a little about each module.

I have come up with a kind of hack that seems to work. Namely, use an event timer to check an update queue:

startClient :: IO (TVar [Update])
startClient = /*Connect to server,
listen for updates and add to queue*/

gui :: TVar [Update] -> IO ()
gui trdl = do
f <- frame [text := "counter", visible := False]
p <- panel f []
st <- staticText p []
t <- timer f [interval := 10, on command := updateGui st]
set f [layout := container p $ fill $ widget st, clientSize := (sz 200 100), visible := True]
where
updateGui st = do
rdl <- atomically $ readTVar trdl
atomically $ writeTVar trdl []
case rdl of
[] -> return ()
dat : dl -> set st [text := (show dat)]

main :: IO ()
main = startClient >>= start gui

So a client listens for the updates on the TCP connection, adds them to a queue. Every 10ms, an event is raised whose action is to check this queue and show the latest update in a static text widget.

If you have a better solution, please let me know!

I found a solution without a busy wait at: http://snipplr.com/view/17538/

However you might choose a higher eventId in order to avoid conflicts with existing ids.

Here is some code from my module http://code.haskell.org/alsa/gui/src/Common.hs:

myEventId :: Int
myEventId = WXCore.wxID_HIGHEST+100
-- the custom event ID, avoid clash with Graphics.UI.WXCore.Types.varTopId

-- | the custom event is registered as a menu event
createMyEvent :: IO (WXCore.CommandEvent ())
createMyEvent =
WXCore.commandEventCreate WXCore.wxEVT_COMMAND_MENU_SELECTED myEventId

registerMyEvent :: WXCore.EvtHandler a -> IO () -> IO ()
registerMyEvent win io =
WXCore.evtHandlerOnMenuCommand win myEventId io

reactOnEvent, reactOnEventTimer ::
SndSeq.AllowInput mode =>
Int -> WX.Window a -> Sequencer mode ->
(Event.T -> IO ()) ->
IO ()
reactOnEvent _interval frame (Sequencer h _) action = do
mvar <- MVar.newEmptyMVar

void $ forkIO $ forever $ do
MVar.putMVar mvar =<< Event.input h
WXCore.evtHandlerAddPendingEvent frame =<< createMyEvent

registerMyEvent frame $
MVar.takeMVar mvar >>= action

-- naive implementation using a timer, requires Non-Blocking sequencer mode
reactOnEventTimer interval frame sequ action =
void $
WX.timer frame [
WX.interval := interval,
on command := getWaitingEvents sequ >>= mapM_ action]

The code shows two ways to handle the problem:

  • reactOnEventTimer does a busy wait using the WX timer.
  • reactOnEvent only gets active when an event actually arrives. This is the prefered solution.

In my example I wait for ALSA MIDI sequencer messages. The Event.input call waits for the next ALSA message to come. The action gets the results of Event.input, that is, the incoming ALSA messages, but it is run in the WX thread.

Category:haskell Time:2010-07-05 Views:0

Related post

  • Synchronous vs. Asynchronous updates in Real-time applications 2011-03-04

    I am looking to update an application in which I have the ability to update synchronously or asynchronously. For the real-time nature of the app, which currently ranges from a synchronous execution of methods ranging in frequencies from 1-60Hz, do yo

  • I have an aspx page with master page and i want to asynchronous update the ContantPlaceHolder 2011-04-26

    I have an aspx page with master page and i want to asynchronous update the ContantPlaceHolder, i think about apdate panel, when the user submit the actions the update panel will close and open again with the solution, or to use an: ContentPlaseHolder

  • How to display varying cell layouts with asynchronously updating text and images? 2011-07-25

    I am working on a remote controlling app for a home automation system. The mobile and the home automation device communicate via WebSockets. To display the functions of the automation device, I am currently using ListViews and Adapters with a varying

  • Asynchronous update Android context menu 2012-01-13

    Word up, I need to update a context menu for a widget (listview in this case). The items for the menu need to come from a call to a web service. If the web service call is made synchronously on the main UI thread then this works. However due to fact

  • MVC in Android: Application or Service for asynchronous updates? 2010-07-03

    (I'm sorry for not being so clear in my first post) Here is the situation: I have data that is to be refreshed from the Internet. Let's call it Model. What I want to do: Basically it sounds like an MVC model, where the Model is also kept persistent i

  • Does WPF-DataBinding support asynchronous updates 2010-08-15

    I changed accidentally the value of a BusinessObject-property that implements INotifyPropertyChanged from within a BackgroundWorker (BackgroundWorker.DoWork). Amazingly, this led not to an error but actualized the text of the TextBlock that was bound

  • Asynchronous updating 2011-05-13

    I'm new to ajax and like how it can do things asynchronously without having to reload the page. If I wanted to update my shopping cart total without having to actually hit the "update" button could it be done with the XMLHttpRequest object in this. T

  • Asynchronous update/ deletion of data 2011-07-22

    I still consider myself a beginner when it comes to JQUERY+Coldfusion...so I'd like to ask for help/ direction on this. I'm trying to make a search page of items that acts similar to gmail. There is a delete button and basically it asynchronously del

  • Databinding issue with class that is asynchronously updated 2009-08-19

    When I bind a BindingList<ProcessDataItem> to a ComboBox an InvalidOperationException is thrown saying, that the collection that is enumerated changed. Instances of ProcessDataItem permanently receive updates when their corresponding measuremen

  • Asynchronously updating PyGTK tray icon 2011-01-16

    As explained here, I have a simple tray icon using PyGTK. Being very new to GTK, it appears to me that gtk.main() is synchronous, blocking any further processing until the respective UI is closed. So how can I periodically (e.g. every 5 seconds) upda

  • Asynchronous updating DIV layer without AJAX 2011-12-27

    Is there any way to update a HTML DIV layer in ASP.NET/C# for every 2 seconds without using AJAX triggers. Preferably using JavaScripts (Major priority) or jQuery (If not possible with JavaScripts). --------------Solutions------------- if you have to

  • Is there a better way to create asynchronous updates without using setInterval? 2012-03-13

    I have multiple parts of my site which check for updates every half a second, so it can alert you of messages, etc. However I feel that using $.post with a setInterval could be a bit heavy on the site. Is there an alternative method that is better re

  • Asynchronous updating / AJAX in Django 1.4 2012-04-16

    Hi I am still new to Django and have not worked with Ajax before. I am building an app where two players are able to chat, so it's basically a chatbox and I want the page to update for one player when the other player enters text on their page. I was

  • Prototype PeriodicExecutor doesn't update source 2009-05-22

    I have a script that updates a table when there are new entries in the database. It pulls a time from the last row in the table and then grabs all the entries that were entered since then. It runs fine the first time, it grabs the new entries and upd

  • How would I create an asynchronous notification system using RESTful web services? 2009-07-07

    I have a Java application which I make available via RESTful web services. I want to create a mechanism so clients can register for notifications of events. The rub is that there is no guarantee that the client programs will be Java programs and henc

  • Asynchronous UpdatePanel within WordPress Post 2009-08-20

    I am demoing bit of JavaScript in a WordPress blog post that randomly produces some content. I'd like the user to be able to click a button and regenerate new random content via the script, and I'd like to do it asynchronously. Does anyone have exper

  • UpdatePanel.Update(), nothing seems to happen 2009-10-01

    I'm working with an UpdatePanel that I'd like to refresh programmatically on the server side. The reason is I display some data that takes a pretty long time to load, so I need to display the page and some sort of progress meanwhile. What I did is th

  • Update mechanism theory 2009-12-21

    I write engineering applications at work in C# .NET. Often, these applications have complex update mechanisms, at least the I end up writing complex update mechanisms. Can anyone direct me to some books or something where I can learn update theory? S

  • .NET LINQ-to-SQL asynchronous commit 2010-02-04

    i am considering - in order the get a high performance application - to keep a single DataContext in the cache to perform the selects and updates to... In order the keep the responsetimes low, i'd like to create an asynchronous update like the one i

Copyright (C) pcaskme.com, All Rights Reserved.

processed in 0.552 (s). 13 q(s)