-- 嵌套表 local class = class local select = select local next = next local setmetatable = setmetatable local assert = assert local type = type local getmetatable = getmetatable local pairs = pairs local xpcall = xpcall local tostring = tostring local table_insert = table.insert -------------------------------------------------- local NestingTable = class("NestingTable") -- 断言类型 local function isKind(obj, strKind) local mt if type(obj) == "table" then mt = getmetatable(obj) end while mt do if mt.__cname == strKind then return true end mt = mt.super end return false end local function exception(e) -- Log.e(e) return e end local function xxpcall(f, ...) return xpcall(f, exception, ...) end --- 构造函数 -- @param deep 深度 -- @param bWeak 弱引用 function NestingTable:initialize(deep, bWeak) self.m_deep = deep or 1 self.m_bWeak = bWeak == true self.m_count = 0 self.m_items = {} self:clear() end --- 新增对象 -- @param item 对象实例 -- @param k 键值 -- @param ... 多个键值 function NestingTable:add(item, k, ...) if not item or not k or select("#", k, ...) ~= self.m_deep then -- Log.w("NestingTable add nil!") return end if ... then local _item = self:get(k) if not _item then local deep = self.m_deep - 1 _item = NestingTable.new(deep, self.m_bWeak) self.m_items[k] = _item end _item:add(item, ...) else self.m_items[k] = item -- Log.d("NestingTable add", k, item) end end --- 删除对象 -- @param k 键值 -- @param ... 多个键值 function NestingTable:remove(k, ...) if not k or select("#", k, ...) ~= self.m_deep then -- Log.w("NestingTable remove k nil!") return end local _item = self:get(k) if not ... then -- Log.d("NestingTable remove", k, _item) self.m_items[k] = nil elseif _item then _item:remove(...) if not next(_item:getItems()) then self.m_items[k] = nil end end end --- 取对象 -- @param k 键值 -- @param ... 多个键值 -- @return 被管理对象实例 function NestingTable:get(k, ...) if not k then -- Log.w("NestingTable get k nil!") return end local item = self.m_items[k] if not ... then return item end if item then return item:get(...) end end --- 取所有对象 function NestingTable:getItems() return self.m_items end function NestingTable:clear() if self.m_deep <= 1 then self.m_items = self.m_bWeak and setmetatable({}, { __mode = "v", }) or {} else self.m_items = {} end end function NestingTable:traverse(closure) assert(closure) for _, item in pairs(self.m_items) do if isKind(item, "NestingTable") then item:traverse(closure) else xxpcall(closure, item) end end end function NestingTable:pack(packName, ...) local ret = {} for key, item in pairs(self.m_items) do if isKind(item, "NestingTable") then ret[tostring(key)] = item:pack(packName, ...) elseif packName then ret[tostring(key)] = item[packName](item, ...) else ret[tostring(key)] = item end end return ret end function NestingTable:packKey(deep) assert(deep, "packKey") local ret = {} for key, item in pairs(self.m_items) do if deep <= self.m_deep then ret[tostring(key)] = item:packKey(deep) else table_insert(ret, key) end end return ret end return NestingTable