I've got an external program that generates dynamic data and stores it in a text file. I want to display this data in a gauge so I wrote a lua script to read that file and provide various items of that data to some measures. Since a number of the measures update at the same time, I was trying to detect that in the lua script and only read from disk once to try to be more efficient. Here is what I've got so far:
function Initialize()
data = LoadData()
end
function Update()
print(os.clock() - lastLoad)
-- if we've done a load within the last 500ms, don't do another.
if (os.clock() - lastLoad) > 0.5 then
data = LoadData()
end
if SELF:GetName() == "Measure1" then
return data["online"]
elseif SELF:GetName() == "Measure2" then
return data["temps"]
end
end
function LoadData()
local data = {}
-- load the data
lastLoad = os.clock()
return data
end
It's not working though. LoadData gets called for each measure. The 'print' statement that I put in the Update function always prints approx. 4.988 or there-abouts. I'm guessing it is because each measure is processed by a separate thread, so they all see the same value for 'lastLoad'. Ideally I need a Mutex or a critical section, but I don't know if that is supported in the Rainmeter version of Lua.
Any ideas how I can accomplish this?
Edit: I tried setting the global update rate to 10 and the UpdateDivider to 500 and 501, respectively, for the two measures, but it is still doing the same thing.
After some experimentation and research, I have come to realize that when multiple measures use the same Lua script, each measure actually has its own separate instance of the lua script, including the value of all global variables. I had assumed that the variables would be shared. (If I am wrong about any of this, please correct me.)
So it seems that it won't be possible for the Lua computations done for one measure to be made available to other measures.
russdirks wrote:After some experimentation and research, I have come to realize that when multiple measures use the same Lua script, each measure actually has its own separate instance of the lua script, including the value of all global variables. I had assumed that the variables would be shared. (If I am wrong about any of this, please correct me.)
So it seems that it won't be possible for the Lua computations done for one measure to be made available to other measures.
You are correct. Each Script measure is a separate, unique, sandboxed instance of Lua.
Any "sharing" of information between them would have to be explicit "hand offs". That might be by having one Lua script write a file and the other read it, or having a Lua script use !bangs to set #Variables# or use !SetOption to set the value of Calc or String measures, that the other script could use. There is no direct way to share information between scripts. They are sandboxed.
Somewhat unrelated, but worth remembering, is that Lua scripts are not "re-entrant". The Initialize() function is executed and any values maintained when the script measure is created by Rainmeter, but is not updated or read again until the measure is destroyed and re-created (a skin refresh). All other functions in the script, Like Update() that is executed on each update of the measure in Rainmeter, or other functionName() that you might call with !CommandMeasure, are instantiated from scratch each time they are executed. Setting a variable to "1" in one update does not mean it will be "1" on the next update.
jsmorley wrote:Any "sharing" of information between them would have to be explicit "hand offs". That might be by having one Lua script write a file and the other read it, or having a Lua script use !bangs to set #Variables# or use !SetOption to set the value of Calc or String measures, that the other script could use.
Yes, I had thought of doing something like that. I was worried about 2 things though: (maybe you can answer)
The !SetVariable bang just writes to memory, right, not to my .ini file on disk? That would sort of defeat my goal of trying to save on disk I/O.
Race conditions ... Is Rainmeter single threaded or multi-threaded?
jsmorley wrote:Somewhat unrelated, but worth remembering, is that Lua scripts are not "re-entrant". ... Setting a variable to "1" in one update does not mean it will be "1" on the next update.
Are you sure? I'm seeing something different. With the following test script ...