Flushing extra touch events
|
|
Paladin Pinion
The other one of 10
Join date: 3 Aug 2007
Posts: 191
|
01-13-2009 15:12
I want an object to rotate while the mouse is down on it so I scripted a touch event. It works, but too many events pile up in the queue and the object continues to rotate long after the mouse is released. Is it possible to prevent so many touch events from occuring?
I know I can start rotation on touch_start, trigger a timer, and stop it on touch_end. But if it's possible to just slow down the touch events or eliminate the extras, that would be much easier and save some scripting.
Just happened to think, would adding a brief sleep command in the touch event slow it down or would it make them pile up even faster? (Not inworld or I'd test it.)
|
|
Nexii Malthus
[Cubitar]Mothership
Join date: 24 Apr 2006
Posts: 400
|
01-13-2009 15:57
llMinEventDelay might be what you are looking for rather.
Use touch( integer d){} to rotate and set min event delay to 0.2-0.25 sec, that should cover the delay indured by llSetRot and similiar functions that induce their own sleeps.
_____________________
 Geometric Library, for all your 3D maths needs. https://wiki.secondlife.com/wiki/Geometric Creator of the Vertical Life Client
|
|
Paladin Pinion
The other one of 10
Join date: 3 Aug 2007
Posts: 191
|
01-13-2009 16:20
Thanks, I'll definitely try it, you're right that it is probably the way to go.
The wiki isn't clear whether the delay affects all scripts in the object and all its prims, or just the current script. Also, I'd want to set it back to a normal delay on touch_end, but the wiki isn't clear how to do that either. Anyone know?
|
|
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
|
01-13-2009 17:24
From: Paladin Pinion Thanks, I'll definitely try it, you're right that it is probably the way to go.
The wiki isn't clear whether the delay affects all scripts in the object and all its prims, or just the current script. Also, I'd want to set it back to a normal delay on touch_end, but the wiki isn't clear how to do that either. Anyone know? I THINK it is only the current script Certainly each script has its own queue. Should be easy to test using timers in any case. Give it a try, and let us know what you come up with.  To set the delay back again, you should be able to just use llMinEventDelay() again with a smaller delay (min is 0.05; I'm sure if you use that--or probably any smaller value--it'll go back to default behavior).
|
|
Rolig Loon
Not as dumb as I look
Join date: 22 Mar 2007
Posts: 2,482
|
01-13-2009 17:25
Can't you just set llMinEventDelay(0.1) in your touch_end event? I think the default delay after an event is 0.1 seconds.
|
|
Paladin Pinion
The other one of 10
Join date: 3 Aug 2007
Posts: 191
|
A few tests
01-14-2009 11:09
Okay, I played around with all this. I set a delay on touch_start of 0.5 seconds, and had a touch event say the script time. It works fine, the object chatted every half second. On touch_end I set the delay to 0.0 and triggered a timer, which reported the script time. This chatted a quarter-zillion times per second. So the technique appears to work. I got slow chat while mousing down, and fast chat after I let go.
There's a glitch though. I had to set the delay to a full second before SL recognized the mouse release fast enough, and even then rotation triggered one more time before SL noticed I'd let go. That's okay for what I'm doing, but rotations a full second apart are very jerky, which is to be expected. So for smooth rotation while the mouse is down, I think I'll need to implement a timer on touch_start and remove it on touch_end. I'm sorry about that because using the touch-only approach would be much more elegant and save script space.
I didn't test whether the delay affects all scripts in the object or only the current one, because a) Heewee is never wrong, and b) it was 2 AM.
|
|
Void Singer
Int vSelf = Sing(void);
Join date: 24 Sep 2005
Posts: 6,973
|
01-14-2009 12:27
actualy using a timer is ver elegent for your situation, basically replacing the touch event, you can avoid excess execution by using a variable in the timer event call from touch start, and instead of stopping the timer in touch end, just set the variable to 0, and test it in the timer event like so timer(){ if (gFltTimer){ //- do rotation } }
that should catch any timer events that were already queued but will occur after touch stop
_____________________
| | . "Cat-Like Typing Detected" | . This post may contain errors in logic, spelling, and | . grammar known to the SL populace to cause confusion | | - Please Use PHP tags when posting scripts/code, Thanks. | - Can't See PHP or URL Tags Correctly? Check Out This Link... | - 
|
|
Paladin Pinion
The other one of 10
Join date: 3 Aug 2007
Posts: 191
|
01-14-2009 16:10
I was trying not to leave timers running when they weren't necessary. Am I trying too hard to be a good citizen?
|
|
Void Singer
Int vSelf = Sing(void);
Join date: 24 Sep 2005
Posts: 6,973
|
01-14-2009 18:28
I forgot a line lol... timer(){ if (gFltTimer){ //-- do rotation }else{ llSetTimerEvent( gFltTimer ); } }
there, no more rampant timer
_____________________
| | . "Cat-Like Typing Detected" | . This post may contain errors in logic, spelling, and | . grammar known to the SL populace to cause confusion | | - Please Use PHP tags when posting scripts/code, Thanks. | - Can't See PHP or URL Tags Correctly? Check Out This Link... | - 
|
|
Paladin Pinion
The other one of 10
Join date: 3 Aug 2007
Posts: 191
|
01-14-2009 19:37
I see now. Thanks very much, I'll give it a go. Should work fine. 
|
|
Paladin Pinion
The other one of 10
Join date: 3 Aug 2007
Posts: 191
|
01-14-2009 23:39
Well...it should have worked fine. It turns out to work the same as the other methods I tried. Here's my first timer script: touch_start(integer num) { llMessageLinked(LINK_ROOT,2,"rotate",""); llSetTimerEvent(0.75); } touch_end(integer num) { llSetTimerEvent(0.0); } timer() { llMessageLinked(LINK_ROOT,2,"rotate",""); }
The timer can't be much shorter than .75 secs or the object continues to rotate long after the mouse goes up. Otherwise the messages get queued. Next I implemented Void's suggestion: integer rotFlag = FALSE;
touch_start(integer num) { rotFlag = TRUE; llSetTimerEvent(0.25); } touch_end(integer num) { rotFlag = FALSE; } timer() { if (rotFlag) llMessageLinked(LINK_ROOT,2,"rotate",""); else llSetTimerEvent(0.0); }
This also queues the messages. The object kept rotating long after the mouse was released. The only way I could get this to work right was to increase the timer back up to .75, which prevents the pile-up but performs the same as the other methods. I never mentioned that I have to use a link message. The controller is a child prim and so it needs to send a message to the root, so that the whole linkset will turn. Is that the problem?
|
|
Void Singer
Int vSelf = Sing(void);
Join date: 24 Sep 2005
Posts: 6,973
|
01-15-2009 10:26
you might try something that might be slightly faster for switch, but I'm not sure about timing. move the child scripts to the root, and use SetLink in them instead, and instead of using link messages, use changed events and hidden prim properties (like hidden face) to trigger them. that may eliminate queing issues, not sure.
_____________________
| | . "Cat-Like Typing Detected" | . This post may contain errors in logic, spelling, and | . grammar known to the SL populace to cause confusion | | - Please Use PHP tags when posting scripts/code, Thanks. | - Can't See PHP or URL Tags Correctly? Check Out This Link... | - 
|
|
Zen Zeddmore
3dprinter Enthusiast
Join date: 31 Jul 2006
Posts: 604
|
01-15-2009 10:48
Have you thought about using the llDetectedTouchFace function? I use it as an analog slider control. you could maybe use reports from positions touched to ser=t rotation.
_____________________
A kilogram of programmable nanobots can lower the certainty of both death AND taxes.
|