It is currently April 25th, 2024, 8:53 pm

Help with freezing marquees.

Get help with creating, editing & fixing problems with skins
User avatar
jsmorley
Developer
Posts: 22629
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: Help with freezing marquees.

Post by jsmorley »

Yes, ActionTimer is not intended, nor designed, to support "never ending" animations.

Constantly "killing" threads in Windows is a recipe for hanging an app sooner or later. It's why you can hang WebParser by beating it up to stop what it is doing and start over repeatedly in short order. It's a related issue.

It's just not that easy to have an ActionTimer measure recursively run itself at the end. The trouble is, you can't be sure it really is "done" before you hit it with a "Stop" command. That is really the point of the "Stop" command.

The only way to stop a thread that is running from outside the thread is to shoot it in the head. Windows is pretty ok with this once in a while, it does all the "cleanup" it needs to do and all is well. If you do this repeatedly in a short period of time, it can lead to problems.
User avatar
Yincognito
Rainmeter Sage
Posts: 7164
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: Help with freezing marquees.

Post by Yincognito »

chamlex wrote: February 20th, 2020, 11:26 pm So apparently I'm not alone with this issue. This post https://forum.rainmeter.net/viewtopic.php?f=5&t=34703 outlines another person with the issue using Action Timers and getting the same errors. I might look into using marquee lua to see if i can get a scrolling marquee for when the text is too long.
Yes, jsmorley is correct on this one. One other solution for you (and for me, in a similar situation) is to use the "classic" way (i.e. without ActionTimer or Lua) to roll text in a marquee, when it comes to "endless" motion on some computers. I can confirm that the method works with no freeze whatsoever. I currently have 2 skins rolling text for more than a day (yeah, forgot to turn off my laptop the other day) with 0 issues and minimal impact on the system.

The only inconvenient while doing things from Rainmeter itself and without involving ActionTimer would be the fact that if you link an OS tooltip to that skin it will flicker due to the very short update rates. But even for that there is a solution, i.e. to make a custom tooltip skin, see here (for a basic sample) and here (for an improved one, with a preview).
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth
User avatar
jsmorley
Developer
Posts: 22629
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: Help with freezing marquees.

Post by jsmorley »

I'm not sure I want to take the time to dig into it, but there might be a way to make an "endless animation" more reliable and stable with ActionTimer. I'm thinking that if you can somehow signal the skin that an ActionTimer "action" is "finished", then you might be able to restart the action without using a "Stop" command. Perhaps setting a value on a String or Calc measure, and on that measure test to see if some "maximum" value has been reached. If so, then maybe wait a bit with a !Delay bang, and then issue a new "Execute" command to the ActionTimer measure.

The trouble, and the risk, with this is that ActionTimer actions don't in and of themselves "do" anything. They send bangs to the skin, and while the action can be "done" sending bangs, it's more difficult to be sure what the last bang is doing is actually "done". This would take some care.

The long and the short of it is that you don't ever want to have an ActionTimer measure recursively call itself. ActionTimer is designed to be triggered by some external event, like a mouse over, or perhaps a test on an IfCondition / IfMatch.

It's a bit hard to test, since the issue with "hanging" the ActionTimer thread is not something that happens at any particular point or time. It seems to depend a bit on how powerful your PC is, as it seems to be better at handling this if it has a lot of "speed" to throw at the problem.
chamlex
Posts: 15
Joined: February 16th, 2020, 12:13 am

Re: Help with freezing marquees.

Post by chamlex »


Yes, jsmorley is correct on this one. One other solution for you (and for me, in a similar situation) is to use the "classic" way (i.e. without ActionTimer or Lua) to roll text in a marquee, when it comes to "endless" motion on some computers. I can confirm that the method works with no freeze whatsoever. I currently have 2 skins rolling text for more than a day (yeah, forgot to turn off my laptop the other day) with 0 issues and minimal impact on the system.
Thanks. Is there an easy to follow example of the ”classic” way?
User avatar
Yincognito
Rainmeter Sage
Posts: 7164
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: Help with freezing marquees.

Post by Yincognito »

jsmorley wrote: February 21st, 2020, 2:22 pm I'm not sure I want to take the time to dig into it, but there might be a way to make an "endless animation" more reliable and stable with ActionTimer. I'm thinking that if you can somehow signal the skin that an ActionTimer "action" is "finished", then you might be able to restart the action without using a "Stop" command. Perhaps setting a value on a String or Calc measure, and on that measure test to see if some "maximum" value has been reached. If so, then maybe wait a bit with a !Delay bang, and then issue a new "Execute" command to the ActionTimer measure.

The trouble, and the risk, with this is that ActionTimer actions don't in and of themselves "do" anything. They send bangs to the skin, and while the action can be "done" sending bangs, it's more difficult to be sure what the last bang is doing is actually "done". This would take some care.

The long and the short of it is that you don't ever want to have an ActionTimer measure recursively call itself. ActionTimer is designed to be triggered by some external event, like a mouse over, or perhaps a test on an IfCondition / IfMatch.

It's a bit hard to test, since the issue with "hanging" the ActionTimer thread is not something that happens at any particular point or time. It seems to depend a bit on how powerful your PC is, as it seems to be better at handling this if it has a lot of "speed" to throw at the problem.
Yeah, I thought about this too after our conversation the other days. I even tried - albeit not exactly as you suggest - to trigger an execute from another Calc measure and see if it changes things. It didn't (in fact, for some reason, it didn't work at all, if I remember corectly), but as I said, I didn't use your idea and went instead to "update" the Calc measure still from the last action of the ActionTimer measure (meaning it was still some sort of recursion involved, at least indirectly).

I also thought about "estimating" when the AT measure is finished, pretty much the same as you suggest, but gave up implementing the idea thinking that no matter how much I tried, there would still be some delay involved, that would break the "fluidity" of the movement. Granted, it would probably be too small to be noticed with the naked eye, but it would exist, and although it wouldn't (as far as I can see) accumulate over time, it might pose some problems in various scenarios like a busy CPU, different system specs needing different "delays" and so on. Anyway, to give your suggestion the benefit of the doubt, I think this might be a possible (though subject to circumstances) workaround.

That being said, I'm not entirely sure what caused those freezes. I've checked with a message queue "spying" program the status of the message queue in the case of the "marquee" skin I was testing, and obviously, there were indications that it was "crowded" in there, but also ran into an issue when several weeks ago I was programming in MS Excel's VBA and a recursive function I wrote was taking "too many steps" according to the error message, and had to turn it into a non-recursive one (using loops, but unfortunately, we don't have that luxury in Rainmeter). So, in other words, the cause could be Windows message crowding, too many recursive steps by the AT measure, or both. I can't say for sure which one is it. My experience in similar situations seems to indicate that recursion is the culprit, but then at slower speeds (i.e. bigger "wait" times) it didn't hang, although I didn't have the patience to wait hours to see if it does eventually, so probably it's a combination of both.

Yes, I guess it's established by now that AT must be used precisely according to the manual specifications, as it can run into trouble if "abused". My only issue with this is that it's a pitty that this happens even in the most "reasonable" (in theory) circumstances, like movements of very small "chunks" of data and in a relatively short period of time. I mean, a GIF can "run" for days without any issues - though, granted, if you have a lot of GIFs displayed at the same time, the CPU will bleed to death trying to keep up.
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth
User avatar
balala
Rainmeter Sage
Posts: 16172
Joined: October 11th, 2010, 6:27 pm
Location: Gheorgheni, Romania

Re: Help with freezing marquees.

Post by balala »

chamlex wrote: February 21st, 2020, 4:17 pm Is there an easy to follow example of the ”classic” way?
How about this?

Code: Select all

[MeasureActionTimer]
Measure=Plugin
Plugin=ActionTimer
ActionList1=Repeat Move1,#animationSpeed#,[MeasureMarquee1Offset:] | Wait #marqueeEndWait# | Reset1
Reset1=[!SetVariable marquee1 0][!CommandMeasure MeasureActionTimer "Stop 1"][!UpdateMeasure MeasureActionTimer][!UpdateMeter MeterText1][!UpdateMeter "Uptime"][!Redraw][!Delay "1000"][!CommandMeasure MeasureActionTimer "Execute 1"]
Move1=[!SetVariable marquee1 "(#marquee1# - 1)"][!UpdateMeasure MeasureActionTimer][!UpdateMeter MeterText1][!Redraw]
ActionList2=Repeat Move2,#animationSpeed#,[MeasureMarquee2Offset:] | Wait #marqueeEndWait# | Reset2
Reset2=[!SetVariable marquee2 0][!CommandMeasure MeasureActionTimer "Stop 2"][!UpdateMeasure MeasureActionTimer][!UpdateMeter MeterText2][!UpdateMeter "Uptime"][!Redraw][!Delay "1000"][!CommandMeasure MeasureActionTimer "Execute 2"]
Move2=[!SetVariable marquee2 "(#marquee2# - 1)"][!UpdateMeasure MeasureActionTimer][!UpdateMeter MeterText2][!Redraw]
DoOver2=[!CommandMeasure MeasureActionTimer "Execute 2"]
ActionList3=Repeat Move3,#animationSpeed#,[MeasureMarquee3Offset:] | Wait #marqueeEndWait# | Reset3
Reset3=[!SetVariable marquee3 0][!CommandMeasure MeasureActionTimer "Stop 3"][!UpdateMeasure MeasureActionTimer][!UpdateMeter MeterText3][!UpdateMeter "Uptime"][!Redraw][!Delay "1000"][!CommandMeasure MeasureActionTimer "Execute 3"]
Move3=[!SetVariable marquee3 "(#marquee3# - 1)"][!UpdateMeasure MeasureActionTimer][!UpdateMeter MeterText3][!Redraw]
DoOver3=[!CommandMeasure MeasureActionTimer "Execute 3"]
DynamicVariables=1
Just replace the [MeasureActionTimer] measure with the above one. Everything else unchanged.
User avatar
Yincognito
Rainmeter Sage
Posts: 7164
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: Help with freezing marquees.

Post by Yincognito »

chamlex wrote: February 21st, 2020, 4:17 pm Thanks. Is there an easy to follow example of the ”classic” way?
Well, I don't know your definition of "easy" in the first place, but... here it is (I guarantee you this won't freeze, unless you want it to, LOL - you'll understand what I mean after playing with it ;-) ):

Code: Select all

[Variables]
ContainerWidth=136
TextWidth=0
ScrollingStep=10
SlidingStep=1
CurrentStep=(#SlidingStep#)
SlidingUpdate=24
Text="Wed, 00 May 2020   ●   ‒000 °C   ●   Showers Early / Clearing Late"

[Rainmeter]
AccurateText=1
Update=#SlidingUpdate#

---Measures---

[MeasureCounter]
Group=CounterGroup
Disabled=1
Measure=Calc
Formula=((MeasureCounter<0)?(#ContainerWidth#+#TextWidth#):((MeasureCounter>(#ContainerWidth#+#TextWidth#))?(0):(MeasureCounter+#CurrentStep#)))
OnUpdateAction=[!SetOption MeterText X (#ContainerWidth#-[MeasureCounter])][!UpdateMeter *][!Redraw]
IfCondition=(MeasureCounter<0)
IfTrueAction=[!UpdateMeter *][!UpdateMeasure "MeasureCounter"]
IfCondition2=(MeasureCounter>(#ContainerWidth#+#TextWidth#))
IfTrueAction2=[!DisableMeasure "MeasureCounter"][!UpdateMeasure "MeasureCounter"][!EnableMeasure "MeasureCounter"][!UpdateMeasure "MeasureCounter"]
IfConditionMode=1
DynamicVariables=1

---Meters---

[MeterBackground]
Meter=Shape
Shape=Rectangle 0,0,168,13 | StrokeWidth 0.5 | Stroke Color 255,64,32 | Fill Color 32,32,32,128
UpdateDivider=-1

[MeterTitle]
Meter=String
ClipString=2
FontFace=Tahoma
FontSize=7
AntiAlias=1
FontWeight=700
FontColor=255,255,255,255
StringEffect=Shadow
FontEffectColor=0,0,0,255
X=2
Y=0
Text=WEA
UpdateDivider=-1
MouseScrollUpAction=[!DisableMeasure "MeasureCounter"][!UpdateMeasure "MeasureCounter"][!EnableMeasure "MeasureCounter"][!UpdateMeasure "MeasureCounter"]
MouseScrollDownAction=[!DisableMeasure "MeasureCounter"][!UpdateMeasure "MeasureCounter"][!EnableMeasure "MeasureCounter"][!UpdateMeasure "MeasureCounter"]
LeftMouseUpAction=[!SetOption MeterText X (0)][!UpdateMeter *][!EnableMeasure "MeasureCounter"][!UpdateMeasure "MeasureCounter"][!Redraw]
DynamicVariables=1

[MeterContainer]
Meter=Shape
X=31
Y=0
Shape=Rectangle 0,0,136,13 | Fill Color 0,0,0,255 | StrokeWidth 0
UpdateDivider=-1
MouseOverAction=[!PauseMeasure "MeasureCounter"]
MouseLeaveAction=[!UnpauseMeasure "MeasureCounter"]
MouseScrollUpAction=[!SetVariable CurrentStep (-#ScrollingStep#)][!UnpauseMeasure "MeasureCounter"][!UpdateMeasureGroup "CounterGroup"][!PauseMeasure "MeasureCounter"][!SetVariable CurrentStep (#SlidingStep#)]
MouseScrollDownAction=[!SetVariable CurrentStep (#ScrollingStep#)][!UnpauseMeasure "MeasureCounter"][!UpdateMeasureGroup "CounterGroup"][!PauseMeasure "MeasureCounter"][!SetVariable CurrentStep (#SlidingStep#)]
MiddleMouseUpAction=[!UnpauseMeasure "MeasureCounter"][!UpdateMeasure "MeasureCounter"][!DisableMeasure "MeasureCounter"][!UpdateMeasure "MeasureCounter"][!EnableMeasure "MeasureCounter"][!UpdateMeasure "MeasureCounter"][!PauseMeasure "MeasureCounter"]
DynamicVariables=1

[MeterText]
Meter=String
Container=MeterContainer
FontFace=Tahoma
FontSize=7
FontWeight=400
FontColor=160,255,160,255
FontEffectColor=0,0,0,255
StringEffect=Shadow
Antialias=1
ClipString=0
InlineSetting=Color | 128,255,255,255
InlinePattern="^([^●]*)   ●"
InlineSetting2=Color | 255,255,255,255
InlinePattern2="(   ●   )"
InlineSetting3=Color | 255,224,128,255
InlinePattern3="●   ([^●]*)$"
X=(#ContainerWidth#/2)
Y=0
Text=#Text#
UpdateDivider=-1
OnUpdateAction=[!SetVariable TextWidth [MeterText:W]]
DynamicVariables=1
It's not complicated, despite the long formulas involved. It has options like sliding endlessly, scrolling over to "drag" the sliding text forward or backward, middle mouse click to "reset" movement from the beginning, good place to add other "items" to jump to and slide, etc. You'll discover them in no time, if you have the guts to "explore" this... :sly:

EDIT: Forgot the most important thing: the animation is disabled when the skin is loaded or refreshed. To enable it, just click the bold text on the left side of the skin (i.e. "WEA"). Also...

IMPORTANT NOTE: If you ever decide to adapt this in a (different) skin, be careful to also change (i.e. increase) the update rate of the other measures in the skin, cause you wouldn't want to, say, poll a site every 24 milliseconds and get banned... For example, if you have a WebParser measure somewhere in the skin, you should set its UpdateRate=(#ActualUpdateRateYouWantInMilliseconds#/#SlidingUpdate#), meaning that if you want it to update every 10 minutes, it would be like UpdateRate=(10*60*1000/#SlidingUpdate#) (i.e. 10 min x 60 seconds x 1000 milliseconds, everything divided by 24 milliseconds).
balala wrote: February 21st, 2020, 5:08 pm
How about this?
....
Well, you beat me this time to it. :thumbup: There is only one small detail though: when I mentioned the "classic way", I meant no ActionTimer, no Lua, nothing but pure Rainmeter "proper" stuff involved. Your example still involves ActionTimer, which is proven by now to cause issues with recursive + fast + endless animation on some computers (mine and the OP's included). But hey, if you have a way to avoid those freezes / hangs, I'm all ears, really. :great: In my case, the "classic" way of doing things (like above) never failed me all these years. ;-)
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth
User avatar
balala
Rainmeter Sage
Posts: 16172
Joined: October 11th, 2010, 6:27 pm
Location: Gheorgheni, Romania

Re: Help with freezing marquees.

Post by balala »

Yincognito wrote: February 21st, 2020, 5:43 pm Well, you beat me this time to it.
Yep, this happens many times with each of us, I think. Not a problem.
Yincognito wrote: February 21st, 2020, 5:43 pm Your example still involves ActionTimer, which is proven by now to cause issues with recursive + fast + endless animation on some computers (mine and the OP's included). But hey, if you have a way to avoid those freezes / hangs, I'm all ears, really. :great: In my case, the "classic" way of doing things (like above) never failed me all these years. ;-)
Well, actually I think it is done. Freezes avoided. At least I left the skin running for more then an hour and still no freezing. Still runs well. Let's see if it does run for you or any other without problems. I am curious if it does.
The ActionTimer solution has a great advantage in front of your solution: it uses the default Update=1000, which is much more advantageous in front of the low update you need to use in your code (you've used Update=24).
chamlex
Posts: 15
Joined: February 16th, 2020, 12:13 am

Re: Help with freezing marquees.

Post by chamlex »

Wow thanks for the quick replies and comments. I am impressed by the helpfulness of this community. Balala quick question for you though your code has a request to update an Uptime meter that I did not have in my original code. What type of meter is this? Sorry if its a dumb question I'm still learning and getting use to the coding language.

Code: Select all

[MeasureActionTimer]
Measure=Plugin
Plugin=ActionTimer
ActionList1=Repeat Move1,#animationSpeed#,[MeasureMarquee1Offset:] | Wait #marqueeEndWait# | Reset1
Reset1=[!SetVariable marquee1 0][!CommandMeasure MeasureActionTimer "Stop 1"][!UpdateMeasure MeasureActionTimer][!UpdateMeter MeterText1][!UpdateMeter "Uptime"][!Redraw][!Delay "1000"][!CommandMeasure MeasureActionTimer "Execute 1"]
Move1=[!SetVariable marquee1 "(#marquee1# - 1)"][!UpdateMeasure MeasureActionTimer][!UpdateMeter MeterText1][!Redraw]
ActionList2=Repeat Move2,#animationSpeed#,[MeasureMarquee2Offset:] | Wait #marqueeEndWait# | Reset2
Reset2=[!SetVariable marquee2 0][!CommandMeasure MeasureActionTimer "Stop 2"][!UpdateMeasure MeasureActionTimer][!UpdateMeter MeterText2][!UpdateMeter "Uptime"][!Redraw][!Delay "1000"][!CommandMeasure MeasureActionTimer "Execute 2"]
Move2=[!SetVariable marquee2 "(#marquee2# - 1)"][!UpdateMeasure MeasureActionTimer][!UpdateMeter MeterText2][!Redraw]
DoOver2=[!CommandMeasure MeasureActionTimer "Execute 2"]
ActionList3=Repeat Move3,#animationSpeed#,[MeasureMarquee3Offset:] | Wait #marqueeEndWait# | Reset3
Reset3=[!SetVariable marquee3 0][!CommandMeasure MeasureActionTimer "Stop 3"][!UpdateMeasure MeasureActionTimer][!UpdateMeter MeterText3][!UpdateMeter "Uptime"][!Redraw][!Delay "1000"][!CommandMeasure MeasureActionTimer "Execute 3"]
Move3=[!SetVariable marquee3 "(#marquee3# - 1)"][!UpdateMeasure MeasureActionTimer][!UpdateMeter MeterText3][!Redraw]
DoOver3=[!CommandMeasure MeasureActionTimer "Execute 3"]
DynamicVariables=1
User avatar
Yincognito
Rainmeter Sage
Posts: 7164
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: Help with freezing marquees.

Post by Yincognito »

balala wrote: February 21st, 2020, 6:28 pmYep, this happens many times with each of us, I think. Not a problem.
Yes, of course it's not (a problem). I was just joking. ;-)
balala wrote: February 21st, 2020, 6:28 pmThe ActionTimer solution has a great advantage in front of your solution: it uses the default Update=1000, which is much more advantageous in front of the low update you need to use in your code (you've used Update=24).
I know. However, as I said, the only disadvantage in case of my previous solution is if you use tooltips and they flicker - and for that there is already a solution: custom tooltip skins, where you don't depend on the update rate of the parent anymore and you can format everything taking full advantage of Rainmeter's capabilities (compared to the OS tooltips' ones). The fast update rate is not a disadvantage anywhere else, as other individual measures / meters can be set to update as slow as you want anyway.

That being said, something is still updating once every 32 milliseconds anyway. It may not be Rainmeter itself or the rest of the measures, but it's the ActionTimer thread. From this point of view, it's just another way of riding the same horse (there's a similar saying in our language "Same Mary, but wearing a different hat").
balala wrote: February 21st, 2020, 6:28 pmWell, actually I think it is done. Freezes avoided. At least I left the skin running for more then an hour and still no freezing. Still runs well. Let's see if it does run for you or any other without problems. I am curious if it does.
Oh, I wished you'd be right on this one, but I literally spent hours trying different ways to stop the freezes with jsmorley in another thread, to no avail. I've sort of had enough of it. And yes, it was pretty much the same in that thread as well: he managed to make the skin work for hours without freezing, while the exact same code freezed after a couple of minutes on my side. Hopefully, the OP will take your solution (as it's easier to understand) and be happy about it, but for me, the conclusion is pretty much final, after so many attempts: I hate to say it, as I love almost everything about Rainmeter, but ActionTimer is simply unreliable for endless + fast + recursive animation. It wasn't designed for it, and apparently both Brian's and JSMorley's warnings in both the manual and the posts announcing the plugin were spot on on this. Other than that, for what it was designed for (i.e. short animations, non-recursive), ActionTimer works perfectly.
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth