Function Optimization

I have this print() statement so I can check in the console if it runs 1 time. but it multiplies every time I go back to the function.

I tried disconnecting the text button so that it calls the new function. instead, it still happens.

I’m not yet well experienced with the behavior of functions and stuff, so if there are some optimization for this, please tell me.

Script:

function setUpMainMenu()
	local menu_connections = {}
	--for index, obj in pairs(MainMenu:GetChildren()) do
	--	if not obj:IsA("TextButton") then continue end
	--	obj.TextTransparency = 1
	--end
	MainMenu.Visible = true
	--for index, obj in pairs(MainMenu:GetChildren()) do
	--	if not obj:IsA("TextButton") then continue end
	--	Animator:Fade(obj, "in", 1, false)
	--end
	
	local Play = MainMenu:WaitForChild("Play")
	local Settings = MainMenu:WaitForChild("Settings")
	
	menu_connections[Play.Name .. "_1"] = Play.MouseEnter:Connect(function()
		Play.Text = "<u>PLAY</u>"
	end)
	menu_connections[Play.Name .. "_2"] = Play.MouseLeave:Connect(function()
		Play.Text = "PLAY"
	end)
	
	menu_connections[Settings.Name .. "_1"] = Settings.MouseEnter:Connect(function()
		Settings.Text = "<u>SETTINGS</u>"
	end)
	menu_connections[Settings.Name .. "_2"] = Settings.MouseLeave:Connect(function()
		Settings.Text = "SETTINGS"
	end)
	menu_connections[Settings.Name .. "_3"] = Settings.MouseButton1Click:Connect(function()
		menu_connections[Settings.Name .. "_3"]:Disconnect()
		setUpSettings()
	end)
end

function setUpSettings()
	local settings_connections = {}
	MainMenu.Visible = false
	SettingsFrame.Visible = true
	
	-- contents
	local best_of_round = SettingsFrame["setting-contents"]["best-of-round"]
	local bor_setter = best_of_round.setter
	local function setBestOfRound(request)
		if request == "inc" then
			if table.find(default_settings.rounds, Settings_Folder.rounds.Value) >= 1 and table.find(default_settings.rounds, Settings_Folder.rounds.Value) < #default_settings.rounds then
				Settings_Folder.rounds.Value = default_settings.rounds[table.find(default_settings.rounds, Settings_Folder.rounds.Value) + 1] -- increment
			elseif table.find(default_settings.rounds, Settings_Folder.rounds.Value) >= #default_settings.rounds then
				Settings_Folder.rounds.Value = default_settings.rounds[1]
			else
				warn("error incrementing")
				return
			end
		elseif request == "dec" then
			if table.find(default_settings.rounds, Settings_Folder.rounds.Value) <= 1 then
				Settings_Folder.rounds.Value = default_settings.rounds[#default_settings.rounds]
			elseif table.find(default_settings.rounds, Settings_Folder.rounds.Value) > 1 and table.find(default_settings.rounds, Settings_Folder.rounds.Value) <= #default_settings.rounds then
				Settings_Folder.rounds.Value = default_settings.rounds[table.find(default_settings.rounds, Settings_Folder.rounds.Value) - 1]
			else
				warn("error decrementing")
				return
			end
		else
			warn("invalid")
			return
		end
		return
	end
	
	settings_connections[bor_setter.less.Name] = bor_setter.less.MouseButton1Click:Connect(function()
		setBestOfRound("dec")
	end)
	settings_connections[bor_setter.greater.Name] = bor_setter.greater.MouseButton1Click:Connect(function()
		setBestOfRound("inc")
	end)
	print("foo")
	-- Go Back
	SettingsFrame.TopBar.goBack.MouseButton1Click:Connect(function()
		SettingsFrame.Visible = false
		settings_connections[bor_setter.less.Name]:Disconnect()
		settings_connections[bor_setter.greater.Name]:Disconnect()
		setUpMainMenu()
	end)
	return
end

Console:
Invoke 1: foo
Invoke 2: foo(x2)
Invoke 3: foo(x4)
Invoke 4: foo(x8)
Invoke #: foo(x2000) – this lags the game now.

The problem is that you don’t disconnect the connection to SettingsFrame.TopBar.goBack.MouseButton1Click (the connection creation is copied below from your code).

SettingsFrame.TopBar.goBack.MouseButton1Click:Connect(function()
	SettingsFrame.Visible = false
	settings_connections[bor_setter.less.Name]:Disconnect()
	settings_connections[bor_setter.greater.Name]:Disconnect()
	setUpMainMenu()
end)

The problem should be fixed if you make the following change:

 settings_connections[SettingsFrame.TopBar.goBack.Name] = SettingsFrame.TopBar.goBack.MouseButton1Click:Connect(function()
	settings_connections[SettingsFrame.TopBar.goBack.Name]:Disconnect()
	SettingsFrame.Visible = false
	settings_connections[bor_setter.less.Name]:Disconnect()
	settings_connections[bor_setter.greater.Name]:Disconnect()
	setUpMainMenu()
end)

Here’s an explanation of what happens with the current code. Connection for opening means a connection to Settings.MouseButton1Click. Connection for closing means a connection to SettingsFrame.TopBar.goBack.MouseButton1Click.

  • initial setUpMainMenu call (not found in the code you posted but I assume this is further down in the local script):
    -connection for opening settings is created (opening connections: 1)
  • opening settings for the 1st time:
    -opening connection is disconnected: (opening connections: 1-1 = 0),
    -foo is printed once (total foos: 1),
    -connection for closing is created (total closing connections: 1)
  • closing the settings for the 1st time:
    -connection for opening settings is created 1 time (opening connections: 0+1)
  • opening the settings for the 2nd time:
    -opening connection is disconnected: (opening connections: 1-1 = 0),
    -foo is printed 1 time (total foos: 1+1 = 2),
    -connection for closing is created (total closing connections: 1+1 = 2)
  • closing the settings for the second time:
    -connection for opening settings is created 2 times because of 2 closing connections (opening connections: 0+2 = 2)
  • opening the settings for the 3rd time:
    -opening connections are disconnected (opening connections: 2-2 = 0),
    -foo is printed 2 times because of 2 opening connections (total foos: 2+2 = 4),
    -connection for closing is created 2 times because of 2 opening connections (total closing connections: 2+2 = 4)
  • closing the settings for the 3rd time:
    -connection for opening the settings is created 4 times because of 4 closing connections (opening connections: 0+4 = 4)
  • opening the settings for the 4th time:
    -opening connections are disconnected (opening connections: 4-4 = 0),
    -foo is printed 4 times because of 4 opening connections (total foos: 4+4 = 8),
    -connection for closing is created 4 times because of 4 opening connections (total closing connections: 4+4 = 8)
  • closing the settings for the 4th time:
    -connection for opening the settings is created 8 times because of 8 closing connections (opening connections: 0+8 = 8)

And so on…

In short, every time the settings are opened, all connections for opening settings are disconnected, as they should. However, because the connection for closing isn’t disconnected when the settings are closed, the closing connections stack up and thus the number of new opening connections created when closing the settings increases when the settings are opened and closed multiple times.

1 Like

Refer to what is said the post above.


There was a bit in your code that you should probably change.

menu_connections[Settings.Name .. "_3"] = Settings.MouseButton1Click:Connect(function()
		menu_connections[Settings.Name .. "_3"]:Disconnect()
		setUpSettings()
	end)

could be simplified to

menu_connections[Settings.Name .. "_3"] = Settings.MouseButton1Click:Once(function()
		setUpSettings()
	end)
2 Likes

Wouldn’t that change just make the problem worse?

Nope. It has the exact same end result
(You probably missed it, but I replaced :Connect with :Once, hence why I removed the disconnect)

1 Like

Oh, I see. My bad, you’re right.

Didn’t know there was :Once() for Connections. welp, every day is a learning day.

Thanks for the solutions!

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.