Why doesn't this work?

BlitzMax Forums/MaxGUI Module/Why doesn't this work?

TeraBit(Posted 2006) [#1]
Hi All,

I am trying to write a custom gadget using a simiar event model to the one below.

But I can only get one of them to work at a time. If I create more than one instance, either the application will exit without a word (in Debug Build), or only one of the works (Non Debug).

Should I post it in the Bug forum, or am I doing something silly?




Mark Tiffany(Posted 2006) [#2]
This just runs & exits for me...


Mark Tiffany(Posted 2006) [#3]
...and it's the AddHook that fails. I'm not sure you can reference "Self" in a "New" method?


Mark Tiffany(Posted 2006) [#4]
Okay, the above code runs for me if I amend eventhook to check that I received an event before processing it - presumably I'm getting some kind of weird non-event being raised? In any case, window test2 is not showing anything, which presumably is your bug...
	Function eventhook:Object(id,data:Object,context:Object)
		Local	event:TEvent
		Local	app:TApplet
		event = TEvent(data)
		If Not event Then return
		app=TApplet(context)
		app.OnEvent event	
	End Function



Mark Tiffany(Posted 2006) [#5]
And here's the fix:

	Function eventhook:Object(id,data:Object,context:Object)
		Local	event:TEvent
		Local	app:TApplet
		event = TEvent(data)
		If Not event Then Return data
		app=TApplet(context)
		app.OnEvent event	
		Return data
	End Function

Why does this fix things? When Bmx calls the eventhooks, it calls them in sequence until one returns Null. If Null is returned, it assumes the eventhook has handled the event and stops calling subsequent eventhooks, if the object is returned, it moves on to the next eventhook. You were "firing blanks", and so your second gadget never received a darn thing!

Sometimes you want the event to "pass through" all eventhooks, and do something with each, and this is what I've done here. This is the simplest thing to do, but means lots of unnecessary processing, and potential for bugs if you forget to check what gadget the event is intended for.

The best thing to do however, is to use the following:
	
	Method OnEvent:Integer(Event:TEvent) Abstract

	Function eventhook:Object(id,data:Object,context:Object)
		Local	event:TEvent
		Local	app:TApplet
		event = TEvent(data)
		If Not event Then Return data
		app=TApplet(context)
		If app.OnEvent(event) Return
		Return data
	End Function

You then change your code in OnEvent to return null if it has handled the event and nothing else needs to know about it.

There's actually another issue in your OnEvent code. You are handling ALL events for ALL gagdets here. You should check that the event is related to your gadget(s) before handling it. For example, there is a timer and a canvas in each gadget. you are processing each event twice in each gadget, because you're not checking that it relates to you.

So, here's the fully fixed code (unless I missed something else of course!)



TeraBit(Posted 2006) [#6]
Hi,

Thanks for that. The hook code was copied from the examples in the BlitzMax documentation, so I wasn't really expecting it to bomb out.

Thanks for the help.