GManB Posted May 30, 2020 Share Posted May 30, 2020 Should I be able to successfully call llSetTimerEvent from within a listen event handler? Code snippet below. Setting the timer works fine from touch_start but not from listen. touch_start(integer num) { if(isSwinging) { isSwinging = FALSE; llSetTimerEvent(0.0); llSetLinkPrimitiveParamsFast(LINK_ROOT, [PRIM_ROTATION,initialRot]); llSetTouchText("Swing"); } else { isSwinging = TRUE; llSetTimerEvent(0.02); llSetTouchText("Stop"); } } timer() { integer stepIndex = 0; llSetTimerEvent(0.0); for(stepIndex=0;stepIndex<fullPeriodSteps;stepIndex++) { llSetLinkPrimitiveParamsFast(LINK_THIS, [PRIM_ROTATION,llList2Rot(rotList,stepIndex)]); if (llList2Integer(sleepList,stepIndex) == TRUE) llSleep(0.01); } llSetTimerEvent(0.1); } listen(integer channel, string name, key id, string message) { list arguments = llParseString2List(message,["|"],[""]); if(channel == privateChannel && llList2String(arguments,0) == "startSwing"); { isSwinging = TRUE; llSetTimerEvent(0.02); } if(channel == privateChannel && llList2String(arguments,0) == "stopSwing"); { isSwinging = FALSE; llSetTimerEvent(0.0); llSetLinkPrimitiveParamsFast(LINK_ROOT, [PRIM_ROTATION,initialRot]); } ...... Thanks, G Link to comment Share on other sites More sharing options...
Rolig Loon Posted May 30, 2020 Share Posted May 30, 2020 I suspect that the problem is that you are firing the timer very fast and are resetting it way too often. I doubt that you can get a timer to trigger at all if you set it with llSetTimerEvent(0.02); There's even a note to that effect in the wiki: If you repeatedly call this function at some interval less than sec the timer event will never fire. As a minor point, you may find it helpful to add parentheses in if tests that include more than one condition. They aren't technically necessary and the compiler should parse things correctly, but if nothing else, extra parentheses make things more human-readable. So, for example.... if( (channel == privateChannel ) && ( lList2String(arguments,0) == "startSwing")) BTW, you have repeated the same fatal error in both if tests in the listen event. Get rid of the semicolon at the end of both. Your script will run as written,. but it will ignore the stuff after each test (or misinterpret it). 😎 Link to comment Share on other sites More sharing options...
GManB Posted May 30, 2020 Author Share Posted May 30, 2020 2 minutes ago, Rolig Loon said: I suspect that the problem is that you are firing the timer very fast and are resetting it way too often. I doubt that you can get a timer to trigger at all if you set it with llSetTimerEvent(0.02); There's even a note to that effect in the wiki: If you repeatedly call this function at some interval less than sec the timer event will never fire. As a minor point, you may find it helpful to add parentheses in if tests that include more than one condition. They aren't technically necessary and the compiler should parse things correctly, but if nothing else, extra parentheses make things more human-readable. So, for example.... if( (channel == privateChannel ) && ( lList2String(arguments,0) == "startSwing")) BTW, you have repeated the same fatal error in both if tests in the listen event. Get rid of the semicolon at the end of both. Your script will run as written,. but it will ignore the stuff after each test (or misinterpret it). 😎 Added parens... semi's were cut-n-paste error "If you repeatedly call this function at some interval less than sec the timer event will never fire." I interpreted this statement to mean, given that 'sec' is bold and dotted-underlined, that if I have calls to llSetTimerEvent in code that causes llSetTimerEvent to be executed at an interval less than the _value_ of the sec argument to llSetTimerEvent. In my specific case my interpretation would mean I would have to be careful to not to call llSetTimerEvent sooner than 0.02 seconds after the initial call. Since I do not call llSetTimerEvent in the code path from listen except from within timer which should be ok because the timer fired. Finally, the values to llSetTimerEvent work fine with called from within touch_start. Does my interpretation seem reasonable or should I take 'sec' to me 1.0 seconds? Also, I did test llSetTimerEvent from within the listen with an argument of 1.0 and that did not change behavior. G Link to comment Share on other sites More sharing options...
GManB Posted May 30, 2020 Author Share Posted May 30, 2020 Continuing testing I tried using 1.0 as an argument to llSetTimerEvent in _both_ the llSetTimerEvent calls (one in touch_start and one in listen) and now both touching and menu driven start/stop work fine. G Link to comment Share on other sites More sharing options...
Rolig Loon Posted May 30, 2020 Share Posted May 30, 2020 I'm glad that worked. LSL isn't always as predictable as we might hope. I suspect resident gremlins. Kidding aside, though, debugging even something as simple as this can be confusing because there may be more than one thing creating problems. If you're lucky enough to clear up one issue, there may be another lurking below the surface. Until you do enough testing to be sure, you can't tell whether you've really found the root of the problem. It often helps to add debug messages at key spots, just to be sure that you know what values are being tossed around. Link to comment Share on other sites More sharing options...
GManB Posted May 30, 2020 Author Share Posted May 30, 2020 Plenty of debug print stmts that I removed from pasted code Yeah. Every execution environment has it's seemingly goofy idiosyncrasies. I think I am over the hump wrt the overall execution model. I am certain bits of goofiness remain. Just finished watching the launch... wheeee.. what fun!! G Link to comment Share on other sites More sharing options...
GManB Posted May 30, 2020 Author Share Posted May 30, 2020 Rolig, BTW, referencing a couple other threads, I am now happy with having the frame both rez and re-position any time after rez, the swing at the proper relative position and rotation. And with the swing motion always being correct relative to the frame. Things seemed to make a lot more sense once I got the frame and swing local axes correct for SL when exporting from Maya and using llRezAtRoot (instead of llRezObject). And I am almost certain that, for now, I will be going with a fully manual process to align the swing and frame (via llDialog menu from frame). Just, it seems to me, too many weird corner cases to cover to try to do that automatically... Maybe once I am more proficient. Thanks for your help! G Link to comment Share on other sites More sharing options...
Wulfie Reanimator Posted May 30, 2020 Share Posted May 30, 2020 (edited) 7 hours ago, GManB said: "If you repeatedly call this function at some interval less than sec the timer event will never fire." I interpreted this statement to mean, given that 'sec' is bold and dotted-underlined, that if I have calls to llSetTimerEvent in code that causes llSetTimerEvent to be executed at an interval less than the _value_ of the sec argument to llSetTimerEvent. In my specific case my interpretation would mean I would have to be careful to not to call llSetTimerEvent sooner than 0.02 seconds after the initial call. Since I do not call llSetTimerEvent in the code path from listen except from within timer which should be ok because the timer fired. Finally, the values to llSetTimerEvent work fine with called from within touch_start. Does my interpretation seem reasonable or should I take 'sec' to me 1.0 seconds? You're correct. When you call llSetTimerEvent(1), the timer-event won't be triggered until one second has passed. If you call llSetTimerEvent(1) again after only 0.5 seconds, the timer-event is pushed back and won't be triggered until one second has passed since the new call. I consider this a useful feature, it would be way more inconvenient if you couldn't update and avoid the timer event being triggered after the first call. Edit: @Mollymews 1/45 = 0.0222... Edited May 31, 2020 by Wulfie Reanimator 2 Link to comment Share on other sites More sharing options...
GManB Posted May 31, 2020 Author Share Posted May 31, 2020 1 hour ago, Wulfie Reanimator said: You're correct. When you call llSetTimerEvent(1), the timer-event won't be triggered until one second has passed. If you call llSetTimerEvent(1) again after only 0.5 seconds, the timer-event is pushed back and won't be triggered until one second has passed since the new call. I consider this a useful feature, it would be way more inconvenient if you couldn't update and avoid the timer event being triggered after the first call. Ok, I see that. And I agree it's a useful feature. But, in the original situation when things were not working as I expected I was calling llSetTimerEvent(0.02). And, as far as I could determine, there should be no calls to llSetTimerEvent until it fired. So, potentially, two things could cause this. 1. As Rolig said, things just might get squirrelly with such a small value as an argument, or, 2. something happening in my code that I didn't understand was causing fast repeated calls to llSetTimerEvent(0.02). As much as I dislike just saying it it's probably 1 since *increasing* the interval fixed the issue... sighs... Maybe something to do with this 'frame time' of 22ms... but, that's another discussion G Link to comment Share on other sites More sharing options...
Mollymews Posted May 31, 2020 Share Posted May 31, 2020 (edited) 2 hours ago, GManB said: Maybe something to do with this 'frame time' of 22ms... but, that's another discussion each type of event fires once per frame. A frame is nominally 1/45 of a second (0.222). When the server lags then frame rate slows in another post I typoed 0.0222 instead of 0.222. Which might have led you to work wrongly we can check for the server frame rate with http://wiki.secondlife.com/wiki/LlGetRegionFPS and/or http://wiki.secondlife.com/wiki/LlGetRegionTimeDilation edit oops what Wulfie said. Is Sunday morning and I cant count anymore Edited May 31, 2020 by Mollymews 1 1 Link to comment Share on other sites More sharing options...
Lucia Nightfire Posted May 31, 2020 Share Posted May 31, 2020 1 hour ago, Mollymews said: A frame is nominally 1/45 of a second (0.222). When the server lags then frame rate slows in another post I typoed 0.0222 instead of 0.222. 0.0222 was a typo? 1 Link to comment Share on other sites More sharing options...
Mollymews Posted May 31, 2020 Share Posted May 31, 2020 2 minutes ago, Lucia Nightfire said: 0.0222 was a typo? everything is a typo at the moment 2 Link to comment Share on other sites More sharing options...
GManB Posted May 31, 2020 Author Share Posted May 31, 2020 6 minutes ago, Mollymews said: everything is a typo at the moment lol...but seriously... first, 1/45th of a sec is 0.0222 or 22.2ms ... so 0.0222 is not a typo. but, events fire only once a frame? Ugh... why? Then llSetTimerEvent(x) where x is less than 0.0222 will result in oddness... ..in my original code I set x to 0.02 which is slightly less than 0.0222 so oddness could occur... btw, my academic and professional background is in real-time OSs, VM, scheduling, and scheduling theory... working in this environment is new for me and I can see we do need to be very clever about things. G Link to comment Share on other sites More sharing options...
Mollymews Posted May 31, 2020 Share Posted May 31, 2020 yes GManB, the SL realtime engine comes with its own set of nuances. We have to get inventive sometimes like a way to ameliorate jitter is to run a timer and a sensorrepeat simultaneously. When the server is running normally then we get up to 2 timed events every frame when this gets really critical then we can add another script. Now up to 4 timed events every frame. And so on Link to comment Share on other sites More sharing options...
GManB Posted May 31, 2020 Author Share Posted May 31, 2020 11 minutes ago, Mollymews said: yes GManB, the SL realtime engine comes with its own set of nuances. We have to get inventive sometimes like a way to ameliorate jitter is to run a timer and a sensorrepeat simultaneously. When the server is running normally then we get up to 2 timed events every frame when this gets really critical then we can add another script. Now up to 4 timed events every frame. And so on I see. So we get one timed event *type* per frame. Sensor and timer are different types so we get two. What about asynchronous events like, touch_start? G Link to comment Share on other sites More sharing options...
Wulfie Reanimator Posted May 31, 2020 Share Posted May 31, 2020 6 minutes ago, GManB said: I see. So we get one timed event *type* per frame. Sensor and timer are different types so we get two. What about asynchronous events like, touch_start? G touch_start's parameter (the integer) enumerates all of the people who touched it during the same frame, 0 being the first index. Link to comment Share on other sites More sharing options...
Kyrah Abattoir Posted June 1, 2020 Share Posted June 1, 2020 (edited) Another important thing is that LSL scripts only have a single execution pointer, your timer() will only be able to fire after the current event is completed. In addition, events are not guaranteed to fire on the frame they are scheduled, I believe that is what the "missed event" region stat is. Edited June 1, 2020 by Kyrah Abattoir Link to comment Share on other sites More sharing options...
ItHadToComeToThis Posted June 7, 2020 Share Posted June 7, 2020 On 5/30/2020 at 7:51 PM, Rolig Loon said: I suspect that the problem is that you are firing the timer very fast and are resetting it way too often. I doubt that you can get a timer to trigger at all if you set it with llSetTimerEvent(0.02); There's even a note to that effect in the wiki: If you repeatedly call this function at some interval less than sec the timer event will never fire. As a minor point, you may find it helpful to add parentheses in if tests that include more than one condition. They aren't technically necessary and the compiler should parse things correctly, but if nothing else, extra parentheses make things more human-readable. So, for example.... if( (channel == privateChannel ) && ( lList2String(arguments,0) == "startSwing")) BTW, you have repeated the same fatal error in both if tests in the listen event. Get rid of the semicolon at the end of both. Your script will run as written,. but it will ignore the stuff after each test (or misinterpret it). 😎 You can. It’s negligible whether you notice the difference under 0.05 but they do fire down to 0.01 and possibly below and do run code Link to comment Share on other sites More sharing options...
GManB Posted June 8, 2020 Author Share Posted June 8, 2020 7 hours ago, ItHadToComeToThis said: You can. It’s negligible whether you notice the difference under 0.05 but they do fire down to 0.01 and possibly below and do run code Referencing the two diagrams attached. This is how I think llSTE behaves in reference to the line in the wiki that Rolig referenced, "f you repeatedly call this function at some interval less than sec the timer event will never fire." In diag A things work out as expected llSTE(x) is executed at time t0, the timer() event handler is executed at time t1. llSTE(y) is called at time t2 and time timer() event handler is called at time t3. All find and dandy. In diag B llSTE(x) is called again at time t0 but due to whatever concurrency issues llSTE(y) is called before t1. In this case the timing code is *reset* to t2+y and the timer() event handler is executed only once at t3. Note that the magnitude of x and y are irrelevant to the behavior in scenarios A and B. x could be 48 hours and y 50 hours or x could be 10m and y 20ms..same behavior... what we do not know is the lower bound on llSTE. ItHadToComeToThis says that giving 10ms as a argument to llSTE has observably correct behavior.. What is clear to me now is that there is only a single 'timer' and llSTE called before the expiration of the previous call actually resets that single 'timer'. Agree or disagree? G Link to comment Share on other sites More sharing options...
Lucia Nightfire Posted June 8, 2020 Share Posted June 8, 2020 (edited) Setting another timer value will reset the current timer. If a timer() event is already queued, it will remain queued. Setting a timer of 0.0 will cull a queued timer() event. Edited June 8, 2020 by Lucia Nightfire 1 Link to comment Share on other sites More sharing options...
GManB Posted June 8, 2020 Author Share Posted June 8, 2020 5 hours ago, Lucia Nightfire said: Setting another timer value will reset the current timer. If a timer() event is already queued, it will remain queued. Setting a timer of 0.0 will cull a queued timer() event. When does a timer() event get queued? At the expiration of the time given as an argument to llSTE? Link to comment Share on other sites More sharing options...
Lucia Nightfire Posted June 9, 2020 Share Posted June 9, 2020 10 hours ago, GManB said: When does a timer() event get queued? At the expiration of the time given as an argument to llSTE? In general, yes. The target global end time(set & checked in the background) is updated when calling llSetTimerEvent() and again when the a timer event is queued, not when the actual timer() is triggered. This means for example, if you set a 5.0 second timer, then either do work in a long loop or a sleep that consumes 9 seconds of script time, your next two timer events will be 1.0 seconds apart, given whatever event delay time follows. 1 Link to comment Share on other sites More sharing options...
GManB Posted June 9, 2020 Author Share Posted June 9, 2020 7 minutes ago, Lucia Nightfire said: In general, yes. The target global end time(set & checked in the background) is updated when calling llSetTimerEvent() and again when the a timer event is queued, not when the actual timer() is triggered. This means for example, if you set a 5.0 second timer, then either do work in a long loop or a sleep that consumes 9 seconds of script time, your next two timer events will be 1.0 seconds apart, given whatever event delay time follows. Thanks. This gives me a much more complete model of the behavior. G Link to comment Share on other sites More sharing options...
Recommended Posts
Please take a moment to consider if this thread is worth bumping.
Please sign in to comment
You will be able to leave a comment after signing in
Sign In Now