It is currently March 28th, 2024, 10:56 pm

Weird ActionTimer behavior.

Get help with creating, editing & fixing problems with skins
User avatar
kyriakos876
Posts: 919
Joined: January 30th, 2017, 2:01 am
Location: Greece

Weird ActionTimer behavior.

Post by kyriakos876 »

Hello, I'm working on a skin and came up with a piece of code that works in a strange, to me, way.

Here' s the code that's acting weird:

Code: Select all

[Rainmeter]
Update=1000
OnUpdateAction=[!CommandMeasure MeasureAngle2 "Stop 1"][!CommandMeasure MeasureAngle2 "Execute 1"]

[Variables]
C=0

[MeasureAngle]
Group=Anim
Measure=Plugin
Plugin=ActionTimer
ActionList1=Repeat Action1, 27, 36 | Action2
Action1=[!SetVariable C "(Clamp(#C#+10,0,360))"][!UpdateMeasureGroup Anim][!UpdateMeterGroup Anim][!Redraw]
Action2=[!SetVariable C "0"][!UpdateMeasureGroup Anim][!UpdateMeterGroup Anim][!Redraw]
DynamicVariables=1
So, here I have this Measure to pretty much work all the time. How am I doing that? Well if you notice the OnUpdateAction and the Update and calculate the time it takes for the ActionList1 to be completed which would be 27*36=972 milliseconds, given the fact that it is repeated every 1000 milliseconds it sould run smoothly with a 28milliseconds gap to even add more time between repeats (currently 27 milliseconds for every repeat.) The thing is if I change the 27 to 28 it starts to act weird (in the second repetition it takes some time to zero the variable C as I see in the log which is normal as it loses the update cycle 28*36=1008>1000) but it should follow the command [!CommandMeasure MeasureAngle2 "Stop 1"] and stop it then start again with the variable C set to 0 (according to this (Clamp(#C#+10,0,360)) it should be starting from 0 anyway and climb to 360). Well, it doesn't do that... Now if I change 27 to 36 It stops working completely after 1 repetition and the variable stays 360 forever as I see in the log. What's going on here?
User avatar
balala
Rainmeter Sage
Posts: 16110
Joined: October 11th, 2010, 6:27 pm
Location: Gheorgheni, Romania

Re: Weird ActionTimer behavior.

Post by balala »

I'd try to completely remove the Action2 option of the [MeasureAngle] measure (along with removing it from the ActionList1 option) and would add all those bangs to the OnUpdateAction option of the [Rainmeter] section:

Code: Select all

[Rainmeter]
Update=1000
OnUpdateAction=[!SetVariable C "0"][!CommandMeasure MeasureAngle "Stop 1"][!CommandMeasure MeasureAngle "Execute 1"][!UpdateMeasureGroup Anim][!UpdateMeterGroup Anim][!Redraw]

[Variables]
C=0

[MeasureAngle]
Group=Anim
Measure=Plugin
Plugin=ActionTimer
ActionList1=Repeat Action1, 28, 36
Action1=[!SetVariable C "(Clamp((#C#+10),0,360))"][!UpdateMeasureGroup Anim][!UpdateMeterGroup Anim][!Redraw]
DynamicVariables=1
(To be honest here, your initial code as you had it written, didn't even work for me).
After this change, it works even if you're increasing more the Wait value in the ActionList1 option, but it's true that in this case, the variable doesn't reach 360.
User avatar
kyriakos876
Posts: 919
Joined: January 30th, 2017, 2:01 am
Location: Greece

Re: Weird ActionTimer behavior.

Post by kyriakos876 »

balala wrote:I'd try to completely remove the Action2 option of the [MeasureAngle] measure (along with removing it from the ActionList1 option) and would add all those bangs to the OnUpdateAction option of the [Rainmeter] section...
Sometime later I change the [!SetVariable C "0"] from the Action2 to the OnUpdateAction and it fixed my problem but I still dont understand why doesn't it stop as commanded on the [!CommandMeasure MeasureAngle "Stop 1"] part and restart from 0 as commanded from [!SetVariable C "(Clamp((#C#+10),0,360))"]?
balala wrote: (To be honest here, your initial code as you had it written, didn't even work for me).
After this change, it works even if you're increasing more the Wait value in the ActionList1 option, but it's true that in this case, the variable doesn't reach 360.
I probably missed something as I didn't copy the whole code but only this part. Thanks for the solution but my question still remains...
User avatar
eclectic-tech
Rainmeter Sage
Posts: 5384
Joined: April 12th, 2012, 9:40 pm
Location: Cedar Point, Ohio, USA

Re: Weird ActionTimer behavior.

Post by eclectic-tech »

kyriakos876 wrote:Sometime later I change the [!SetVariable C "0"] from the Action2 to the OnUpdateAction and it fixed my problem but I still dont understand why doesn't it stop as commanded on the [!CommandMeasure MeasureAngle "Stop 1"] part and restart from 0 as commanded from [!SetVariable C "(Clamp((#C#+10),0,360))"]?



I probably missed something as I didn't copy the whole code but only this part. Thanks for the solution but my question still remains...
When you send the command to stop action 1, the second action list is not executed, so your variable maintains wherever value it was at when the action timer stopped; it is not being reset to zero. Then on the next update, the action timer runs, but because you clamp the value to a maximum of 360, you don't see any change; it remains 360.

The issue you are seeing is due to the fact that the OnUpdateAction is performed at the end of the update cycle (Manual Note: The action(s) defined will take place at the very end of the update cycle. Changes made will generally not be visible until the next update, unless bangs are used to update desired measures and meters and redraw the skin.)

So I would suggest the code below. You can modify the skin update rate, and also the action timer repeat "wait" time, to get an almost continuous action (however, this is not a recommended use of the action timer).

I added the reset of the variable and an update of the measure in between the stop and start commands to the action timer in the OnUpdateAction, so the change is available the next time the action timer is activated.

Code: Select all

[Rainmeter]
Update=1000
OnUpdateAction=[!CommandMeasure MeasureAngle "Stop 1"][!SetVariable C "0"][!UpdateMeasureGroup Anim][!CommandMeasure MeasureAngle "Execute 1"]

[Variables]
C=0

[MeasureAngle]
Group=Anim
Measure=Plugin
Plugin=ActionTimer
ActionList1=Repeat Action1, 10, 36
; | Action2
Action1=[!SetVariable C "(Clamp(#C#+10,0,360))"][!UpdateMeasureGroup Anim][!UpdateMeterGroup Anim][!Redraw]
; Action2=[!SetVariable C "0"][!UpdateMeasureGroup Anim][!UpdateMeterGroup Anim][!Redraw]
DynamicVariables=1

[Meter]
Meter=String
User avatar
kyriakos876
Posts: 919
Joined: January 30th, 2017, 2:01 am
Location: Greece

Re: Weird ActionTimer behavior.

Post by kyriakos876 »

eclectic-tech wrote:When you send the command to stop action 1, the second action list is not executed, so your variable maintains wherever value it was at when the action timer stopped; it is not being reset to zero. Then on the next update, the action timer runs, but because you clamp the value to a maximum of 360, you don't see any change; it remains 360.
I don't know why but I thought that clamp if restarted will start from the minimum value (in this case 0). So I guess I was wrong... Thanks for clarifying that!
User avatar
eclectic-tech
Rainmeter Sage
Posts: 5384
Joined: April 12th, 2012, 9:40 pm
Location: Cedar Point, Ohio, USA

Re: Weird ActionTimer behavior.

Post by eclectic-tech »

kyriakos876 wrote:I don't know why but I thought that clamp if restarted will start from the minimum value (in this case 0). So I guess I was wrong... Thanks for clarifying that!
Glad to help! :great:
User avatar
jsmorley
Developer
Posts: 22628
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: Weird ActionTimer behavior.

Post by jsmorley »

kyriakos876 wrote:I don't know why but I thought that clamp if restarted will start from the minimum value (in this case 0). So I guess I was wrong... Thanks for clarifying that!
Clamp() does not set any values, it restrict values from being set below and above defined points.

Code: Select all

[Rainmeter]
Update=1000
DynamicWindowSize=1
AccurateText=1

[Counter]
Measure=Loop
StartValue=1
EndValue=10
Increment=1

[MeasureClamp]
Measure=Calc
Formula=Clamp(Counter,3,7)

[MeterValue]
Meter=String
MeasureName=MeasureClamp
FontSize=11
FontWeight=400
FontColor=255,255,255,255
SolidColor=47,47,47,255
Padding=5,5,5,5
AntiAlias=1
As long as the number is equal to or between the values in low,high in the Clamp(), the function doesn't care otherwise what the number is.
User avatar
kyriakos876
Posts: 919
Joined: January 30th, 2017, 2:01 am
Location: Greece

Re: Weird ActionTimer behavior.

Post by kyriakos876 »

jsmorley wrote:Clamp() does not set any values, it restrict values from being set below and above defined points.

.
.
.

As long as the number is equal to or between the values in low,high in the Clamp(), the function doesn't care otherwise what the number is.
So if I exceed by 1 the max limit it will start from the min and climb back to the max?
User avatar
jsmorley
Developer
Posts: 22628
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: Weird ActionTimer behavior.

Post by jsmorley »

kyriakos876 wrote:So if I exceed by 1 the max limit it will start from the min and climb back to the max?
Nope, it will be set and stay at the max.

While it is below the min it will be and stay the min. While it is above the max it will be and stay the max

Clamp() in and of itself is in no way any kind of "loop".

That why when you want grow and shrink something like a FontSize for instance, you need two ActionList(s) in the ActionTimer Measure:

One that adds a value to the #Variable# controlling the FontSize, using Clamp() (or you could just as easily use Max()) to restrict the value to the highest FontSize you want to allow. Whatever formula you have adding to the value will keep "trying" to add to it after it hits max, but just won't be able to. Clamp() will steadfastly refuse to the let the number go above the max.

One that subtracts a value from the #Variable# controlling the FontSize, using Clamp() (or you could just as easily use Min()) to restrict the value to the lowest FontSize you want to allow. Whatever formula you have subtracting from the value will keep "trying" to subtract from it after it hits min, but just won't be able to. Clamp() will steadfastly refuse to let the number go below the min.

Clamp() in and of itself in no way ever "starts over". That's not what it is about.

We use Clamp() in ActionTimer because it can be hard, or even impossible, to get "exactly" the right number of times to "repeat" adding or subtracting some "increment" to/from the value, creating some "total amount of change", that ends up not slightly over-runing or under-running the starting and ending values you want. This is particularly true in things that must be integers, like FontSize or X, or W. The idea is to "divide" the amount of change by the number of steps you want to do it in, and that is likely to end up being a few over or a few under the target.

We also use Clamp() in ActionTimer because you are likely to want to "stop" one action before it it through, and "start" the opposite one. If we have an example of changing the alpha value of a meter from 0-255, and we do it in 255 steps, if we "stop" it while it is on its way up, but it is currently only at 200 for instance, the other opposing action will try to move down, by subtracting in 255 steps. Without Clamp() that would end up with a value -55, which is completely invalid for an Alpha value, and would be disastrously wrong in an X or W. When Clamp(#Var#-1,0,255) sees the number at 0, the next 54 times you try to subtract from it, it will just stubbornly keep the number at 0.

Clamp() just says "Ask away, I'm not allowing the number to be below this, or above that."

How it works under the covers is:

Clamp(number,minvalue,maxvalue)

If number is less than minvaluue, then number is forced to be equal to minvalue.
If number is greater than maxvalue, then number is forced to be equal to maxvalue.
User avatar
kyriakos876
Posts: 919
Joined: January 30th, 2017, 2:01 am
Location: Greece

Re: Weird ActionTimer behavior.

Post by kyriakos876 »

jsmorley wrote:Nope, it will be set and stay at the max.

.
.
.

If number is less than minvaluue, then number is forced to be equal to minvalue.
If number is greater than maxvalue, then number is forced to be equal to maxvalue.
I get it now. Thanks!