Nesting Variables

Changes made during the Rainmeter 4.1 beta cycle.
User avatar

Nesting Variables

August 23rd, 2017, 1:42 pm
jsmorley
Developer   [16120 posts]

There may be times when you want to embed or 'nest' variables within variables. This might include any combination of #Variables#, #Built-InVariables#, [SectionVariables] or $MouseVariables$.

So for instance, the goal might be to have things like:

Code: Select all

Text=#MyVar#MyOtherVar##
Text=#MyVar[MyMeasure]#
Text=[MyMeasure#MyVar#]
Text=[MyMeasure[MyOtherMeasure]]


This creates ambiguities that simply can't be reliably parsed and understood by Rainmeter, and can't work.

Rainmeter solves this by having an alternative form of these variables. These function exactly as their normal counterparts do, but can successfully be nested.

The alternative 'nesting' form of the variables

[#VarName]
Replaces: #VarName#
[&MeasureName]
Replaces: [MeasureName]
[$MouseVar]
Replaces: $MouseVar$

So our examples above would look like:

Code: Select all

Text=[#MyVar[#MyOtherVar]]
Text=[#MyVar[&MyMeasure]]
Text=[&MyMeasure[#MyVar]]
Text=[&MyMeasure[&MyOtherMeasure]]


Additional details and notes at: https://docs.rainmeter.net/manual-beta/variables/nesting-variables/

This is not intended to "deprecate" the existing forms of the variables. Although there is no reason why you might not, or can't, just use these all the time going forward, we are not interested in causing the work involved with trying to convert all older skins, nor any consternation here on the forums with a lot of "that's deprecated, don't use it" stuff with something of the scope of this.
User avatar

Re: Nesting Variables

September 5th, 2017, 8:24 am
Aethrios
   [47 posts]

I realize this change is a little old, but I don't find I need to update often.

This, however, for the love of all the good things in the world, is perhaps the single biggest change I've seen to Rainmeter since I started using it that I've been genuinely excited about!

A thousand thanks, dev team. You've made my night!
User avatar

Re: Nesting Variables

September 12th, 2017, 10:08 pm
eclectic-tech
Rainmeter Sage   [2173 posts]

When creating my Dice Roll skin, I encountered times when nested variables would not work for me.

I created a working ActionTimer measure using old syntax variables:

Code: Select all

[Variables]
NumOfTumbles=44
W=10
U=[!UpdateMeter *][!Redraw]

...

[mActionTimer]
Measure=Plugin
Plugin=ActionTimer
ActionList1=Repeat RollDice,#W#,#NumOfTumbles#
RollDice=[!UpdateMeasureGroup Dice]#U#
DynamicVariables=1
The measure functioned as expected.

But then I thought I should start to use the new syntax for variables that allow nesting:

Code: Select all

[mActionTimer]
Measure=Plugin
Plugin=ActionTimer
ActionList1=Repeat RollDice,[#W],[#NumOfTumbles]
RollDice=[!UpdateMeasureGroup Dice][#U]
DynamicVariables=1
But this code does not work.

The brackets in the U variable may be the issue with that value, but the W (wait) and repetition values are simple values that I thought should work. This appears to be an issue using them in the ActionTimer plugin; I haven't tried in any other plugins. However, I also had issues try to use the [#U] in the context menu to update meters after using !SetOption... even tried [[#U]] (ugly, but it failed too) :???:

Any ideas?
User avatar

Re: Nesting Variables

September 12th, 2017, 10:22 pm
jsmorley
Developer   [16120 posts]

We will look into that.
User avatar

Re: Nesting Variables

September 17th, 2017, 4:54 am
Brian
Developer   [1504 posts]

eclectic-tech wrote:Any ideas?

While similar in nature, there are actually 2 issues here. 1 has to do with ActionTimer and 1 has to do will ALL actions in Rainmeter. However, both are parsing issues.


[Technical Details]
Things to keep in mind:
  1. During the update cycle (either on the first update, or on all updates if DynamicVariables=1), regular non-action options are read from an internal cache (basically raw strings). Once the option is read, our parser first replaces any regular #variables# with its value. Then any [section] variables are replaced with the referenced measure value. At this point the option will be fully parsed with all the variable substitutions done and the measure/meter does whatever it needs to with it.
  2. Actions on the other hand, work differently. We want the action to have the most up-to-date value from measures available when the action is executed, not when it is read during the update cycle. To achieve this, we do not parse [section] variables in actions on read - we do it when the action is executed. We do still parse regular variables normally though.
  3. Because of #2 above, to parse the new-style nested variables correctly, we need to hold off on parsing [#variables] in only actions since there is a chance of nesting regular variables with section variables (ie. [#Var1[&Var2]]). This means that using this new style for regular variables makes these variables dynamic in actions just like regular section variables. This is one of the only differences between using the old style syntax vs. the new style syntax.


Back to the issues.

For ActionTimer:
The problem is the Repeat and Wait options were not designed to accept anything other than 'raw' numbers. Using the old-style syntax for regular variables works just fine here because this variable style is ALWAYS replaced when the option is read (see #1 above). However, technically the ActionList1/N options are actions...so due to #2 above, any [section] variables are not replaced until the action is executed. Since the parser expected a number when building the action list and not a reference to a measure (ie. [MeasureName]), the repeat option would fail. Same with the Wait option. Nested variables failed because of #3 above.

For ALL actions:
This problem is more about "when" we replace section variables when an action is executed and has lead to the discovery of a very long standing bug that hasn't reared its ugly head until now. We have often encouraged users to completely replace a long series of bangs with a regular variable to make things more readable. This has always worked great since regular variables are always replaced when the action is read (see #1 above). However, due to #2, using this same method with a section variable is broken - but no one in their right minds would do something like this.

Consider this:

Code: Select all

[MeasureString]
Measure=String
String=[!Log "Hello World"]

[SomeStringMeter]
Meter=String
...
LeftMouseUpAction=[MeasureString]
You would expect this code to log the message "Hello World" to the log when the string meter was clicked. But it does not..with no error or anything. The reason this fails is because for actions, we expect the bang(s) to be in a specific format. We basically search for a [!. Once found, we get the name of the bang, then replace any section variables after the bang name. Once done, then we execute the bang. So basically we are parsing the bang name first, then replacing and section variables in the parameters of the bang, then executing it. In the case above, when the meter is clicked, the text [MeasureString] is sent to the bang parser not the value that measure represents (see #2 and #3 above).
[/Technical Details]

Anyway.... both of these issues should be fixed for the next beta. Thank you for reporting these issues!

-Brian
User avatar

Re: Nesting Variables

54 minutes ago
eclectic-tech
Rainmeter Sage   [2173 posts]

Just thought I would let you know today's update took care of things and is working great... :thumbup:

No issues using nested variables with the ActionTimer or Context Menus!

Thanks! :rosegift:
User avatar

Re: Nesting Variables

10 minutes ago
Brian
Developer   [1504 posts]

Great!

-Brian

Return to “Rainmeter 4.1”



Who is online

Users browsing this forum: No registered users and 2 guests