aboutsummaryrefslogtreecommitdiff
path: root/tutorials/tut031_metatables.md
blob: a397cc9f80c5098c92e3cddecc665833223abef4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# Tut 0x031

## Metatables

In the last tutorial we saw how to make a simple inventory, but we used a function from Gmod's library that was a bit silly. When we made a copy of our inventory, we used table.Copy() to return a copy seperate to the version in the registry. There's nothing wrong with this, but if you have a lot of fields, and default tables in your inventory, this can get quite costly. There's a simple alternative, lua metatables.

[Programming in Lua](https://www.lua.org/pil/13.html) does a much better job at explaining metatables than I ever could, so take a look at how they use it. We're not going to use all the features they discuss, just 1: the \_\_index method, to replace the DeSerialize() function from @{tut030_inventories.md}.

	function inv:DeSerialize()
		local self_copy = {}
		local mt = {
			__index = function(table,key)
				return self[key]
			end
		}
		setmetatable(self_copy,mt)
		local json = util.JSONToTable(data)
		for k,v in pairs(json) do
			local item_name = v[1]
			local item_data = v[2]
			local item = item_registry.GetItemFromData(item_name,item_data)
			self_copy.items[k] = item
		end
		for k,v in pair(self_copy.items) do
			self_copy.weight = self_copy.weight + v.weight
		end
		return self_copy
	end

Making this change for our example inventory isn't really a big deal, since we don't have many functions, but it's easy to get to a point where it's beneficial to not copy all the fields of an inventory whenever you need to deserialize it.