strange event issue

BlitzMax Forums/MaxGUI Module/strange event issue

Ghost Dancer(Posted 2014) [#1]
I've started getting an 'unhandled exception: attempt to index array beyond length' error in my event code.

Here's a little snippet:

Method rawEvents(event:TEvent)
	If Not event Then Return

	Select event.ID
	Case EVENT_MENUACTION
		Select event.Source      '<<<--- error occurs on this line


The error only occurs when I use a hot key - its fine when I select the same option directly from the context menu. It doesn't happen every time either, so it does seem to be situational.

I don't understand how this can error as its basic event code. Any ideas what might cause this?

Edit: Added 'If Not event Then Return' to code snippet.


Henri(Posted 2014) [#2]
Hello,

only thing that I see from your code is that you are not checking if the event is valid.
Here is a minimal menu example for comparison:
SuperStrict

Import maxgui.drivers

New TApp

Repeat
	WaitEvent()
Forever

Type TApp
	
	Field style:Int		= WINDOW_TITLEBAR| WINDOW_RESIZABLE| WINDOW_MENU| WINDOW_CENTER
	Field win:tgadget	= CreateWindow("Menu test",0,0,400,300,Null,style)
	Field menu:tgadget	= CreateMenu("Help",100,WindowMenu(win))
	Field about:tgadget	= CreateMenu("About",101,menu,KEY_S,MODIFIER_COMMAND)
	
	Function main_eventhook:Object(id:Int,data:Object,context:Object)
		If TApp(context) Then TApp(context).OnEvent(TEvent(data))
		Return data
	End Function
	
	Method New()
		UpdateWindowMenu(win)
		AddHook EmitEventHook,main_eventhook,Self
	EndMethod
	
	Method OnEvent(event:TEvent)

		If Not event Return
		
		Select event.id
			Case EVENT_WINDOWCLOSE,EVENT_APPTERMINATE
				End
		
			Case EVENT_MENUACTION
				Select event.source
					Case about		Notify "Hello world"
				EndSelect
		EndSelect
		
	EndMethod
EndType


-Henri


Ghost Dancer(Posted 2014) [#3]
Thanks I'll see if that helps.


Ghost Dancer(Posted 2014) [#4]
Not had the issue again so looks like that fixed it, cheers. Strange that it only recently started happening though - been working on this program for years and not had the issue before.


Ghost Dancer(Posted 2014) [#5]
Resurrecting this thread as I've started getting the error again. I'm still not sure why/when it occurs as it doesn't happen all the time. The array error does not make sense for the line that causes the error - is there some internal max issue that could cause this?

Any and all suggestions would be welcome as these random crashes are making my app unusable.


H&K(Posted 2014) [#6]
Does it make a difference if you use the source objects handle rather than the field itself


Ghost Dancer(Posted 2014) [#7]
Do you mean using EventSource() instead of event.Source?


H&K(Posted 2014) [#8]
Actually I meant EventSourceHandle()

As far as Im aware Eventsource() is just a non oop wrapper for event.source, however its use would probably be the same in what I was thinking. So although that's not what I meant, it isn't what I didn't mean ;)


Ghost Dancer(Posted 2014) [#9]
OK, I see what you mean lol. Dumb question, how do I get the handle of my gadgets to check against EventSourceHandle?


Ghost Dancer(Posted 2014) [#10]
Also, I still don't see how its getting the error: event.source is either a gadget or null, so how can it produce that error?


H&K(Posted 2014) [#11]
You questioning it makes me think its harder than I recall, but I thought EventSourceHandle would be the event source handle (ie effectively an Int variable), of the event you are just got the id of.

My reasoning is you can be more assured that "Select" isn't failing, which your code snippet hasn't convinced me off.
And I always assume that the wrapper is a little bit more secure/bullet proof than the underlying Object.
Quite often I will change to the wrapper for error checking, (well more for concept checking really)


Ghost Dancer(Posted 2014) [#12]
EventSource returns a TGadget, EventSourceHandle returns an Int. I don't know of a way to get an Int handle of a gadget (in this case a menu) - its not something I've had to do before and can't see a function to do it.


H&K(Posted 2014) [#13]
I Assume you posed b4 my edit.

But I'm saying Not to compare them, but to see if the code fails when you use the handle instead.

And if you don't think that its doable, then my idea is wrong


Ghost Dancer(Posted 2014) [#14]
Yeah think I did. It is definitely the Select statement it is erroring on. I just tried this:

	Method rawEvents(event:TEvent)
		If Not event Then Return
		
		Select event.ID
		Case EVENT_MENUACTION
			If event.Source = addEntryOpt Then
				Print "OK"
			End If
			
			Select event.Source
			Case addEntryOpt
				menu_addNode
...


No prob with the If statement, but errored again on Select, which just doesn't make any sense to me at all.


H&K(Posted 2014) [#15]
So.. if we pass select an Int handle instead....

(It make little sense to me, BUT I don't like Select as a structure)


Ghost Dancer(Posted 2014) [#16]
That gives a compiler error as I'm trying to compare an Int to a TGadget. As I said, I don't know how to get a gadget's Int handle.

If I temporarily remove all the case statements then no error occurs, but I can't really test it as the program won't function without the events!


H&K(Posted 2014) [#17]
If event.Source = addEntryOpt
     addEntryOptHandle = EventSourceHandle
End if



Ghost Dancer(Posted 2014) [#18]
Yeah, just changed the select/case statements to If/else and found the problem. It was in one of the actual case statements (there were a lot of case statements otherwise I might have spotted it).

Cheers for your help, it was driving me nuts. I have made a mental note that errors on Select can be misleading!


H&K(Posted 2014) [#19]
No prob


TomToad(Posted 2014) [#20]
Shouldn't you use event.data to test which menu item was selected? Like this?
SuperStrict

Import maxgui.drivers

New TApp

Repeat
	WaitEvent()
Forever

Type TApp
	Const MENU_ABOUT:Int = 101
	
	Field style:Int		= WINDOW_TITLEBAR| WINDOW_RESIZABLE| WINDOW_MENU| WINDOW_CENTER
	Field win:tgadget	= CreateWindow("Menu test",0,0,400,300,Null,style)
	Field menu:tgadget	= CreateMenu("Help",100,WindowMenu(win))
	Field about:tgadget	= CreateMenu("About",MENU_ABOUT,menu,KEY_S,MODIFIER_COMMAND)
	
	Function main_eventhook:Object(id:Int,data:Object,context:Object)
		If TApp(context) Then TApp(context).OnEvent(TEvent(data))
		Return data
	End Function
	
	Method New()
		UpdateWindowMenu(win)
		AddHook EmitEventHook,main_eventhook,Self
	EndMethod
	
	Method OnEvent(event:TEvent)

		If Not event Return
		
		Select event.id
			Case EVENT_WINDOWCLOSE,EVENT_APPTERMINATE
				End
		
			Case EVENT_MENUACTION
				'Select event.source
				Select event.data
					'Case about	Notify "Hello world"
					Case MENU_ABOUT		Notify "Hello world"
				EndSelect
		EndSelect
		
	EndMethod
EndType



Henri(Posted 2014) [#21]
I don't see any reason for event.source to fail, but event.data is probably the intended place.

-Henri


Ghost Dancer(Posted 2014) [#22]
It wasn't a problem with event.source, it was one of the case statements - the fact that the error occurred on the select threw me off the scent!

Guess I could have done it with event.data, result is the same though.