It is currently March 29th, 2024, 2:59 pm

[BUG?] Substitute not yielding result on first update

Report bugs with the Rainmeter application and suggest features.
User avatar
Yincognito
Rainmeter Sage
Posts: 7031
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

[BUG?] Substitute not yielding result on first update

Post by Yincognito »

Test skin:

Code: Select all

[Variables]
Calc=1.6

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

---Measures---

[MeasureCalc]
Measure=Calc
Formula=#Calc#
;UpdateDivider=-1
RegExpSubstitute=1
Substitute="^.*$":"[MeasureCalc:0]"
DynamicVariables=1

---Meters---

[MeterCalc]
Meter=String
FontFace=Consolas
FontColor=255,255,255,255
SolidColor=47,47,47,255
Padding=5,5,5,5
FontSize=16
AntiAlias=1
Text="Calc = [MeasureCalc]"
DynamicVariables=1
Expected result: the meter and the log should present the measure's string value as "2" right after refresh, similar to how self referencing formulas in a Calc measure work

Actual result: it takes one update for the measure's string value to become "2", making it unusable for scenarios where an UpdateDivider=-1 is used; also, the measure's string value is initially "0", which is odd considering that DynamicVariables=1 is used everywhere

Question: is this a bug or some particularity of how Substitute works? If the former, a fix would be nice, if the latter, is it not possible for a measure to have its number value fractional and its string value the truncated or rounded version of that?
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth
User avatar
Brian
Developer
Posts: 2674
Joined: November 24th, 2011, 1:42 am
Location: Utah

Re: [BUG?] Substitute not yielding result on first update

Post by Brian »

No bug here. Your substitute will always be 1 update behind.

The reason is the order in which items are processed during the Update cycle. Variables are "read" before the measure/meter is updated.

So here is a rough breakdown of what is happening in this case:
  1. Rainmeter first creates the measures, then the meters. At this point, all measure values are 0.
  2. Update cycle #1 (Note, all measures are updated before meters)
    1. The measure MeasureCalc is read. After all the values are read and replaced, Substitute now looks like this: Substitute="^.*$":"0"
    2. The measure then updates, and the number value of MeasureCalc is now 1.6.
    3. After the measure is updated, Substitute now replaces everything with 0 (from step a).
  3. The rest of the measures update, then the meters update in a similar fashion.
  4. Everything is drawn to the screen
  5. Update cycle #2
    1. If DynamicVariables=1, the measure is read again. In this case, the measure reads all the values again and replaces the variables. Substitute now looks like this: Substitute="^.*$":"2"
    2. The measure now updates, and number value of MeasureCalc is still 1.6.
    3. After the measure updates, Substitute now replaces everything with 2 (from step a).
  6. The rest of the measures update, then the meters.
  7. Everything is drawn to the screeen.
  8. Repeat steps 5 through 7.

The important part is to remember that variables are replaced before any updating of measure/meter.

I hope that helps.

-Brian
User avatar
balala
Rainmeter Sage
Posts: 16110
Joined: October 11th, 2010, 6:27 pm
Location: Gheorgheni, Romania

Re: [BUG?] Substitute not yielding result on first update

Post by balala »

Yincognito wrote: November 13th, 2021, 5:54 pm Actual result: it takes one update for the measure's string value to become "2", making it unusable for scenarios where an UpdateDivider=-1 is used; also, the measure's string value is initially "0", which is odd considering that DynamicVariables=1 is used everywhere
Besides Brian's explanation, note that even if UpdateDivider=-1 is set, you can get the measure updating by an OnRefreshAction=[!UpdateMeasure "MeasureCalc"] option, added to the [Rainmeter] section. Yep, I understand this is not what you want, but might be a solution in some circumstances:

Code: Select all

[Variables]
Calc=1.6

[Rainmeter]
Update=1000
DynamicWindowSize=1
AccurateText=1
OnRefreshAction=[!UpdateMeasure "MeasureCalc"]

---Measures---

[MeasureCalc]
Measure=Calc
Formula=#Calc#
UpdateDivider=-1
RegExpSubstitute=1
Substitute="^.*$":"[MeasureCalc:0]"
DynamicVariables=1

---Meters---

[MeterCalc]
Meter=String
MeasureName=MeasureCalc
FontFace=Consolas
FontColor=255,255,255,255
SolidColor=47,47,47,255
Padding=5,5,5,5
FontSize=16
AntiAlias=1
Text=Calc = %1
DynamicVariables=1
User avatar
Yincognito
Rainmeter Sage
Posts: 7031
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: [BUG?] Substitute not yielding result on first update

Post by Yincognito »

Brian wrote: November 13th, 2021, 6:50 pm No bug here. Your substitute will always be 1 update behind.

The reason is the order in which items are processed during the Update cycle. Section variables are "read" before the measure/meter is updated.

So here is a rough breakdown of what is happening in this case:
  1. Rainmeter first creates the measures, then the meters. At this point, all measure values are 0.
  2. Update cycle #1 (Note, all measures are updated before meters)
    1. The measure MeasureCalc is read. After all the values are read and replaced, Substitute now looks like this: Substitute="^.*$":"0"
    2. The measure then Updates, and the number value of MeasureCalc is now 1.6.
    3. After the measure is updated, Substitute now replaces everything with 0.
  3. The rest of the measures update, then the meters update in a similar fashion.
  4. Everything is drawn to the screen
  5. Update cycle #2
    1. If DynamicVariables=1, the measure is read again. In this case, the measure reads all the values again and replaces the variables. Substitute now looks like this: Substitute="^.*$":"2"
    2. The measure now updates, and number value of MeasureCalc is still 1.6.
    3. After the measure updates, Substitute now replaces everything with 2.
  6. The rest of the measures update, then the meters.
  7. Everything is drawn to the screeen.
  8. Repeat steps 5 through 7.

The important part is to remember that variables are replaced before any updating of measure/meter.

I hope that helps.

-Brian
Thanks, Brian, now it makes sense from the POV of how Rainmeter works. Unfortunately it doesn't help me to round the value in the same measure, so I guess the only option is to truncate the value by removing stuff after the decimal point, a bit inconvenient for my case. Thanks anyway, at least now I know that the rest of my positive update divider measures using this method produced wrong results, i.e. values that were one update behind (this might explain some visual inconsistencies I had, so I suppose it's a good thing that I know I have to correct them). ;-)
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth
User avatar
death.crafter
Rainmeter Sage
Posts: 1399
Joined: April 24th, 2021, 8:13 pm

Re: [BUG?] Substitute not yielding result on first update

Post by death.crafter »

Yincognito wrote: November 13th, 2021, 7:24 pm Thanks, Brian, now it makes sense from the POV of how Rainmeter works. Unfortunately it doesn't help me to round the value in the same measure, so I guess the only option is to truncate the value by removing stuff after the decimal point, a bit inconvenient for my case. Thanks anyway, at least now I know that the rest of my positive update divider measures using this method produced wrong results, i.e. values that were one update behind (this might explain some visual inconsistencies I had, so I suppose it's a good thing that I know I have to correct them). ;-)
Hii Yinco... Been a long time. Hope your teeth are shining like diamonds :D

Anyway, why try to use substitute tho? You could just directly use Round in the formula, couldn't you?
from the Realm of Death
User avatar
Brian
Developer
Posts: 2674
Joined: November 24th, 2011, 1:42 am
Location: Utah

Re: [BUG?] Substitute not yielding result on first update

Post by Brian »

One solution could be to use another Calc measure specifically for "string" values.

Code: Select all

[MeasureCalc_Number]
Measure=Calc
Formula=#Calc#
DynamicVariables=1

[MeasureCalc_String]
Measure=Calc
Formula=[MeasureCalc_Number:0]
DynamicVariables=1

[MeasureCalc_String2]
Measure=Calc
Formula=Round(MeasureCalc_Number)
Note, the string measure needs to be placed after the number measure. String1 uses section variables, thus needing DV=1. String2 doesn't need DV=1. Neither need Substitute.

-Brian

Edit - death.crafter beat me half way.
User avatar
Yincognito
Rainmeter Sage
Posts: 7031
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: [BUG?] Substitute not yielding result on first update

Post by Yincognito »

balala wrote: November 13th, 2021, 7:19 pm Besides Brian's explanation, note that even if UpdateDivider=-1 is set, you can get the measure updating by an OnRefreshAction=[!UpdateMeasure "MeasureCalc"] option, added to the [Rainmeter] section. Yep, I understand this is not what you want, but might be a solution in some circumstances:

Code: Select all

[Variables]
Calc=1.6

[Rainmeter]
Update=1000
DynamicWindowSize=1
AccurateText=1
OnRefreshAction=[!UpdateMeasure "MeasureCalc"]

---Measures---

[MeasureCalc]
Measure=Calc
Formula=#Calc#
UpdateDivider=-1
RegExpSubstitute=1
Substitute="^.*$":"[MeasureCalc:0]"
DynamicVariables=1

---Meters---

[MeterCalc]
Meter=String
MeasureName=MeasureCalc
FontFace=Consolas
FontColor=255,255,255,255
SolidColor=47,47,47,255
Padding=5,5,5,5
FontSize=16
AntiAlias=1
Text=Calc = %1
DynamicVariables=1
Normally a good idea (both the OnRefreshAction and using the string value of the measure through MeasureName) indeed, but since OnRefreshAction also acts after the first skin update (i.e. "at the very end of the first update cycle" as per the manual), this produces pretty much the same result... :confused:
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth
User avatar
balala
Rainmeter Sage
Posts: 16110
Joined: October 11th, 2010, 6:27 pm
Location: Gheorgheni, Romania

Re: [BUG?] Substitute not yielding result on first update

Post by balala »

Yincognito wrote: November 13th, 2021, 7:34 pm Normally a good idea (both the OnRefreshAction and using the string value of the measure through MeasureName) indeed, but since OnRefreshAction also acts after the first skin update (i.e. "at the very end of the first update cycle" as per the manual), this produces pretty much the same result... :confused:
Yeah, was just an idea when I read your post.
User avatar
Yincognito
Rainmeter Sage
Posts: 7031
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: [BUG?] Substitute not yielding result on first update

Post by Yincognito »

death.crafter wrote: November 13th, 2021, 7:30 pmHii Yinco... Been a long time. Hope your teeth are shining like diamonds :D
Well, they're shining alright, but the bad tooth is still there, LOL - been postponing the removal as I had other things to solve first.
death.crafter wrote: November 13th, 2021, 7:30 pmAnyway, why try to use substitute tho? You could just directly use Round in the formula, couldn't you?
Brian wrote: November 13th, 2021, 7:31 pm One solution could be to use another Calc measure specifically for "string" values. [...] Note, the string measure needs to be placed after the number measure. String1 uses section variables, thus needing DV=1. String2 doesn't need DV=1. Neither need Substitute.
Yep, I know I could do it the ways you described. :D The reason I wouldn't prefer to do it those ways is that I want to have BOTH the fractional value (so I can easily verify the computation result in the log) AND the rounded value (so I can display it nicely in the meter) ... in the same measure. Something like a FreeDiskSpace, a Time or a UsageMonitor measure, only with (fractional vs integer) numbers involved.

My scenario is one where what comes after the decimal point is critical to make sure I do the calculation right (it involves the declination of the Sun, the Greenwich hour angle and the equation of time, not to mention computing perihelion and december solstice day of year, LOL), but at the same time I only use or display integer values (basically, angles between 0 and 359) visually. I already have a couple of measures computing stuff and I want to minimize their number as much as possible to keep things relatively simple, hence my desire to have it in a single measure. Last, but not the least, at first view it seemed like something that could actually be done using such a regex substitute, until Brian's explanation that is.

Bottom line, I guess it's just about trying to keep things compact. :confused:
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth
User avatar
Brian
Developer
Posts: 2674
Joined: November 24th, 2011, 1:42 am
Location: Utah

Re: [BUG?] Substitute not yielding result on first update

Post by Brian »

Another alternative is to just use the section variable in the meter altogether.

Code: Select all

[Variables]
Calc=1.6

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

---Measures---

[MeasureCalc]
Measure=Calc
Formula=#Calc#

---Meters---

[MeterCalc]
Meter=String
FontFace=Consolas
FontColor=255,255,255,255
SolidColor=47,47,47,255
Padding=5,5,5,5
FontSize=16
AntiAlias=1
Text="Number = [MeasureCalc:]#CRLF#Rounded = [MeasureCalc:0]"
DynamicVariables=1
-Brian