Page 1 of 1
Is there a way to run a loop in a second thread?
Posted: Sun Mar 05, 2023 11:55 am
by psemo
I really googled a lot and couldn't find a sensible way to do this
I want the below code to work every frame except "local particles = ..."
Code: Select all
local ParticleManager = [[
local Particles = ...
local dt = love.timer.getDelta()
for pIndex, Particle in pairs(Particles)
do
if Particle.timer > Particle.dissappearTime then
table.remove(Particles, pIndex)
Particle = nil
else
Particle.PosX = Particle.PosX + (Particle.directionX * Particle.speed * (1 - (Particle.timer / Particle.dissappearTime))) * dt
Particle.PosY = Particle.PosY + (Particle.directionY * Particle.speed * (1 - (Particle.timer / Particle.dissappearTime))) * dt
Particle.timer = Particle.timer + dt
end
end
]]
this code below starts the code upper.
Code: Select all
function CreateThread(Particles)
-- Creates a new thread and start it
local Manager = love.thread.newThread(ParticleManager)
Manager:start(Particles)--gotta run this every frame and pass the table of particles
--And this needs dt
end
I don't know how to call from the main too
Re: Is there a way to run a loop in a second thread?
Posted: Sun Mar 05, 2023 2:05 pm
by Bigfoot71
I don't really understand the problem you are facing but löve2d already has a particle system:
https://love2d.org/wiki/ParticleSystem
And something that has nothing to do but your loop may cause errors, if you iterate an array in which you are removing elements you have to iterate upside down, ie:
Code: Select all
for i = #tbl, 1, -1 do
table.remove(tbl, i)
end
Re: Is there a way to run a loop in a second thread?
Posted: Sun Mar 05, 2023 5:12 pm
by psemo
Bigfoot71 wrote: ↑Sun Mar 05, 2023 2:05 pm
I don't really understand the problem you are facing but löve2d already has a particle system:
https://love2d.org/wiki/ParticleSystem
And something that has nothing to do but your loop may cause errors, if you iterate an array in which you are removing elements you have to iterate upside down, ie:
Code: Select all
for i = #tbl, 1, -1 do
table.remove(tbl, i)
end
I know that but I wanna use the one I created myself. I just wanna run it on my second thread every frame. How can I do that?
Re: Is there a way to run a loop in a second thread?
Posted: Sun Mar 05, 2023 6:53 pm
by Andlac028
Create thread at the game start and send partickes to it and use channel:supply to push data to main thread. Also meassure time since last supply (or alternatively, just use :push and take delta time from another channel where you push it from main thread).
In main thread, pop particles positions and do the work. But always store last particles positions, in case, the particles thread would be slow and wouldn’t push particles positions yet to main thread.
(not tested, let me know, if you need example code, or something)
Also apart from removing elements from array and using pairs, if you have numerical indexes, use ipairs, as it can be faster.
And one microoptimalization: division is a lot slower than multiplication. If you divide frequently (something/value) with same value, consider using precomputed reciprocal value (rValue=1/value) and then do multiplication instead (something*rValue)
And also you compite timer/disappertime twice (once for x and once for y), consider saving frequently computed value in temp variable instead of compiting them more times.
Re: Is there a way to run a loop in a second thread?
Posted: Sun Apr 02, 2023 5:41 am
by kuinashi101
I'm making an 2d-array based particle system these days which could do more fancy things on the particles, like tween scale and color, wavy movement, apply shaders..etc.
My process flow is pre-spawn particle data for say 5000 times and store then in a table 'masterPool'. declare and iterate another table named 'pSleep' which stores numbers as index from 1 to 5000. each time you spawn particles, you get and remove the number from last index of 'pSleep' and store it to another table 'pActive'. now you can deal with activated particles by taking numbers in 'pActive' as reference to 'masterPool'. pass them to the thread. set the pushed back data to original ones for draw().
Suggestion is using frame call instead of calculating delta time and it's not necessary to update it each frame. you just have to run the thread again after the it is completed, so that will truly take advantage of threading which is doing stuffs by occupy lesser resource from main thread. the influence of a slightly latency of updating particles' graphic should be tolerable.
Re: Is there a way to run a loop in a second thread?
Posted: Mon Apr 03, 2023 3:24 pm
by Sasha264
One day I tried to do my own particle system that way, with the threads. But no luck, because for me necessity to copy (push / supply or whatever) data from separate thread turned out to be a bottleneck. And there is not so much calculation for every particle every frame. Basically its just x = x + v * dt with some similar additions, so, I got no real benefit from running it in separate thread.
Maybe there is a way to make some benefit with love 2d byte object that can be shared between threads
love.data.newByteData, but I newer did that.
Instead now I am using vertex shaders and instanced drawings for my own particles. So, in separate vertex buffer I store all particle params: position, velocity, color, angle, fade, sprite index, etc... and in vertex shader gpu calculates actual particle position and appearance based on that. And on cpu side each particle consumes only one-time calls of
Mesh:setVertexAttribute, and after that particle is all set, and for consequent frames cpu do literally nothing for that particle, while it keeps moving, fading, rotating... and do what it meant to do.