Search code examples
lua

Inherit LUA Table with variables from Class with setmetatable


I'm new to the concept of "faking" OOP in lua with metatables, indexes and OOP in general.

I'm trying to create an instance from an Object in LUA which use variables in the table, so that every instance have its own values. The Fighter model seams pretty common, so I'm trying to explain :-)

FIGHTER = {
    ["id"] = "Fighter",
    ["params"] = {      
        ["route"] = 
        {                                    
            ["points"] = 
            {
                [1] = 
                {
                    ["x"] = wp01x,
                    ["y"] = wp01y,
                    ["speed"] = fighterSpeed,
                    ["task"] = 
                    {
                        ["id"] = "ComboTask",

                    },
                },
            },
        },
    },
}

function FIGHTER:new(t)
    t = t or {}
    setmetatable(t,self)
    self.__index = self
    return t
end

local wp01x = 0.38746345345
local wp01y = 1.39876268723
local fighterSpeed = 123

local test = FIGHTER:new({FIGHTER})

When the table is created, x, y, speed are nil (so the entries missing on construction).

Passing the values in the Constructor with something like

self.["Mission"].["params"].["route"].["points"].[1].["speed"] = 99

don't work either.

What would be best practice to create such instances? Use some preset values and clone the table later?


Solution

  • I correct your version a little bit and hope it opens your eyes...

    FIGHTER = {
        ["id"] = "Fighter",
        ["params"] = {      
            ["route"] = 
            {                                    
                ["points"] = 
                {
                    [1] = 
                    {
                        ["x"] = 0,
                        ["y"] = 0,
                        ["speed"] = 0,
                        ["task"] = 
                        {
                            ["id"] = "ComboTask",
    
                        },
                    },
                },
            },
        },
    }
    
    function FIGHTER:new(t, wpx, wpy, speed)
        t = t or {id = "Fighter", params = {route = {points = {[1] = {x = wpx, y = wpy, fighterSpeed = speed, task = {id = "ComboTask"}}}}}}
        setmetatable(t,self)
        self.__index = self
        return t
    end
    
    local wp01x = 0.38746345345
    local wp01y = 1.39876268723
    local fighterSpeed = 123
    
    -- The t = t or >>{...}<< case
    test = FIGHTER:new(_, wp01x, wp01y, fighterSpeed)
    -- The t = >>t<< case
    test = FIGHTER:new({id = "Fighter", params = {route = {points = {[1] = {x = wp01x, y = wp01y, fighterSpeed = fighterSpeed, task = {id = "ComboTask"}}}}}})