table.remove() and nested tables...

Bobert13

Prince
Joined
Feb 25, 2013
Messages
346
I'm in the process of restructuring a custom class that uses metatables and tables to track it's members. Sometimes, I need to remove a table entry which is itself another metatable (and some of it's members are even initialized as tables or numbers and they may or may not have data stored). I want to use table.remove and have the indexes decremented. Is it safe to just remove the sub-class metatable without removing any of it's members first or must I remove all members of the sub-class before removing it?

Example (I maka da copy pasta!):
Spoiler :
Code:
-------------------------------------------------------------------------------------------
--Plate Class
-------------------------------------------------------------------------------------------
Plate = inheritsFrom(nil)

function Plate:New()
	local new_inst = {}
	setmetatable(new_inst, {__index = Plate})
	
	new_inst.size = 0
	new_inst.type = 0 --1 == land vs. 0 == sea
	new_inst.tiles = {} --a list of all indexes belonging to this plate
	new_inst.neighbors = {} --a list of all neighboring plates TODO: maybe look at storing how many tiles in this plate touch at least one tile of each neighbor...
	new_inst.speed = 0 --x, y, and absolute (Euclidean Distance) speed
	new_inst.xSpeed = 0
	new_inst.ySpeed = 0
	
	return new_inst
end
-------------------------------------------------------------------------------------------
--PlateMap Class
-------------------------------------------------------------------------------------------
PlateMap = inheritsFrom(FloatMap)

function PlateMap:New(width,height,wrapX,wrapY)
	local new_inst = FloatMap:New(width,height,wrapX,wrapY)
	setmetatable(new_inst, {__index = PlateMap});

	
	new_inst.plate = {}
	new_inst.ID = {} --FloatMap with an index for each plot
	new_inst.fault = {} --FloatMap with an index for each plot
	new_inst.faultTiles = {} -- a list of all tiles that share a border with another plate
	new_inst.plateCount = 0 
	new_inst.contPercent = 0
	new_inst.contSize = 0
	new_inst.contCount = 0

	return new_inst
end
-------------------------------------------------------------------------------------------
function PlateMap:GeneratePlates(numPlates)
	
[COLOR="Red"]--## SNIP ##--[/COLOR]
	
	--make a table of plate IDs that no longer exist. We do this here to ensure that they're in sequential order!!
	local toRemove = {}
	for ID = 1, PlateMap.plateCount, 1 do
		local plate = PlateMap.plate[ID]
		if plate.size == -1 then
			table.insert(toRemove, ID)
		elseif plate.size < 2 then
			print(string.format("OH NOES!! We still have a %d size plate. ID = %d", plate.size, ID))
		end
	end
	
	print(string.format("BEFORE: plateCount = %d, length of PlateMap.plate = %d; last plate index's size = %d", PlateMap.plateCount, #PlateMap.plate, PlateMap.plate[PlateMap.plateCount].size))
	--iterate through our toRemove table and get rid of that ID from ALL of our datamaps. EVERYTHING here REQUIRES that the IDs stored in toRemove are in sequential order!!
	PlateMap.plateCount = PlateMap.plateCount - #toRemove
	while #toRemove > 0 do
		local ID = table.remove(toRemove)
		-- table.remove(PlateMap.plate[ID].speed)
		-- table.remove(PlateMap.plate[ID].neighbors)
		-- table.remove(PlateMap.plate[ID].info)
		-- table.remove(PlateMap.plate[ID].type)
		-- table.remove(PlateMap.plate[ID].size)
		-- PlateMap.plate[ID] = nil
		table.remove(PlateMap.plate, ID) -- I'm hoping that removing this index removes all nested tables beneath it as well.
		for i = 0, #PlateMap.ID, 1 do --this loop decrements table IDs so that the ID == it's index in ALL datamaps related to plate tectonics (hooray!!)
			if PlateMap.ID[i] > ID then
				PlateMap.ID[i] = PlateMap.ID[i] - 1
			end
		end
	end
	print(string.format("AFTER: plateCount = %d, length of PlateMap.plate = %d; last plate index's size = %d", PlateMap.plateCount, #PlateMap.plate, PlateMap.plate[PlateMap.plateCount].size))
end

I'm asking this because so far as I can tell, it seems that the nested tables are getting removed (the size of the last plate matches before and after) but later on in the script I'm running into weirdness...
 
Back
Top Bottom