helix icon indicating copy to clipboard operation
helix copied to clipboard

Fix item instance's metatable object reference is not updated when gamemode refreshed.

Open 10sa opened this issue 3 years ago • 2 comments

Summary

table.Merge function's merging is if element is table, replacing table's element.

function table.Merge( dest, source )

	for k, v in pairs( source ) do
		if ( istable( v ) && istable( dest[ k ] ) ) then
			-- don't overwrite one table with another
			-- instead merge them recurisvely
			table.Merge( dest[ k ], v )
		else
			dest[ k ] = v
		end
	end

	return dest

end

Unfortunately, table.Merge function is not include metatable object case. (metatable is kind of table.) This means that the metatable reference of the table's metatable object does not change, only the value of the object changes.

Therefore, the following problem occurs when the gamemode is refreshed.

for _, v in pairs(ix.item.instances) do
  if (v.uniqueID == uniqueID) then
    table.Merge(v, ITEM);
    -- It will be trigger assertion failure.
    assert(getmetatable(v.somemetatableobject) == getmetatable(ITEM.somemetatableobject));
  end
end

This code is part of sh_item.lua.

Changes

A new table merge function (ix.util.MetatableSafeTableMerge) with exception handling for metatable objects has been added to the ix.util table and replaced the table.Merge function in sh_item.lua.

Alternative

New hooks for item table

Add an "OnGamemodeReloaded" hook (or similar) to give the items table responsibility for updating metatable objects. This make problem of having to implement code to update object refresh in item table code when using metatable objects.

Edit the document

Just write 'if metatable object in the field of the item table, the object's metatable reference will not change when gamemode refresh.' to the documentation. This is the easiest and fastest way.

10sa avatar Sep 26 '21 13:09 10sa

i am in love

ZeMysticalTaco avatar Sep 26 '21 18:09 ZeMysticalTaco

~~Could you not just make a local function instead of rewriting/overwriting table.Merge?~~

Nvm, you've changed it since.

BullyHunter32 avatar Sep 27 '21 16:09 BullyHunter32