It is currently October 22nd, 2024, 6:51 pm

Lua for conditional operators with strings as result.

Discuss the use of Lua in Script measures.
Crest
Posts: 158
Joined: August 16th, 2013, 12:47 pm

Re: Lua for conditional operators with strings as result.

Post by Crest »

RicardoTM wrote: October 18th, 2024, 11:58 pm The only problem I've noticed so far is on the Shape's Fill option. On first load and on refresh, it will log Invalid shape modifier: 0 (ConditionalExample\Example.ini - [Button])

Captura de pantalla 2024-10-18 185722.png

This happens with any of the conditional functions.
Yeah this is something I've been experiencing for the past year. It seems for certain inline Lua replacements (Fill Color style and Container option) the Lua doesn't get parsed at all on initial skin load. This doesn't actually affect the final render as it subsequently parses but does lead to the error message you saw (and for the container it complaining about invalid container).

Another workaround is placing the Fill styling in the Shape option last and exclusively as a conditional that itself prefixes a pipe character to the replacement string. In your example skin you're already placing it last but instead of using Extend Fill you can place the inline Lua replacement conditional directly in the Shape.

Eg: instead of your current Shape code of:

Code: Select all

Shape=Ellipse 0.0,0.0,[[#CurrentSection]:W] | Extend Stroke | Extend StrokeColor | Extend Fill
...
Fill=[&C:con(([#ButtonState]=0),'Fill Color [#ButtonDisabledColor]','Fill Color [#ButtonEnabledColor]')]
You can do the following instead as an alternative workaround for this issue (notice no pipe is used after `StrokeColor`, instead it's added via the replacement string):

Code: Select all

Shape=Ellipse 0.0,0.0,[[#CurrentSection]:W] | Extend Stroke | Extend StrokeColor [&C:con(([#ButtonState]=0),'| Fill Color [#ButtonDisabledColor]','| Fill Color [#ButtonEnabledColor]')]
RicardoTM
Posts: 404
Joined: December 28th, 2022, 9:30 pm
Location: México

Re: Lua for conditional operators with strings as result.

Post by RicardoTM »

Crest wrote: October 19th, 2024, 2:24 am
Hey Crest, excellent suggestion, thank you. Since you mentioned containers I also tested on them. I don't know if you have found a fix for that. The only thing I have came up with to fix it is using a measure with substitute:

Code: Select all

[mContainer]
Measure=String
String=[&C:con(([#ButtonState]=0),'','SomeMeter')]
Substitute="0":""
DynamicVariables=1

[Meter]
Meter=String
Container=[mContainer]
...
This fixes it perfectly fine but it defeats the purpose of not having to use measures though. And of course a bang to update it is necessary. However it's still better than having to set options :lol:
Crest
Posts: 158
Joined: August 16th, 2013, 12:47 pm

Re: Lua for conditional operators with strings as result.

Post by Crest »

Yeah didn't find anything suitable for containers. It'd be nice to just have a per meter/meter style native option to suppress log messages for such scenarios (as IIRC the web parser measure has) given the errors are ignorable and not user/author caused (but to those unaware may look as such).

Perhaps something worth posting in the bugs sub-forum in case it'd be feasible to fix.

Edit: I'll also add for more context to readers that this doesn't only occur for values defined as variables. Regardless of what is done or returned in the called function it doesn't trigger when inline initially. Hence even if you used `return ""` (empty string) which if added manually via the INI the container would ordinarily treat as 'no container' the logged error demonstrates the function isn't being correctly called. It's possible on first load Rainmeter may be reading the entire script call as a literal string.
RicardoTM
Posts: 404
Joined: December 28th, 2022, 9:30 pm
Location: México

Re: Lua for conditional operators with strings as result.

Post by RicardoTM »

Crest wrote: October 19th, 2024, 7:22 am
Yup, wish there was an option to disable them as well. Although many users may not care, I can't stand those errors lol.

To answer your edit, I don't think it is rainmeter reading the entire call as a literal string, if that was the case the error would't say "0", but the function as a string, something like: Invalid Container: [&C:con(([#ButtonState]=0),'','SomeMeter')] (...)

The error will "dissapear" if you create a dummy meter called [0], then it will see it as a valid container.

The problem I think relies on how lua evaluates functions on refresh, it's evaluating them and they're returning nill (0) on first load and refresh. I think an initialize function could fix it, but not sure how tho.
User avatar
Yincognito
Rainmeter Sage
Posts: 8534
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: Lua for conditional operators with strings as result. [Help]

Post by Yincognito »

Crest wrote: October 18th, 2024, 4:53 am SKIN:ParseFormula(SKIN:ReplaceVariables("("..cond..")"))
Not on my laptop to test, but I think that simply:
SKIN:ParseFormula(cond)
would work, assuming that cond is already a round bracket enclosed argument on the Rainmeter side, e.g. [&Script:Conditional(([#NumberA]<1?[&NumberB]:[&NumberC]),'True','False').

By the way, like SilverAzide alluded to, since conditionals in Rainmeter are strictly numerical and result in a number, one can skip enclosing the conditionals between apostrophes, thanks to this nice addition courtesy of Brian:
https://forum.rainmeter.net/viewtopic.php?t=40094#p204944
RicardoTM wrote: October 19th, 2024, 7:58 amThe problem I think relies on how lua evaluates functions on refresh, it's evaluating them and they're returning nill (0) on first load and refresh. I think an initialize function could fix it, but not sure how tho.
I believe Rainmeter needs to have proper and complete options even before the "first" update cycle or Initialize() function, i.e. when the skin is read / checked for things like no existing meter and such. I say complete because, given that inline Lua requires the nested syntax to resolve values "immediately" and those values are not yet available at skin read time, placing parts like the container's section name or the Fill Color without the preceding | and between other parts of an option would cause those option to be badly written.

This would explain why adding the | prefixed Fill Color part at the end of the option (where it can be discarded as the empty string, 0 or whatever) works, while it doesn't "in-between" other parts and without | as it would make that option something like Option=... | | ... where the | | part is obviously malformed. Not entirely sure why it works for other options though, maybe it has to do with the fact that those can take a "0" part in them without issues (as opposed to option where that part should refer to something else, e.g. a meter name, a multivalue fill color, etc).
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth
Crest
Posts: 158
Joined: August 16th, 2013, 12:47 pm

Re: Lua for conditional operators with strings as result. [Help]

Post by Crest »

Yincognito wrote: October 19th, 2024, 4:22 pmI think that simply SKIN:ParseFormula(cond) would work, assuming that cond is already a round bracket enclosed argument on the Rainmeter side
Yeah though I mentioned this only as an alternative if not enclosing the formula in the standard parentheses on the INI side, as that's what Ricardo's OP example was originally trying to achieve afaict (as in their second post in the thread they apparently wanted it to be displayed also as a text string sans the parentheses).
Yincognito wrote: October 19th, 2024, 4:22 pmBy the way, like SilverAzide alluded to, since conditionals in Rainmeter are strictly numerical and result in a number, one can skip enclosing the conditionals between apostrophes, thanks to this nice addition courtesy of Brian
That's a good method, too. IMO the ParseFormula approach is flexible as it accepts any such input including with spaces, while using strings for the argument is also useful if you want to expand the function to also handle purely string-based comparisons (rather than just numerical formulas), which is something I touched on and make use of.
Yincognito wrote: October 19th, 2024, 4:22 pmNot entirely sure why it works for other options though, maybe it has to do with the fact that those can take a "0" part in them without issues
Mmm, seems plausible. I'm glad it's brought some discussion at least. Still would be nice to suppress :D
User avatar
Yincognito
Rainmeter Sage
Posts: 8534
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: Lua for conditional operators with strings as result. [Help]

Post by Yincognito »

Crest wrote: October 19th, 2024, 9:03 pm Yeah though I mentioned this only as an alternative if not enclosing the formula in the standard parentheses on the INI side, as that's what Ricardo's OP example was originally trying to achieve afaict (as in their second post in the thread they apparently wanted it to be displayed also as a text string sans the parentheses).

That's a good method, too. IMO the ParseFormula approach is flexible as it accepts any such input including with spaces, while using strings for the argument is also useful if you want to expand the function to also handle purely string-based comparisons (rather than just numerical formulas), which is something I touched on and make use of.

Mmm, seems plausible. I'm glad it's brought some discussion at least. Still would be nice to suppress :D
Indeed. Who likes errors for a perfectly functional skin? :confused:
I might see if there's really no workaround for the container one later on, will let you know if by any chance I find a way.
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth
RicardoTM
Posts: 404
Joined: December 28th, 2022, 9:30 pm
Location: México

Re: Lua for conditional operators with strings as result. [Help]

Post by RicardoTM »

Yincognito wrote: October 19th, 2024, 4:22 pm
To me it is not a mystery why these options are invalid. Shape options require a clear and specific syntax, those being | Fill (..) | Stroke (..) | StrokeWidth (..) etc. where obviously | 0 would be invalid. And containers simply need a valid meter as option, that's why Container=0 is perfectly valid if there's a [0] meter. Other options like fontSize, FontColor, etc. can accept 0 as a value with no problem.

What's important is to understand how is inline lua evaluating functions on first load and refresh, that they're returning 0 no matter what, even when not using variables of any kind, eg. [&C:con((1=1),'','')] should set Container option to Container= even at the start, yet it is evaluating Container=0 anyway.

I mentioned the initialize function but of course I haven't really used it so I really ignore how it works in reality. All I know is what the docs say (which is pretty little information):
(...)
Actions that are needed to "set up" the script, such as declaring global variables, should be done in the Initialize function.
Which can be interpreted as the initial values of a function can be set here, so maybe, and only maybe, declaring con_str, true_str and false_str as global variables that equal valid options could help on the first load. Of course this is a tricky task since those valid options are different for the containers and the shape options. The only valid option for both could be an empty string "", if that can be set as the value on a global variable I don't know. IIRC nill = 0 anyway.

Of course I'm talking from my inexperienced understanding and I can be totally wrong.

If, as you mentioned, rainmeter analyses the skin before even evaluating the functions, then I doubt there's anything that can be done on our side.
User avatar
Yincognito
Rainmeter Sage
Posts: 8534
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: Lua for conditional operators with strings as result. [Help]

Post by Yincognito »

RicardoTM wrote: October 19th, 2024, 10:05 pm If, as you mentioned, rainmeter analyses the skin before even evaluating the functions, then I doubt there's anything that can be done on our side.
I'm not 100% sure just what it analyzes then and in any case the Initialize() function is one of the first things (if not the very first) ran by the skin, so you can indeed use it to set some default values for your (global) variables to prevent errors regarding to those. Thing is, inline functions hardly use such variables anyway, so apart from running some bangs to set things up in Initialize() - something I always try to avoid to make the script fully portable for different skins and syntaxes -, it won't have an impact on the inline function itself.

Regardless, I'll have to test these to be certain, since code differs from person to person and case to case. Personally, I've been able to avoid any errors on start in my scripts, so it might help posting the simplest complete versions of the Fill Color and Container cases in order to see what can be done about them.
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth
RicardoTM
Posts: 404
Joined: December 28th, 2022, 9:30 pm
Location: México

Re: Lua for conditional operators with strings as result. [Help]

Post by RicardoTM »

Yincognito wrote: October 20th, 2024, 8:48 am
So while testing your SectionIndex function, I encountered another error regarding invalid options.

If you have for example

Code: Select all

[Meter5]
Meter=String
Y=50

[Another5Meter]
Meter=String
Y=([&Meter[&S:SI()]:Y])
You get the error: Formula: "[" is unknown: ([&Meter0:Y])

if you take the () out eg. Y=[&Meter[&S:SI()]:Y] , then there's no problem. In this example this is possible, but when math is absolutely needed, then we have a stone in the shoe lol.

This, as the container one, can be "fixed" by having a dummy [Meter0], but yeah well, not everyone might like having dummy meters all around.