Changes to the Script measure and the Lua interface
Posted: 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:
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:
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:
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:
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:
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":
Of course, the functions can return identical results. The following would set both str1 and str2 to "Finland":
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):
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
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
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
Code: Select all
stringMeter = SKIN:GetMeter("StringMeterName")
stringMeter:SetText("hello!") -- STRING specific function
stringMeter:SetX(25) -- common function to all meters
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#")
SKIN:GetVariable(), on the other hand, just gets a variable. The following would set str to "Finland":
Code: Select all
str = SKIN:GetVariable("Country")
Code: Select all
str1 = SKIN:ReplaceVariables("#Country#")
str2 = SKIN:GetVariable("Country")
Code: Select all
str1 = SKIN:ReplaceVariables("#NonexistentVariable#")
str2 = SKIN:GetVariable("NonexistentVariable")