It is currently June 26th, 2019, 4:50 pm

Changes to the Script measure and the Lua interface

Discuss the use of Lua in Script measures.
poiru
Developer
Posts: 2877
Joined: April 17th, 2009, 12:18 pm

Changes to the Script measure and the Lua interface

poiru » July 10th, 2011, 4:29 pm

Rainmeter 2.1 r863 brings a slew of new features and changes to Script measure and Lua scripting. Since the changelog is rather concise about changes in general, I figured I'd explain the major changes in more detail.

1. Changes to how the measure value is returned

Prior to r863, a basic Lua script looked like this:

Code: Select all

function Initialize()
	-- do something here
end

function Update()
	-- do something here
end

function GetStringValue()
	return "Hello world!"
end

function GetValue()
	return 42
end
Initialize() is called when the measure is created, Update() is called on each update cycle, GetStringValue() is called to return the textual value of the measure (e.g. for STRING meters), and GetValue() is called to return the numerical value of the measure (e.g. for Calc measures).

As it turns out, GetValue() has never worked. We decided it would be best to get rid of both GetStringValue() and GetValue(). For new scripts aimed at the latest beta, use the following template:

Code: Select all

function Initialize()
	-- do something here
end

function Update()
	-- do something here

	return "Hello world!"
end
Basically, you should now return the value of the measure on Update() directly (for backwards compatibility, GetStringValue() is called if Update() does not return any value).

Here are some examples of returning values in Update():

return "Hello world!
-> textual value of measure: "Hello world!", numerical value: 0

return "42"
-> textual value of measure: "42", numerical value: 42

return 42
-> textual value of measure: "42", numerical value: 42


2. Ability execute Lua code through bangs

The latest beta adds the !CommandMeasure bang, which can be used to call Lua functions and/or execute Lua code through bangs. Here are a couple of examples:

LeftMouseUpAction=!Execute [!CommandMeasure "ScriptMeasure" "someVar = 5"]
-> set variable someVar to 5 (in the context of the ScriptFile specified by ScriptMeasure)

LeftMouseUpAction=!Execute [!CommandMeasure "ScriptMeasure" "someString = 'Hello world!'"]
-> set variable someString to "Hello world!". Note the use of single quotes to indicate a string.

LeftMouseUpAction=!Execute [!CommandMeasure "ScriptMeasure" "SomeFunction()"]
-> call function SomeFunction

You are not limited to the simple operations above, but can execute any valid Lua code in the context of ScriptMeasureName. So, for example, you could do:

LeftMouseUpAction=!Execute [!CommandMeasure "ScriptMeasure" "if var == 1 then func() end"]
-> if variable var is 1, call function func

LeftMouseUpAction=!Execute [!CommandMeasure "ScriptMeasure" "var = 5; str = 'Hello world!'; func();"]
-> set variable var to 5, set variable str to "Hello world!", and call function func. Note the use of semicolons to separate lines.


3. Deprecation of tolua.cast

Until now, when you wanted to access the STRING meter specific SetText() function in Lua, you can do use some ugly code:

Code: Select all

	stringMeter = tolua.cast(SKIN:GetMeter("StringMeterName"), "CMeterString")
	stringMeter:SetText("hello!")      -- STRING specific function
	stringMeter:SetX(25)               -- common function to all meters
The SKIN:GetMeter() function has been improved in the latest beta and now automatically detects the type of meter (currently, extra functions are only available to STRING meters). This allows you to simplify the code above to:

Code: Select all

	stringMeter = SKIN:GetMeter("StringMeterName")
	stringMeter:SetText("hello!")      -- STRING specific function
	stringMeter:SetX(25)               -- common function to all meters
Note tolua.cast will continue to work for backwards compatibility.


4. New function: GetVariable()

We already have ReplaceVariables(), which is used to replace variables in a Lua string. For example:

Code: Select all

str = SKIN:ReplaceVariables("I live in #Country# and my screen width is #SCREENAREAWIDTH#")
would set str to "I live in Finland and my screen width is 1920" (assuming that the skin .INI file contains Country=Finland under [Variables] and that my screen resolution is 1920x1080).

SKIN:GetVariable(), on the other hand, just gets a variable. The following would set str to "Finland":

Code: Select all

str = SKIN:GetVariable("Country")
Of course, the functions can return identical results. The following would set both str1 and str2 to "Finland":

Code: Select all

str1 = SKIN:ReplaceVariables("#Country#")
str2 = SKIN:GetVariable("Country")
However, if the variable does not exist, the return value differs. In the following case, str1 will be "#NonexistentVariable#" while str2 is empty (or nil in Lua terms):

Code: Select all

str1 = SKIN:ReplaceVariables("#NonexistentVariable#")
str2 = SKIN:GetVariable("NonexistentVariable")