Hi,
I have a problem with RunService which is running my code more than once even if I have the conditions to execute code once. Do you have any suggestions?
Code Example:
local run = game:GetService("RunService")
local otherFolder = game.Workspace:WaitForChild("otherFolder")
local t = {}
run.Heartbeat:Connect(function()
task.spawn(function()
if #t < #otherFolder then
table.insert(t, os.time())
end
end)
end)
The Heartbeat, as stated in the documentation, fires every frame after the physics simulation has completed.
Since Heartbeat fires every frame, it runs at a variable frequency. This implies that the rate will vary depending on the performance of the machine and doesn’t wait for the end of the calling function to continue. If the game is running at 40 FPS, then Heartbeat will fire 40 times per second, and the step argument will be roughly 1/40th of a second.
In your case, task.spawn serves absolutely no purpose. task.spawn create a new desynchronized thread so it’s just not useful in your situation.
I don’t know why you said, “I have the conditions to execute code once” because you have no conditions that stop the Heartbeat. You just insert some os.time, which amounts to adding 40 numbers per second if your computer runs at 40 frames per second.
If you want to stop the loop when your table is as full as your file, you might to do that:
local run = game:GetService("RunService")
local otherFolder = game.Workspace:WaitForChild("otherFolder"):GetChildren() -- Dont forgot the use :GetChildren() to get a table of the content of the instance
local t = {}
local runConnection = nil
runConnection = run.Heartbeat:Connect(function()
if #t < #otherFolder then
table.insert(t, os.time())
else
runConnection:Disconnect()
runConnection = nil
end
end)
But that’s really not the best way to do it, I personally prefer to use repeat.
local run = game:GetService("RunService")
local otherFolder = game.Workspace:WaitForChild("otherFolder"):GetChildren() -- Dont forgot the use :GetChildren() to get a table of the content of the instance
local t = {}
repeat
table.insert(t, os.time())
run.Heartbeat:Wait()
until (#t >= #otherFolder)
If you have any questions, don’t hesitate to ask me!
I understand that the heartbeat runs that way, but the code should run once, because the table gets one element inserted and then the condition should be false. RunService will run untill I disconnect it, but it shouldn’t run the code inside if the condition is not met. I don’t care about disconnecting the runservice.
Because you’re using task.spawn, it is possible two threads are spawned before the table has actually been updated so the condition is true twice in a row.
Suggestions:
print('table size', #t) in task.spawn(function() ... to confirm
remove task.spawn
create a locking mechanism so the table cannot be updated while another thread is updating it.
That code is an example is not the real code I use. I use GetChildren() for that, but is still running the code 2 times. I am polite! I just said I don’t want to disconnect the runservice, that’s all.
You said you don’t care, which is very rude when I’m only trying to help you with a code that isn’t even the one you’re trying to fix. The first code I gave you stops after adding a single element to the table as desired.
Okay I will not argue on that. I need runservice for a reason. I am checking if os.time() - the time from the table is equal with some other thing and then execute the rest of the code. I have some similar code which runs properly, but here it don’t.
That folder is updating at a point in game when I clone something in it and the run service is checking if the number of elements from that folder is greater then the table which has 0 elements and then insert one element and then will wont run because the condition is false. And then I am checking if the os.time() - the time from the table is equal with another value stored in profile service and when that is met the code inside will run once and then the time is removed from the table and redoing the cycle until I get my other conditions etc. But the problem is that the code is running two times in all of my if statements.