初始化不设置字段

Init not setting fields

我正在对插件进行重写,主要是将旧的 WildStar 插件 Wtacher 转变为更新的版本,由于采用了新的模块化结构,该版本更易于维护。原作者允许我这样做,但告诉我重写插件以更好地理解它,因为我对此很陌生。

原来的插件可以在这里找到:http://www.curse.com/ws-addons/wildstar/221782-watcher

我的源代码可以在这里找到:https://github.com/NekoNova/WatcherEx

我在游戏中收到的错误消息如下:

...aming\NCSOFT\WildStar\Addons\WatcherEx\WatcherEx.lua:1433: bad argument #1 to 'ipairs' (table expected, got nil) stack trace: [C]: in function 'ipairs' ...aming\NCSOFT\WildStar\Addons\WatcherEx\WatcherEx.lua:1433: in function 'FillFiltersList' ...aming\NCSOFT\WildStar\Addons\WatcherEx\WatcherEx.lua:886: in function <...aming\NCSOFT\WildStar\Addons\WatcherEx\WatcherEx.lua:867>

所以我在提到的几行查看了我的源代码,基本上这段代码引起了问题:

-- Fills the list of Filters available to be used in the Addon.
function WatcherEx:FillFiltersList()
    if self.wndMain == nil then
        return 
    end

    local filtersList = self.wndMain:FindChild("filters_list")
    filtersList:DestroyChildren()

    for i, filterClass in ipairs(self.tFilters) do
        local filterItem = Apollo.LoadForm(self.xmlDoc, "filter_item", filtersList, self)
        filterItem:SetData({ filter = filterClass })
        filterItem:FindChild("name"):SetText(filterClass.name)
    end

    return filtersList:ArrangeChildrenVert()
end

所以基本上我尝试使用我的内部 tFilters 变量,但它是零,应该是 table。 正如我所说,我对 Lua 游戏编程很陌生,但据我了解,我的 __init 元功能可能设置有误,因为我从原始版本复制了这个并尝试稍微清理一下。这是代码 metatable code:

function WatcherEx:new(tObject)
    tObject = tObject or {}
    setmetatable(tObject, self)
    self.__index = self

    -- Initialization
    self.tSettings = {}
    self.tDefaults = {}
    self.tAbilities = {}
    self.tInnates = {}
    self.tEngineerSpells = {}
    self.tActiveRules = {}

    local tClass = setmetatable({
        __init = function(self)         
            self.tActiveRules = { }
            self.bUnlockAll = false
            self.eventsHidden = nil
            self.tFilters = {
                AvailabilityFilter,
                TimeFilter,
                CombatFilter,
                ActionSetFilter,
                SpecialFilter,
                HPFilter,
                MPFilter,
                ShieldFilter,
                ChargeFilter,
                ResourcesFilter,
                BuffFilter,
                LuaFilter}
        end,
        __base = self,
        __name = "WatcherEx"
    }, {
        __index = self,
        __call = function(cls, ...)
            local tTable = setmetatable({}, self)
            cls.__init(tTable, ...)
            return tTable
        end})

    self.__class = tClass
    return tObject
end

有人能告诉我我做错了什么,并解释一下问题吗?我正在尝试了解更多有关 Lua 的信息,但是关于继承和元类的这一部分有点令人困惑。

编辑: 当我现在看的时候,我实际上在想我可以去掉 metatable 结构,直接将变量设置为我的 WatcherEx Table.....

的成员

好的, 终于明白了....

这是我的 AvailabilityFilter Class 的一个片段,它继承自 BaseFilter,现在我的字段已通过我的 metatables 正确设置:

local AvailabilityFilter = {}
local AvailabilityFilterClass = {
    __init = function(self, ...) return BaseFilter.__init(self, ...) end,
    __base = AvailabilityFilter,
    __name = "AvailabilityFilter",
    __parent = BaseFilter
}
local AvailabilityFilterClassMt = {
    __index = function(cls, strName)
                local val = rawget(AvailabilityFilter, strName)

                if val == nil then
                    return BaseFilter[strName]
                else
                    return val
                end
            end,
    __call = function(cls, ...)
                local _self = setmetatable({}, AvailabilityFilter)  
                cls.__init(_self, ...)
                return _self
            end
}
AvailabilityFilter.mt = {}
AvailabilityFilter.tDefaults = {
    strName = "Availability",
    strWindowName = "AvailabilityFilter",
    bInActionSet = true,
    tParent = BaseFilter
}
AvailabilityFilter.mt.__index = AvailabilityFilter.tDefaults
-----------------------------------------------------------------------------------------------
-- Constructor
-----------------------------------------------------------------------------------------------
function AvailabilityFilter:new()
    local tInstance = {}

    setmetatable(AvailabilityFilter.mt, BaseFilter.__base)
    setmetatable(tInstance, AvailabilityFilter.mt)
    setmetatable(AvailabilityFilterClass, AvailabilityFilterClassMt)

    tInstance.__class = AvailabilityFilterClass

    if BaseFilter.__inherited then
        BaseFilter.__inherited(BaseFilter, AvailabilityFilterClass)
    end

    return tInstance
end

基本上我所做的是:

  • 创建基础过滤器
  • 为其创建元table
  • 为其创建默认值table
  • 创建新对象 + 元table
  • link 它们:对象 -> 对象元table -> 基础过滤器元 table

现在可以使用了:

> a = _G["WatcherExLibs"]["ActionSetFilter"].new()
inspect a.strName
"Action Set"