Skip to content

Implement panel index accessor in Lua #2256

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

noaccessl
Copy link
Contributor

Analogous to the entity index accessor, this approach will be faster. In the game, panel functions are called and panel values are accessed really frequently and numerously.

Benchmark

Using gluafuncbudget
CPU: Intel i7-3770
OS: Windows 10

Code
local meta = FindMetaTable( "Panel" )

local PanelIndexAccessor_C = meta.__index

local g_PanelsTables = {}

local function PanelIndexAccessor_Lua( self, key )

	--
	-- Panel-specialized values
	--
	if ( key == "Hovered" ) then
		return meta.GetTable( self ).Hovered
	elseif ( key == "x" or key == "X" ) then

		local x = meta.GetPos( self )
		return x

	elseif ( key == "y" or key == "Y" ) then

		local _, y = meta.GetPos( self )
		return y

	end

	--
	-- Search the panel table
	--
	local pnlTable = g_PanelsTables[self]

	if ( !pnlTable ) then

		pnlTable = meta.GetTable( self )

		if ( !pnlTable ) then

			-- If table isn't yet installed, look in the metatable
			return meta[key]

		end

		g_PanelsTables[self] = pnlTable

	end

	local value = pnlTable[key]

	-- Look in the table
	if ( value != nil ) then
		return value
	end

	-- Look in the metatable
	value = meta[key]

	return value

end


local TestPanel = vgui.Create( "EditablePanel" )
TestPanel.var = "Hello World!"

local JIT_OFF = false

local Tests = {

	{ name = "C; access x, y", func = function()

		PanelIndexAccessor_C( TestPanel, "x" )
		PanelIndexAccessor_C( TestPanel, "y" )

	end; standard = true; jit_off = JIT_OFF };

	{ name = "Lua; access x, y", func = function()

		PanelIndexAccessor_Lua( TestPanel, "x" )
		PanelIndexAccessor_Lua( TestPanel, "y" )

	end; jit_off = JIT_OFF };

	{ name = "C; access metamethod", func = function()

		PanelIndexAccessor_C( TestPanel, "SetSize" )

	end; standard = true; jit_off = JIT_OFF };

	{ name = "Lua; access metamethod", func = function()

		PanelIndexAccessor_Lua( TestPanel, "SetSize" )

	end; jit_off = JIT_OFF };

	{ name = "C; access table value", func = function()

		PanelIndexAccessor_C( TestPanel, "var" )

	end; standard = true; jit_off = JIT_OFF };

	{ name = "Lua; access table value", func = function()

		PanelIndexAccessor_Lua( TestPanel, "var" )

	end; jit_off = JIT_OFF };

}


gluafuncbudget.Configure( {

	frames = 500;
	iterations_per_frame = 5000;

	digit = 4;

	measure_unit = "ms";
	comparison_basis = "average"

} )

for k, v in ipairs( Tests ) do
	gluafuncbudget.Queue( v )
end
Results

LuaJIT 2.1.0-beta3 (x86-64 Branch)

image

LuaJIT 2.0.4

image

--
local __index_internal = meta.__index

local g_PanelsTables = {}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thoughts on clearing invalid panels from g_PanelsTables every so often?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Panels, Entities are stored in the debug.getregistry() and are cleaned up on disconnect. Lua variables are cleaned up also as Server/Client Lua Interface is being shut down.

@robotboy655 robotboy655 added the Enhancement The pull request enhances current functionality. label Apr 3, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Enhancement The pull request enhances current functionality.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants