Reputation: 479
all!
I came here because I have one problem bugging me for quite some time now. I am using love2d engine as a 'graphical' addition to lua scripting, but this problem is of lua type (I believe, at least).
I have a function:
createNew_keepOld = function (oldImgData, oldImgDraw)
local newImgData = oldImgData --I am assigning old value to another variable
local newImgDraw = oldImgDraw --I am doing the same thing as with data
for x = 0, newImgData:getWidth()-1 do
for y = 0, newImgData:getHeight()-1 do
local r, g, b, a = newImgData:getPixel(x, y)
r = 2*r
g = 2*g
b = 0.5*b
a = 2*a
newImgData:setPixel(x, y, r, g, b, a)
end
end
newImgDraw:replacePixels(newImgData)
return newImgData, newImgDraw
end
When this code finishes, I get the change I need, but not WHERE I want it. I just want to produce two new variables which will store data and image objects. But, in process, original image gets changed.
Is there any way to declare:
name = function (const param, const param)
return some_things
end
So that I get output I need without changing the original stuff? Or is there some problem with my code that I cannot see?
Thanks!
Upvotes: 2
Views: 581
Reputation: 2928
Actually the nature of this problem is both in Love2D and Lua. Anyway.
Quote from Lua Reference Manual 5.3:
Tables, functions, threads, and (full) userdata values are objects: variables do not actually contain these values, only references to them. Assignment, parameter passing, and function returns always manipulate references to such values; these operations do not imply any kind of copy.
Most types from Love2D are of userdata Lua type, so when passing them to your function you are actually passing reference to them, hence you modify the "old" versions in the very end. Those types usually have functions made for copying them.
ImageData
does have one and Image
does not, but you can do the following:
createNew_keepOld = function (oldImgData, oldImgDraw)
local newImgData = oldImgData:clone()
for x = 0, newImgData:getWidth()-1 do
for y = 0, newImgData:getHeight()-1 do
local r, g, b, a = newImgData:getPixel(x, y)
r = 2*r
g = 2*g
b = 0.5*b
a = 2*a
newImgData:setPixel(x, y, r, g, b, a)
end
end
local newImgDraw = love.graphics.newImage(newImgData, oldImgDraw:getFlags())
return newImgData, newImgDraw
end
Note that I created entirely new Image
based on copied ImageData
and image flags from the old one.
Upvotes: 2
Reputation: 5031
In Lua when you make a variable equal to a table value you are not copying or duplicating that information. The new variable simply points to the same values as the other variable.
Example:
tbl1 = {}
tbl2 = tbl1
tbl2[1] = 1
print(tbl1[1])
In order to create a newImgData
based on oldImgData
you need to preform a deep copy:
function deepcopy(orig)
local orig_type = type(orig)
local copy
if orig_type == 'table' then
copy = {}
for orig_key, orig_value in next, orig, nil do
copy[deepcopy(orig_key)] = deepcopy(orig_value)
end
setmetatable(copy, deepcopy(getmetatable(orig)))
else -- number, string, boolean, etc
copy = orig
end
return copy
end
Resource for table copying: Lua-Users Wiki: Copy Table
This Solution only works a table
type, it will not work for userdata
Upvotes: 2