EventSourceHandle changed by timer?!

BlitzMax Forums/MaxGUI Module/EventSourceHandle changed by timer?!

Taron(Posted 2008) [#1]
Using the timer appearantly makes the eventsource change and unreliable...

Try this piece of code and tell me if I'm nuts?!
Does anyone have an idea what happens here and how to resolve the problem?

Import MaxGUI.Drivers

SuperStrict

Global window:Tgadget = CreateWindow:TGadget("EventSource Test", Desktop().width*0.35, Desktop().height*0.35, 320, 240)', Null, WINDOW_CENTER | WINDOW_CLIENTCOORDS)
Global panel:Tgadget =CreatePanel(0,0,ClientWidth(window),ClientHeight(window),window,PANEL_ACTIVE|PANEL_GROUP,"click repeatedly here to see EventSourceHandle change!")
Global label:Tgadget = CreateLabel("EventSourceHandle() =",60,60,150,20,panel)
Global timer:Ttimer = CreateTimer(10)

Function MyHook:Object(iId:Int,tData:Object,tContext:Object)
	Local Event:TEvent = TEvent(TData)
	
	If event = Null Return Null
	
	Select Event.id
		Case EVENT_MOUSEDOWN
			SetGadgetText(label, "EventSourceHandle() = "+EventSourceHandle())
		Case EVENT_TIMERTICK
			If TimerTicks(timer)>10
				StopTimer(timer)
				timer = CreateTimer(10)
			EndIf
	EndSelect
	Return TData
End Function

AddHook EmitEventHook, MyHook

While True
	WaitEvent()
	Select EventID()
		Case EVENT_WINDOWCLOSE
			End
	EndSelect
Wend



Difference(Posted 2008) [#2]
It looks to me like you are creating new timers all the time.
They will have differnet handles. What is the problem?


SebHoll(Posted 2008) [#3]
It looks to me like you are creating new timers all the time.
They will have differnet handles. What is the problem?

The "problem" arises because you are using BRL.EventQueue commands in an event hook.

The BRL.EventQueue functions (EventSourceHandle() being one of them) is designed to return event information from the first event in the event queue. When you set up an event hook, you are asking BlitzMax to pass the event to your function for you to process, before it is added to the event queue. Hence, if you attempt to use any of the BRL.EventQueue functions while in an event hook, you may not be processing the correct event.

Instead of EventSourceHandle(), you would have to use...

HandleFromObject( Event.source )
...although I really wouldn't recommend using integer handles as they are pain when it comes to garbage collection. If you simply want to print a unique identifier for an object, you could perhaps instead print its memory address, i.e.

Print Int ( Byte Ptr Event.source )
Hope this helps!


Difference(Posted 2008) [#4]
The below example shows that the changing handle is due to creating new timers



Taron(Posted 2008) [#5]
Uh, thanks guys! Well, yup, I know it's the creation of new timers, but it's been part of the logic I chose to do the playing/stopping routine and I assumed this to be the most straight forward solution within eventqueing.

I'll try the Byte Pointer solution, sounds very interesting!

There's still so much I have to learn about it all, it's crazy and wonderful.

So, yeah, thanks again, I'll report back once I have news...hehe...


Taron(Posted 2008) [#6]
I guess the problem with the byte ptr is that I have to first find out where the source will at startup. I think I may have to go an entirely different route with the timing.... I can't wrap my mind around it just yet, but I'll try some things. It may be a silly problem altogether, but well...

It's a simple play routine for my synthiziser, enabling a time bar slipping over the waveform during play.
Repeating is always updating the sample before the next repeat, so that you can edit the sound during playback.
The timer has been causing me trouble right from the start, due to its aggressiveness over other events. Without the timer editing runs perfectly smooth, but as soon as a timer runs it can't get continuous eventqueues up to the point where slower systems almost freeze up completely.

Any clues would be very welcome, even if I almost find some in your feedback above already! It's very good and I'll keep exploring...


SebHoll(Posted 2008) [#7]
It depends upon the structure of your code. If most of your code handling is through event queues, then you might want to try processing the timer events through a hook that returns Null. This will mean that the event queue will never see any of time timer events and so will not get clogged up by them.

Does this work any better?


Taron(Posted 2008) [#8]
UH WOW, that was a fantastic tip! Thanks a whole bunch! I think this works famously!

I'll post an update of my synth right away, wonna try? :o)

I've added some demo sounds to it, too, now... but it's all still rather coarse (win32):
Syntaron.rar


SebHoll(Posted 2008) [#9]
Glad to hear! There are some other things that I should probably mention...

If you are using timers, always place their event handling code at the top of your Select...Case block, as unlike C switch blocks, BlitzMax doesn't use jump tables and so the further down the block you place it the more comparisons it has to make before it finds it. This isn't really much of a problem normally, but if your timers are firing lots of times per second, it can really add up.

In addition, it is good practice that your event hook returns the data back if it can't understand it as opposed to returning Null. For example, you should do something like...

Function MyHook:Object(iId:Int,tData:Object,tContext:Object)
	
	Local event:TEvent = TEvent(tData)
	If Not event Then Return tData
wonna try?

I downloaded it and had a look, but to be perefectly honest, I'm not entirely sure what it does... I did however notice that your EXE size is relatively large... Are you using Framework Assistant to ensure that BlitzMax only imports the libaries it needs?

Anyway, glad I could help...


Taron(Posted 2008) [#10]
UH, oh my god, thank you! That's brilliant! I'll set up the assistant right away!!!

One may never know what a question can trigger in terms of brilliant advice. Wow, wow, wow.

What it does:
Syntaron is a sound designer, that creates tiny datasets, which then can get used in your game engine to create all the sounds at startup time and safe plenty of "wav" memory on the disk.

You would make your sound using various markers for envelopes (volume, pitch, filter, etc... (more to come later)), save it as ".syt" and then incbin the .syt in your game, also adding the soundgenerator, which is a tiny bit of code and voila! :)

Load up some of the demo sounds and you'd see what such a sound would look and sound like. It's still in the early stages, but it works already quite well.

You can also save out .wav files, if you wish, in case you'd want to make music with them elsewhere, hehe. It's not that bad for melodies actually.

OH, you can always check my thread on the showcase forum...
Syntaron - W.I.P
(by the way, I just updated that rar file, so you could download it again, but I'll look into the assistant now and may upload another version tonight, if I get it going right away...)


Taron(Posted 2008) [#11]
MUCH BETTER! I've used the assistant and it cut the size in half. I'm not sure if it can be any more compact in terms of library use in any convetional way, but it's already fantastic! Thank you very much!

The new Syntaron.rar is uploaded!


SebHoll(Posted 2008) [#12]
Cool. Another thing you might want to add is drag n' drop support, so that you can drag your .syt files from Windows Explorer onto the Syntaron window to open them. This can be easily done by adding the WINDOW_ACCEPTFILES flag to your CreateWindow() call, and processing the EVENT_WINDOWACCEPT event when it is fired, and opening the path using String( event.extra ).

Finally, on Vista, some of the text is chopped off from the resonance label.



Always leave as much room as possible for labels to run out onto as your end-users PC may use larger system fonts.

Ooh, and finally, if I was going to be really picky, the grey disk symbol for Save (in the toolbar) gives the impression that it is disabled. Is this for a reason?


Taron(Posted 2008) [#13]
Wowsa, how fancy it looks in vista, haha! That's awesome, HAHA! Nice!

Well, damn, that's a good observation, I'll go through the labels next.
And the disk symbol... DOH... was supposed to be stylish, but it's true, it looks very disabled here. I'll go over that all right away!

Thanks very much, again! Man, you're making me happier every time! 8)

Taron


Taron(Posted 2008) [#14]
Done! :o)
Syntaron alpha 1.2 ...now with drag&drop and longer labels..hehe!