wxWidgets: mainloop.bmx

BlitzMax Forums/BlitzMax Programming/wxWidgets: mainloop.bmx

Scaremonger(Posted 2008) [#1]
Previously posted Here
(but content got so large that it was difficult to find)

Scaremonger wrote:
The mainloop.bmx example does not exit properly. The loop continues to run after the window has closed because the loop is a While True..Wend

Is there an equivalent to appTerminate() that can be used to force it to exit, or should we pick up the wxEVT_CLOSE event and set our own flag ?


Brucey wrote:
Yeah... I've kind of not got my head around that completely yet - hence all the debug.

The idea is to run your own main-loop, rather than let wxWidgets run its own - which is normally the case. While at the same time, try to control it from BlitzMax.

The difficulty is finding clear examples on the net that show it in action.


An example on This Page shows a mainloop something like this: But I cannot find the identifier m_shouldExit !!

<-- SNIP -->


Scaremonger(Posted 2008) [#2]
Based on several examples I've found dotted around, the Mainloop.bmx sample should look something like this.

SuperStrict

Framework wx.wxApp
Import wx.wxFrame

Type MyApp Extends wxAppMain
	Field frame:wxFrame
	Global shouldExit:Int = False
	
	Method OnInit:Int()

		frame = wxFrame.CreateFrame(,,"Hello World", 100, 100)
		frame.show()
	
		'# Connect exit event
		frame.Connect(, wxEVT_CLOSE,onQuit)

	Return True
	End Method
	
	Method MainLoop:Int() 
		While True
			While Not Pending() And ProcessIdle() ; Wend
			While Pending()
				If Not Dispatch() Then
					shouldExit = True
					Exit
				End If
			Wend
			If shouldExit Then
				While pending() 
					dispatch() 
					Return 0
				Wend
			End If
DebugLog "While loop"
		Wend
	End Method
	
	Function OnQuit(event:wxEvent) 
		MyApp.shouldExit = True
	End Function

End Type

New MyApp.run()



Brucey(Posted 2008) [#3]
Cool.. but do you think one should have to add their own "idle wait", or should it be doing it itself?

Cuz here it is maxing out the CPU - or maybe that's what it should be doing?


Scaremonger(Posted 2008) [#4]
Perhaps it should be doing it itself, but I guess the idea was to allow the programmer to take complete control of wxWidgets.

As for maxing out the CPU, I must admit I didn't check it, but again perhaps it's down to the programmer to create an efficient loop. At least you know that you are being given enough processor time to run your game. :)


Brucey(Posted 2008) [#5]
At least you know that you are being given enough processor time to run your game.

Very true ;-)

I'm guessing that something like Yield() will give some time back to the OS then.


Scaremonger(Posted 2008) [#6]
Adding yield() in the loop doesn't seem to make much difference. I've tried adding it into different parts of the mainloop without any real difference.

I imagine that the contents of the ProcessIdle() or Pending() will be doing the yield internally, otherwise the OS would cease to function when the app ran.


Scaremonger(Posted 2008) [#7]
I found a bug in the above code, which meant some final messages may not be processed, and the application may terminate "dirty"

Within the message loop, the return statement was in the wrong place. It should read:
	Method MainLoop:Int() 
		While True
			While Not Pending() And ProcessIdle() ; Wend
			While Pending()
				If Not Dispatch() Then
					shouldExit = True
					Exit
				End If
			Wend
			If shouldExit Then
				While pending() 
					dispatch() 
				Wend
				Return 0
			End If
DebugLog "While loop"
		Wend
	End Method



Brucey(Posted 2008) [#8]
Yeah, I found it very fiddly originally, which is why I ended up leaving it in the state it was.

Anyhoo.. it's checked in now. Thanks! :-)