Amaterastis
Amaterastis

Reputation: 479

lua -> how to modify these arguments to be const, or what should I do?

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

Answers (2)

Aki
Aki

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

Nifim
Nifim

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 newImgDatabased 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

Related Questions