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

你说的曾经没有我的故事 提交于 2019-12-11 03:08:25

问题


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!


回答1:


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.




回答2:


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



来源:https://stackoverflow.com/questions/56045849/lua-how-to-modify-these-arguments-to-be-const-or-what-should-i-do

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!