It is currently October 6th, 2024, 12:26 pm

Make Lua unblocking?

Discuss the use of Lua in Script measures.
User avatar
Yincognito
Rainmeter Sage
Posts: 8358
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Make Lua unblocking?

Post by Yincognito »

Is there any way / technique to make long operations / functions in Lua (like, say, a recursive function to get all permutations of some table or string) not "hanging" aka making Rainmeter "busy" while they run through multiple skin / skin section updates? Some older posts on the forum state that coroutines cannot be used in Rainmeter's Lua, though this is not explictly stated in the manual (unless it's an external compiled library even though the Lua manual says it's a sub-library of the basic library, whatever that means). So, what other choices can be used? Ideas?

For the record, I could use a non recursive function or adjust the current recursive one and compute permutations one step at a time, but while this would let Rainmeter "breathe" instead of making it "busy', it would take much longer to complete the operation. I could also use precomputed permutations from a file instead of a function, but really, this is a general problem for long(er) operations, whether they're in Lua or plain Rainmeter itself,hence the question.

P.S. I could post a sample code if needed, but it's not that hard to get what I'm saying here, so I skipped that part for now.
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth
User avatar
Jeff
Posts: 352
Joined: September 3rd, 2018, 11:18 am

Re: Make Lua unblocking?

Post by Jeff »

Yincognito wrote: September 14th, 2024, 2:45 pm Some older posts on the forum state that coroutines cannot be used in Rainmeter's Lua, though this is not explictly stated in the manual (unless it's an external compiled library even though the Lua manual says it's a sub-library of the basic library, whatever that means). So, what other choices can be used? Ideas?
coroutines are not in the Restriction part of that page because they absolutely work in Rainmeter

Code: Select all

[Script]
Measure=Script
ScriptFile=test.lua

[SomeMeter]
Meter=Image
SolidColor=F00F00
W=100
H=100
LeftMouseUpAction=!CommandMeasure Script "coroutine.resume(TheyWork)"

Code: Select all

function Initialize()
	print("This gets executed before the numbers")
	--global variable
	TheyWork = coroutine.create(function()
		for i=1,100 do
			print(i)
			if math.fmod(i, 5) == 0 then coroutine.yield() end
		end
	end)
	print("Coroutine created, call anytime")
	-- didn't know how to run first time without at least one resume
	coroutine.resume(TheyWork)
end
Every time you click the square, the coroutine executes and prints 5 numbers, a genuinely very nice state machine that allows you to do waits for other stuff to send info.

This is an esoteric opinion, but I'm 100% sure the Lua manual is lying, it says it's "multithreaded", which immediately jumps the mind to System/CPU Threads, but in reality if you read between the lines it becomes obvious what they are in pure Lua, only a single coroutine can run at a time and coroutines exist as a different datatype in Lua, like table, userdata or thread. Coroutines are just Serial Lua function blocks, that run serially in the respective code, that Lua just allow you to control the running state of, they are Lua Threads and not System Threads (sadly).
It's not out of the books that the people who implement Lua into an app could assign coroutines to different workers if they want by just spawning different Lua processes and binding some sort of connection between them, in Rainmeter it's just that this hasn't been done, and it's as serial as Rainmeter itself :P
To get to the question of the thread though, since everything in Rainmeter is executed in the same place (most likely the Manage Rainmeter window), and each individual skin dosen't have it's own autonomy beside having a single individual Window form, I don't think it's possible for the entire app to not yield when running an intensive task in one of the skins, the only solution is to just run a different exe to do the work, and to just feed that result back to where you want it in Rainmeter, the only thing I know that dosen't yeild after executing something is RunCommand, which dosen't hang the app untill it gets the result, it just sits there idle while you wait... see if it's possible to use that and to read the Output from it. Good luck!
User avatar
Yincognito
Rainmeter Sage
Posts: 8358
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: Make Lua unblocking?

Post by Yincognito »

Jeff wrote: September 21st, 2024, 3:43 pm coroutines are not in the Restriction part of that page because they absolutely work in Rainmeter
Thanks for the reply and info, Jeff - much appreciated! :rosegift:

What I was concerned about was that since every script measure has its own environment and I wasn't sure that recursive environment "survives" through multiple skin updates, I wouldn't be able to do this permutations coroutine, where ideally I would call to "pause" or "resume" generating permutations from the skin's .ini, instead of from the .lua script.

I admit I didn't test that yet, since I'm in the process of testing and choosing the fastest possible permutation algorithm (the Heap one is a good candidate for now, like this non-optimal Lua script here), but your reply is promising - it remains to be seen if this coroutine / recursive system can be triggered from anywhere in the .lua script and hopefully anywhere in the .ini skin. ;-)
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth