I have a table with params.Params can be vector3/vector4/url/hashes. I need to make a deepcopy of that table. How can i do that? The problem that i don’t know what type of userdata i coping. I tried check fields with pcall but it is not helped.
I can make a map with keys and types. But maybe there are others ways.
Table
return {
go_fun = "create_go_sprite_main",
z = 0.2,
scale = SCALE,
sprite = hash("asteroid1"),
speed = 1000,
rect_size = vmath.vector3(300, 300, 0),
removable = true,
mask = MASK.ENEMY_MASK,
group = MASK.ENEMY,
cg = {
{type = "rect", x = 0, y = 0, w = 250, h = 250},
{type = "circle", x = 0, y = 0, r = 125}
}
}
local function deepcopy(orig)
local orig_type = type(orig)
local copy
if orig_type == 'table' then
copy = {}
for k, v in pairs(orig) do
copy[k] = deepcopy(v)
end
elseif orig_type == "userdata" then
print("here1")
if pcall(orig.w) then
copy = vmath.vector4()
elseif pcall(orig.x) then
copy = vmath.vector3(orig)
else
assert(nil, "unknown user data")
print(orig)
end
print("here2")
else -- number, string, boolean, etc
copy = orig
end
return copy
end
Well, the type() function will return “userdata” for matrix, vector3, vector4 and quaternion types so that’s no help. I guess you could perhaps do some checks to figure things out:
if type(foobar) == "userdata" and not foobar.w then
print("This could be a vector3")
end
pcall() will not work like that. pcall() expects a function (you passed another value type) to invoke and it returns if the function invocation was successful or not, as well as any return values from the function call.
I was working on pretty much exactly this problem. As of 1.2.188 the functions sys.serialize() and sys.deserialize() provide a very convenient solution.
See below where I duplicate the “original” table and modify both a subtable and a vector3. As you can see when pprinting both tables, table “duplicate” contains copies, not refs. Thanks @JCash for the suggestion.
local original = {a = "string", b = {1,2,3}, c = vmath.vector3(4,5,6), d = hash("hash")}
local duplicate = sys.serialize(original)
duplicate = sys.deserialize(duplicate)
duplicate.b[2] = 7
duplicate.c.y = 8
pprint(duplicate)
pprint(original)