running wxApp main loop by hand? Topic is solved

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
User avatar
bsenftner
Knows some wx things
Knows some wx things
Posts: 45
Joined: Thu May 26, 2016 9:19 pm

running wxApp main loop by hand?

Post by bsenftner » Fri May 26, 2017 7:45 pm

I have a released, client using wxWidgets based C++ application, deployed to various flavors of linux and windows. We've just upgraded our application to wxWidgets 3.0.3, from 3.0.1, along with the addition of several new features. One of the new features in our application is a REST communications framework. This REST communications framework wants to have control over the main application loop.

I see from Stackoverflow posts such as this:

https://stackoverflow.com/questions/208 ... tering-the

it is possible to initialize the wxApp by hand. I realize and know from experience wxWidgets GUIs cannot run in a thread that is not main. However, could a wxWidgets based application be executed and maintained in a cooperative polling manner? We have fine grained control to receive callbacks from the REST framework with millisecond accuracy - can one handle the event loop oneself, passing "main thread" level control to wxWidgets for one event loop in each of the REST framework callbacks, therefore achieving integration of both frameworks that want to control the main loop?

-bsenftner

User avatar
doublemax
Moderator
Moderator
Posts: 13182
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: running wxApp main loop by hand?

Post by doublemax » Fri May 26, 2017 7:57 pm

I realize and know from experience wxWidgets GUIs cannot run in a thread that is not main.
To be exact: All gui operations must happen in the same thread in that wxWidgets was initialized. I.e. you can create a secondary thread, initialize the library there and all gui operations can and will happen in that thread. The "DLL" sample does this. This method is used, e.g. if you write a PhotoShop plugin using wxWidgets.

I don't know if this helps in your case.

I would suggest to ask again on the wx-users mailing list. Vadim is probably the only one who can give a full answer here.
https://groups.google.com/forum/#!forum/wx-users
Use the source, Luke!

User avatar
bsenftner
Knows some wx things
Knows some wx things
Posts: 45
Joined: Thu May 26, 2016 9:19 pm

Re: running wxApp main loop by hand?

Post by bsenftner » Thu Jun 01, 2017 12:24 am

My final solution works quite well. I've integrated the C++ REST framework Restbed, which has its own looping main, similar to wxWidget's event loop.

https://github.com/Corvusoft/restbed

Restbed's looping main is spawning threads to handle incoming REST requests, each in it's own thread. As the REST communications is the main purpose of the application, the wxWidgets GUI is the "seldom used" admin console. Additionally, Restbed spawns a "Service Ready" callback thread that is convenient to run wxWidgets on.

From the Restbed Service Ready callback, I call:

Code: Select all

/* in place of the commented out IMPLEMENT_APP() above, this boots the GUI: */
int LaunchGUI(int argc, char** argv)
{
	wxApp* pApp = new AureusREST();
	wxApp::SetInstance(pApp);
	wxEntryStart(argc, argv);
	wxTheApp->OnInit();

	// this performs the wxWidgets event loop, 
	// only returning after the user has 'closed' the GUI
	wxTheApp->OnRun();

	// cleaning up...
	wxTheApp->OnExit();
	wxEntryCleanup();

	return 0;
}
And the Restbed Service Ready Handler is simply:

Code: Select all

void CX_REST_API::service_ready_handler(Service&)
{
	Aureus_rest_log("*** The Aureus REST Service is Live.");

#ifdef _WIN32
	Aureus_rest_log("*** Service PID is '%i'.", _getpid());
#else
	Aureus_rest_log("*** Service PID is '%i'.", getpid());
#endif

	// launch wxWidgets:
	LaunchGUI(__argc, __argv);

	// time to die:
	aureus_cleanup();
	exit(EXIT_SUCCESS);
}
Surprisingly easy. :)

Post Reply