Is it possible to make a collapsing variables without making individual functions?

前端 未结 2 1833
既然无缘
既然无缘 2021-01-25 05:55

I have a code that starts as a small amount of variables and makes more elements using those initial variables.

function new( x, y, width, height )
    local obj         


        
2条回答
  •  囚心锁ツ
    2021-01-25 06:26

    You could make use of metatables, more specific, the __newindex field:

    (Well, need to combine it with the __index field, but eh)

    function new(x, y, width, height )
        local object = {
            font = {}, padding = {}, text = {input=''}, -- tables themself are static
            -- also I assume text.input will change and has to stay the way it is
        }
        -- more static data here (yes yes, I know. The code is a bit ugly, but if it works fine...)
        object.config = { active = true, devmode = false, debug = false, id = gui.id(), type = 'textbox' }
        object.backspace = {key = false, rate = 3, time = 0, pausetime = 20, pause = true}
            object.border = { x = x, y = y, width = width, height = height }
        -- stuff that has to be calculated from the above variables goes below
        local border = object.border
        local function calculate()
            --border
            --body
            object.body = { x = border.x+1, y = border.y+1, width = border.width-2, height = border.height-2 }
            --font
            object.font.size = height-(math.floor(height/4)+1)
            object.font.height = love.graphics.setNewFont( object.font.size ):getHeight()
            --padding
            object.padding.height = math.floor(object.border.height*(2/29))
            object.padding.width = object.padding.height*3
            --text
            object.text.centerHeight = math.ceil(object.body.y+((object.body.height-object.font.height)/2))
            object.text.left = object.body.x+object.padding.width+object.padding.height
            --backspacing
            --config
        end
        calculate()
        local proxy = setmetatable({},{
            __index = object; -- proxy.abc returns object.abc (to get width, use proxy.border.width)
            __newindex = function(s,k,v)
                -- fires whenever 'proxy[k] = v' is done
                -- I assume you'll only change x/y/width/height, as other properties are dynamic
                -- Doing 'proxy.x = 123' is the same as 'object.border.x = 123' + recalculating
                object.border[k] = v -- Actually apply the change
                calculate() -- Recalculate the other properties that depends on the above
            end;
        })
        gui.add(object)
        return object.config.id
    end
    

    You can run code like proxy.x = 12 to edit the X property. All values will be recalculated. It's not the best, but your code a tiny bit annoying to improve. (But hey, if it works fine for you, it's good)

    Note: You can only set x, y, width and height. You can get all properties the old way though, e.g. proxy.padding.width (Mind that proxy.x doesn't work. Use proxy.border.x)

提交回复
热议问题