Wait for event - Need help

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
Post Reply
lakshmy
In need of some credit
In need of some credit
Posts: 4
Joined: Mon Jun 16, 2008 9:23 am

Wait for event - Need help

Post by lakshmy » Thu Feb 05, 2009 4:01 pm

Hi,

In my application, i need to load a file. The loading is actually done by another process, which generates an event on succesful completion of loading. My application will catch this event and process it. I need to suspend the main thread for a while, while waiting for an event and continue further.
i.e.

Code: Select all

MyProcess::test()
{
loadfile(); //The loading is done by another process. On successful loading, an event is generated and intimated to my application. 

//here i need to suspend till the event is received. There is another function that handles this event.
My program should continue from this point after processing this event.
....
....
}
Process2::loadfile()
{
load the file 
generate event();
}
MyProcess::eventhandler()
{
}
The issue is that my application is single threaded. I don't want to use multithreading in my program.
I need to know is there anything like WaitForEvent(event name) which behaves similar to WaitforAccept(), that allows the application to know whether there is any event of the desired type waiting to be processed and allows the control to be switched to the eventhandler() and continue from there

Regards,
Lakshmy

User avatar
Disch
Experienced Solver
Experienced Solver
Posts: 99
Joined: Wed Oct 17, 2007 2:01 am

Post by Disch » Fri Feb 06, 2009 5:10 am

This seems like a strange design... but you might be able to accomplish this by sleeping with periodic calls to wxApp::Yield to keep the event pump moving.

Code: Select all

void MyProcess::test()
{
  loadfile();

  // wait for event
  eventreceived = false;
  while(!eventreceived)
  {
    wxMilliSleep(100);
    wxGetApp().Yield();
  }

  // resume with whatever
}

void MyProcess::EventReceived(wxWhateverEvent& event)
{
  eventreceived = true;
}
EDIT

Note the danger for potential deadlock if the event is never received. Maybe incorporate some kind of timeout to prevent deadlock.

Code: Select all

  // wait for event
  ::wxStartTimer();
  eventreceived = false;
  while(!eventreceived)
  {
    wxMilliSleep(100);
    wxGetApp().Yield();
    if(::wxGetElapsedTime() > 10000)
      return;         // abort if taking longer than 10
                      //   seconds to respond
  }

EDIT2 (last edit I swear)

Forgot about the caveats involved with wxApp::Yield. Perhaps try ::wxSafeYield instead.

Lakshmyb
In need of some credit
In need of some credit
Posts: 6
Joined: Thu Oct 23, 2008 8:19 am

Post by Lakshmyb » Fri Feb 06, 2009 10:01 am

But in this case we are not waiting for a specific event, right?
I want my process to wait for a particular custom event. Can I configure yield such that it yields only to the custom event?

User avatar
Disch
Experienced Solver
Experienced Solver
Posts: 99
Joined: Wed Oct 17, 2007 2:01 am

Post by Disch » Fri Feb 06, 2009 3:01 pm

Lakshmyb wrote:But in this case we are not waiting for a specific event, right?
I want my process to wait for a particular custom event.
That's pretty much exactly what this does -- unless I'm misunderstanding you.

This code would wait until the custom event is triggered. The reason why is because it waits for the 'eventreceived' var to be set to true before proceeding. So to make this respond to your custom event, just have your custom event handler set 'eventreceived' to true. Other events will not change this var and therefore will not stop this loop from waiting.

Other events triggered during the wait period (like stuff triggered by mouseclicks and whatnot) will be processed as well if you use wxGetApp().Yield(). Therefore it would be possible for the user to try to open another file while you're already trying to open a file, which would probably be disasterous in your code. Therefore the ::wxSafeYield() approach is probably better, as this would block window events like menu selections because it disables user input during the yield, but shouldn't block your custom event.

Although -- I'm not 100% positive GUI events triggered during the wxMilliSleep will be blocked. You might have to manally disable the frame and menu before you start waiting, and re-enable them afterwards.

Post Reply