lua 继承现有对象

lua inheritance on existing object

我正在写一个新的构造函数,我有这样的东西:

function Map:new(path, world, debug)
    local map = sti(path, { "box2d" })
    return map
end

function Map:update(dt)
    print('call this')
end

sti 是一些构建 class 对象的第三方库。 我想做的是在我打电话时做到这一点:

map:update(dt)

它调用了我声明的函数。如果没有找到,它会调用 sti 在对象上设置的实际函数。

我试过用元表填充,但似乎无法让我的函数优先于第三方库提供的函数....

阅读我认为是您正在使用的库的源代码 (Simple-Tiled-Implementation),我发现它实际上用另一个元table 覆盖了您的元table:

local function new(map, plugins, ox, oy)
    local dir = ""

    if type(map) == "table" then
        map = setmetatable(map, Map) -- Here
    else
        -- Check for valid map type
        local ext = map:sub(-4, -1)
        assert(ext == ".lua", string.format(
            "Invalid file type: %s. File must be of type: lua.",
            ext
        ))

        -- Get directory of map
        dir = map:reverse():find("[/\]") or ""
        if dir ~= "" then
            dir = map:sub(1, 1 + (#map - dir))
        end

        -- Load map
        map = setmetatable(assert(love.filesystem.load(map))(), Map) -- Or here
    end

    map:init(dir, plugins, ox, oy)

    return map
end

上面的函数定义here

您需要传递一个 table 参数作为映射而不是路径,在那里您可以定义 update(),这将优先于 STI 提供的元 table .

我相信您可以复制 STI 加载地图的过程,并为其提供一个 table 包含您希望在其中定义的函数:

-- Check for valid map type
local ext = map:sub(-4, -1)
assert(ext == ".lua", string.format(
    "Invalid file type: %s. File must be of type: lua.",
    ext
))

-- Get directory of map
dir = map:reverse():find("[/\]") or ""
if dir ~= "" then
    dir = map:sub(1, 1 + (#map - dir))
end

-- Load map
local map = assert(love.filesystem.load(map))()
function map:update()
    -- Do things
end

sti(map, { "box2d" })

不幸的是,sti 在函数顶部声明了 'local dir',因此复制代码无效。 我找到了一个解决方案,我如何让自己轻松地将 class 设置为 lua:

中的代理
-- forward a function call from oldSelf:fn(...) to newSelf:fn(...)
function utils.forwardFunc(fn, newSelf)
   return function(oldSelf, ...)
      local function __NULL__() end
      return (fn or __NULL__)(newSelf, ...)
  end
end

-- make a function fn(...) call newSelf:fn(...)
function utils.func(fn, newSelf)
   return function(...)
      local function __NULL__() end
      return (fn or __NULL__)(newSelf, ...)
  end
end

-- forward any undefined functions called on 'from' to 'to'
-- if 'to' is a function, it acts as a dynamic proxy, incase you are changing what class you are proxying to
-- on the fly. For example, a state machine proxies to the current state
function utils.proxyClass(from, to)
   local mt = getmetatable(from)
   setmetatable(from, {__index = function(_, func)
         if mt and mt[func] then
            return mt[func]
         end

         local forwardTo = to
         if type(to) == 'function' then
            forwardTo = to(from)
         end

         if type(forwardTo[func]) == 'function' then
            return utils.forwardFunc(forwardTo[func], forwardTo)
         else
            return forwardTo[func]
         end
   end})
end