It is currently April 18th, 2024, 5:08 pm

Sometimes the text become 0

Discuss the use of Lua in Script measures.
User avatar
jsmorley
Developer
Posts: 22629
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: Sometimes the text become 0

Post by jsmorley »

Yincognito wrote: March 11th, 2020, 1:23 pm Many thanks for clearing this up, Brian. I did not look at the log with Debug mde checked, as I assumed the OP knew what he was doing more than me, since as I said, I'm not exactly an expert in Lua. I do know from my programming experience that a file needs to be closed after a read or write operation, but (incorrectly) assumed that the Lua integration in Rainmeter made such a process automatic, without needing user intervention.
No, each instance (measure) of the Lua script remains active while the skin is active. Without that, you couldn't have Lua keep track of anything between skin updates, and the Initialize() function would be useless. It would always "start over" each time the script was executed. So if you open a file in Lua, it remains open until you close it or refresh / unload the skin. It would be quite common to want that, so you could open a file for read, and then on each update, read the "next" line of the file until the end is reached.

So when a Lua measure is started on the load / refresh of the skin, any Initialize() function is executed, and then the script is just sitting idling, waiting for a call to any function. The most common call is to Update() which will automatically happen on every update of the measure in the skin, however Update() should not be construed as "executing the script", but just executing the Update() function. Update() is just a function like any other.

There is no call you can make, nor should there be, that says "Restart the entire script from scratch. Close all files, destroy all variables and tables, and start all over." That is only done on the refresh / unload of the skin, when the entire measure is destroyed by Rainmeter.

Nothing says you have to have an Update() function at all, you can use Inline Lua to execute and return a value or take some action on any FunctionName() call to the script. Very few Lua scripts that I write even have an Update() function anymore. It is so seldom that some automatic, regular, update of the script makes more sense than having some measure or meter that needs some work done just ask for it when it needs it.
User avatar
Yincognito
Rainmeter Sage
Posts: 7121
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: Sometimes the text become 0

Post by Yincognito »

jsmorley wrote: March 11th, 2020, 1:27 pm No, each instance (measure) of the Lua script remains active while the skin is active. Without that, you couldn't have Lua keep track of anything between skin updates, and the Initialize() function would be useless. It would always "start over" each time the script was executed. So if you open a file in Lua, it remains open until you close it or refresh / unload the skin. It would be quite common to want that, so you could open a file for read, and then on each update, read the "next" line of the file until the end is reached.

So when a Lua measure is started on the load / refresh of the skin, any Initialize() function is executed, and then the script is just sitting idling, waiting for a call to any function. The most common call is to Update() which will automatically happen on every update of the measure in the skin, however Update() should not be construed as "executing the script", but just executing the Update() function. Update() is just a function like any other.

There is no call you can make, nor should there be, that says "Restart the entire script from scratch. Close all files, destroy all variables and tables, and start all over." That is only done on the refresh / unload of the skin, when the entire measure is destroyed by Rainmeter.

Nothing says you have to have an Update() function at all, you can use Inline Lua to execute and return a value or take some action on any FunctionName() call to the script. Very few Lua scripts that I write even have an Update() function anymore. It is so seldom that some automatic, regular, update of the script makes more sense than having some measure or meter that needs some work done just ask for it when it needs it.
I understand. In some ways, as far as I can tell, it's similar to how one would approach writing a plugin for Rainmeter. Just read the other day some very interesting description you gave to someone interested in writing a plugin, and explaining him why some calls and processes should be done in certain parts of the plugin (e.g. the Initialize, or Update parts) and why some should be done in others.

All in all, it makes sense. No need to "repeat" the operation in Lua's Update() function - instead, do it a single time in another function and let Update() just return the result.
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: Sometimes the text become 0

Post by jsmorley »

Yincognito wrote: March 11th, 2020, 5:03 pm I understand. In some ways, as far as I can tell, it's similar to how one would approach writing a plugin for Rainmeter. Just read the other day some very interesting description you gave to someone interested in writing a plugin, and explaining him why some calls and processes should be done in certain parts of the plugin (e.g. the Initialize, or Update parts) and why some should be done in others.

All in all, it makes sense. No need to "repeat" the operation in Lua's Update() function - instead, do it a single time in another function and let Update() just return the result.
No need for Update() at all in many cases. Any FunctionName() can "return" a value, the difference is that Update() returns the value by setting the string / number value of the Lua measure itself. Other functions return the value to the calling entity, which might be Update() or might be an Inline Lua call in a measure or meter.
User avatar
Yincognito
Rainmeter Sage
Posts: 7121
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: Sometimes the text become 0

Post by Yincognito »

jsmorley wrote: March 11th, 2020, 5:16 pmAny FunctionName() can "return" a value, the difference is that Update() returns the value by setting the string / number value of the Lua measure itself.
So, if I understand this correctly, using Update() to return values from Lua makes those values "persistent", in that they will be available on a potential future use of the Lua measure itself.
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: Sometimes the text become 0

Post by jsmorley »

Yincognito wrote: March 11th, 2020, 5:52 pm So, if I understand this correctly, using Update() to return values from Lua makes those values "persistent", in that they will be available on a potential future use of the Lua measure itself.
Any variable you set globally in Lua is "persistent". It will remain so as long as the skin is loaded.

The way "return" works in Lua (and all programming languages really) is that you call a function with something like:

myValue = SomeFunction(SomeArgument)

When SomeFunction() is executed, it can be made to "return" a value to whatever called it, in this case populating the value of the variables myValue. The value of myValue will remain that until you either change it, or set it to nil, which in effect "erases" it.

In Rainmeter, what "calls" the function Update() is the measure in the skin itself. So what is set is the value of the measure when you use "return" in the function.

Think of it as MeasureValue = Update().

So there are three ways to access Lua from Rainmeter:

1) The update of the measure in the skin will execute Update() in the Lua script, and the measure value will be what is returned.

2) You can call any FunctionName(optionalArg1, optionalArg2...) with Inline Lua, and use the value returned by the function. The value of the Inline Lua [SectionVariable] will be set to what is "returned" by the function. https://docs.rainmeter.net/manual/lua-scripting/inline-lua/#CallingAFunction

3) You can retrieve and use any global variable in Lua (they are all global unless you specify "local" when you define/populate them) by using Inline Lua to retrieve the variable. No "return" at all is needed. The value of the Inline Lua [SectionVariable] will be set to what the value of the variable is. https://docs.rainmeter.net/manual/lua-scripting/inline-lua/#RetrievingAVariable

The advantage to this is that you can set any number of variable values in Update(), or any other function you like, and have access to all of them as separate values. Keep in mind that in Lua / Rainmeter, you can only "return" one value to any calling entity. In Lua itself you can return more than one, with something like myValue1, myValue2 = SomeFunction(SomeArgument), but that won't work between Lua and Rainmeter. No entity in Rainmeter, be it a measure, or a #Variable# or a [SectionVariable] can have more than one value associated with it.

In addition, nothing says you have to "return" or "retrieve" anything really. You can simply have the Update() function in Lua, or any FunctionName() you call, use !Bangs to !SetVariable or !SetOption something in the skin that you want to react to the work the Lua does.
User avatar
Yincognito
Rainmeter Sage
Posts: 7121
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: Sometimes the text become 0

Post by Yincognito »

Ok, so then what exactly is the "advantage" of using Update() to set a Lua measure's value? It isn't persistency, since you said all Lua's returns are persistent - then what is it? Or, using Update() is more or less "obsolete" and is used just for the convenience of having the value assigned to some measure?! Unless, of course, there is another convenient thing in using Update() to return stuff: not bothering to update the value "manually" and just let the "automatic" measure update rate do this job.

Sorry for insisting on this, but I'm like that: I have to understand what I'm talking about. If I don't, then the entire process is pointless, as nothing productive will come out of it.
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: Sometimes the text become 0

Post by jsmorley »

Yincognito wrote: March 11th, 2020, 6:46 pm Ok, so then what exactly is the "advantage" of using Update() to set a Lua measure's value? It isn't persistency, since you said all Lua's returns are persistent - then what is it? Or, using Update() is more or less "obsolete" and is used just for the convenience of having the value assigned to some measure?! Unless, of course, there is another convenient thing in using Update() to return stuff: not bothering to update the value "manually" and just let the "automatic" measure update rate do this job.

Sorry for insisting on this, but I'm like that: I have to understand what I'm talking about. If I don't, then the entire process is pointless, as nothing productive will come out of it.
In a sense, perhaps Update() is a bit of a prehensile tail, as it pre-dates the creation of Inline Lua. However, it does have a few advantages:

1) It is called automatically on each update of the measure, you don't have to call it manually in any way. You just control how often with UpdateDivider like any other measure.

2) You can define your own "options" on the Lua measure, and those can be treated as "arguments" you pass to the Update() measure. So you can use !SetOption to change your own custom option on the measure, then !UpdateMeasure it to return a value that is based on that "argument".

3) There are some economies of scale that Update() provides. If you for instance had one Lua measure, that returns one value, but you wanted to use that value lots of places, it will be marginally more efficient to have the script execute Update() just once, in the measure, and just use that value as MeasureName= in String meters, or [MeasureName] other places, rather than using Inline Lua repeatedly to actually do the "work" over and over again. This is not terribly likely, but possible.

What is more likely is that you will have some FunctionName(SomeArgument) that you call, and what it returns will be based on the "argument" you pass to it. That might be in tons of places, but most likely with differing arguments in each place. That is the strength and beauty of Inline Lua.
User avatar
Yincognito
Rainmeter Sage
Posts: 7121
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: Sometimes the text become 0

Post by Yincognito »

jsmorley wrote: March 11th, 2020, 6:51 pm In a sense, perhaps Update() is a bit of a prehensile tail, as it pre-dates the creation of Inline Lua. However, it does have a few advantages:

1) It is called automatically on each update of the measure, you don't have to call it manually in any way. You just control how often with UpdateDivider like any other measure.

2) You can define your own "options" on the Lua measure, and those can be treated as "arguments" you pass to the Update() measure. So you can use !SetOption to change your own custom option on the measure, then !UpdateMeasure it to return a value that is based on that "argument".

3) There are some economies of scale that Update() provides. If you for instance had one Lua measure, that returns one value, but you wanted to use that value lots of places, it will be marginally more efficient to have the script execute Update() just once, in the measure, and just use that value as MeasureName= in a String meter, or [MeasureName] other places, rather than using Inline Lua repeatedly to actually do the "work" over and over again. This is not terribly likely, but possible.
That entirely clarifies things - thanks. I was just a bit confused on Update()'s functional purpose, but now it all makes sense. :thumbup:
jsmorley wrote: March 11th, 2020, 6:51 pmWhat is more likely is that you will have some FunctionName(SomeArgument) that you call, and what it returns will be based on the "argument" you pass to it. That might be in tons of places, but most likely with differing arguments in each place. That is the strength and beauty of Inline Lua.
Indeed.
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: Sometimes the text become 0

Post by jsmorley »

The long and the short of it is that Lua itself is just a lot of fun to use. It is very, very simple, while being quite powerful and flexible. Once you wrap your head around the concepts of If/Then/Else and For/Next and Tables (arrays) and basic programming constructs like that, you will find that the syntax and use of Lua is really easy. It is a very "forgiving" language, that doesn't have anywhere near the strict "rules" that a language like C does. It's a good fit with Rainmeter...