It is currently June 27th, 2019, 11:06 am

Read variable from variables.inc file in lua script

Discuss the use of Lua in Script measures.
User avatar
lawty
Posts: 20
Joined: April 7th, 2014, 1:55 pm

Read variable from variables.inc file in lua script

lawty » April 15th, 2014, 1:50 pm

Hi
I cant seem to find an answer to how I would go about reading a variable from an .inc file. My skins are writing values to a file and I would like to be able to read a variable from the file in the lua script and then write back. I can find plenty of examples of writing to the inc file but not reading from it via lua.
I can also find examles of reading variables from the skin - but this is not what I need - I need to get the value from the file.

The SKIN:GetVariable does not seem to have an option for the config file like writekeyvalue etc...

Can anyone help?
Many thanks

anna
User avatar
jsmorley
Developer
Posts: 19273
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: Read variable from variables.inc file in lua script

jsmorley » April 15th, 2014, 1:59 pm

There is no native Lua way to read a .inc (which is really a .ini file format). It is just a text file that you would have to open, read in lines and parse them to separate the keys from the values.

There are a couple of Lua snippets created by smurfier that can pretty robustly read and write .ini formatted files that you might want to look at:

Read .ini file

Write .ini file

To be honest, I would not re-invent the wheel on "writing", but would just send a SKIN:Bang('!WriteKeyValue', ...) to the skin to take care of writing any changes to variable values in the .inc file. Reading you would indeed need to do in Lua, as there is no "file" version of GetVariable(). Also, I'm sure you are aware, but no changes made to a .inc @Include file will ever be seen by the skin itself unless you !Refresh it. That needs to be factored into design decisions.

Note: If you are reading or writing "unicode" characters in the .inc file, you should take a look at the "Using Unicode with Lua scripting" section of Unicode in Rainmeter.
User avatar
jsmorley
Developer
Posts: 19273
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: Read variable from variables.inc file in lua script

jsmorley » April 15th, 2014, 3:45 pm

On further reflection, I am not sure that what you are looking to do is the best approach. I understand the intent of having a skin and a Lua script used by the skin "share" a .inc @Include file, but there are some issues that should be considered, and perhaps an approach that is more reliable, and certainly far, far easier in the long haul.

Overview

Having a Lua script read and write an external text file that is strictly for its own use is fine and dandy. Having the script try to "share" a .inc @Include file with the skin, which has very specific behaviors and conditions, is very risky at best, and probably not the way to go. To be perfectly honest, given the integration via GetVariable() and SKIN:Bang() between the Lua and the skin, trying to read and write the .inc from the Lua is just a huge amount of effort and risk for very little benefit.

The problems

First, any change to a .inc @Include file will not be seen by the skin unless and until you !Refresh the skin or reload it. @Include is not "dynamic", but is only read once when the skin code is read by Rainmeter. You can certainly execute a !Refresh after every change you make to the .inc file either in the skin or the Lua, but that seems to me to be pretty brute-force and trying to use a .inc file in that dynamic a way is really not what it was intended for.

Second, any character you write using Lua that is not in the standard 128 ASCII code table is going to cause major problems. If it is greater than 128, but in the first 255 characters defined as ANSI, then it will work fine, but only on a system that is running the same locale (language) in Windows that you are. If not, or if it is a character outside of the 255 and only defined by Unicode, then things are just going to blow up.

The real rub with this is that there is NO easy way to correct for the issue. The problem is that Lua ONLY reads and writes Unicode using the UTF-8 Unicode encoding standard, and Rainmeter skins will NOT read or write .inc files encoded in UTF-8. They must be ANSI or UTF-16. The second you write a Unicode character to a .inc file with Lua, that file is destroyed from the standpoint of Rainmeter.

http://docs.rainmeter.net/tips/unicode-in-rainmeter

Recommended solution

I would handle ALL variable management from the skin, not the Lua. That is not to say that the Lua should not get a variable value and change it in code, but it should never read or write directly to / from the .inc file.

So the approach is:

In the skin, if you change a variable defined and read from the @Include file, just use both [!SetVariable ...] and [!WriteKeyValue ...] in the same action. That way the .inc file is kept current and permanent (for when you refresh or reload the skin), while at the same time the current variable value is "known" by the skin without having to refresh.

In the Lua, simply use GetVariable to read the value of a variable. If you change it, do the same thing we do in the skin. Use both SKIN:Bang('!SetVariable', ...) and SKIN:Bang('!WriteKeyValue', ...) to make the skin write to the .inc file while keepng the value of the variable current for everyone. Again, no refresh needed.

That way the "skin" is always in charge of managing both variables and the .inc file. It can be encoded as UTF-16 if you want to use Unicode anywhere, and the Lua plays what I propose is the correct role in this scenario. It never reads or writes to the .inc file directly, but uses bangs to the skin to manage things. Then there is never any reason that GetVariable() isn't the best solution for having the Lua know the current and "shared" value.
User avatar
lawty
Posts: 20
Joined: April 7th, 2014, 1:55 pm

Re: Read variable from variables.inc file in lua script

lawty » April 17th, 2014, 8:11 am

Hiya
Many thanks for the heads up. I ended up going down the lua path because I needed to be able to check the length of a variables value and as I understand it (which may be wrong) - there is no way to do this in the skin. So after reading some posts, I was looking to write to the inc file based on the length. I can then use this in the skin and show the correct information.
I seem to have it working - as you say its not ideal and it would be great if the skins could have the ability to do this.

Many thanks for all your help on this

anna