--[[ The database has the following structure: { [appearanceID] = { [itemLink] = true, }, } It is updated at the following events: Character is logged on. The Transmog collection is updated. ]] local Database = {} CanIMogIt.Database = Database CanIMogIt.sourceIDQueue = {} local getItemInfoReceivedCount = 0 function Database:AddItem(itemLink, appearanceID) --[[ Adds the given itemLink to the database. Returns whether it was added or not. Will use the given appearanceID if passed, instead of recalculating. ]] appearanceID = appearanceID or CanIMogIt:GetAppearanceID(itemLink) if not appearanceID then return false end local appearanceTable = CanIMogItDatabase[appearanceID] if not appearanceTable then appearanceTable = self:AddAppearance(appearanceID) end if not appearanceTable[itemLink] then appearanceTable[itemLink] = true return true end return false end function Database:AddAppearance(appearanceID) --[[ Adds the appearanceID to the database if it's not there already. Returns the appearanceTable if it was created, false otherwise. ]] if not appearanceID then return false end if not CanIMogItDatabase[appearanceID] then local appearanceTable = {} CanIMogItDatabase[appearanceID] = appearanceTable return appearanceTable end return false end function Database:RemoveItem(itemLink) -- Removes the item from the database. local appearanceID = CanIMogIt:GetAppearanceID(itemLink) if not appearanceID then return false end local appearanceTable = CanIMogItDatabase[appearanceID] if appearanceTable and appearanceTable[itemLink] then appearanceTable[itemLink] = nil return true end return false end function Database:RemoveAppearance(appearanceID) --[[ Removes the appearanceID from the database. Returns whether it was removed or not. ]] if CanIMogItDatabase[appearanceID] then CanIMogItDatabase[appearanceID] = nil return true end return false end function Database:GetAppearanceTable(itemLink) -- Returns the appearance table for the item in the database. local appearanceID = CanIMogIt:GetAppearanceID(itemLink) return CanIMogItDatabase[appearanceID] end function Database:GetItem(itemLink) -- Returns whether the item is in the database. local appearanceTable = Database:GetAppearanceTable(itemLink) if appearanceTable then return appearanceTable[itemLink] or false end return false end function Database:UpdateAppearances() --[[ Updates the database with the current appearances, adding or removing as needed. ]] appearances = CanIMogIt:GetAppearances() for appearanceID, appearance in pairs(appearances) do if appearance.isCollected then self:AddAppearance(appearanceID) self:AddAppearanceSources(appearanceID) else self:RemoveAppearance(appearanceID) end end end function Database:AddItemBySourceID(sourceID, appearanceID) local itemLink = select(6, C_TransmogCollection.GetAppearanceSourceInfo(sourceID)) if string.find(itemLink, '|h%[%]|h') then -- still cooking -- Call GetItemInfo here so that we can capture the event when it's done cooking. GetItemInfo(itemLink) CanIMogIt.sourceIDQueue[sourceID] = appearanceID return end self:AddItem(itemLink, appearanceID) end function Database:AddAppearanceSources(appearanceID) -- Adds the sources (the items) of the appearance to the database. local sources = C_TransmogCollection.GetAppearanceSources(appearanceID) if not sources then return end for i, source in pairs(sources) do if source.isCollected then self:AddItemBySourceID(source.sourceID, appearanceID) end end end function Database:UpdateFromKnownSources(knownSources, appearanceID) -- Updates the items given from knownSources. for sourceID, source in pairs(knownSources) do self:AddItemBySourceID(sourceID, appearanceID) end end function Database:UpdateItem(itemLink, hasTransmogFromItem) -- Updates the status of the item in the database. if hasTransmogFromItem then self:AddItem(itemLink) else self:RemoveItem(itemLink) --[[ Need to update appearances in case the last item was removed from an appearanceTable]] local appearanceID = CanIMogIt:GetAppearanceID(itemLink) if CanIMogItDatabase[appearanceID] and next(CanIMogItDatabase[appearanceID]) == nil then -- if it's the last item in the appearanceTable, then remove the table. CanIMogItDatabase[appearanceID] = nil end end end function CanIMogIt.frame:PlayerLogin(event, ...) if event == "PLAYER_LOGIN" then -- add all known appearanceID's to the database Database:UpdateAppearances() end end function CanIMogIt.frame:TransmogCollectionUpdated(event, ...) if event == "TRANSMOG_COLLECTION_UPDATED" then -- add the equipment slot that was changed to the database Database:UpdateAppearances() end end local function tablelength(T) local count = 0 for _ in pairs(T) do count = count + 1 end return count end function CanIMogIt.frame:GetItemInfoReceived(event, ...) if event ~= "GET_ITEM_INFO_RECEIVED" then return end if next(CanIMogIt.sourceIDQueue) == nil then return end -- Update the database with any items that were still cooking. getItemInfoReceivedCount = getItemInfoReceivedCount + 1 if getItemInfoReceivedCount >= 300 or tablelength(CanIMogIt.sourceIDQueue) <= 300 then getItemInfoReceivedCount = 0 done = {} for sourceID, appearanceID in pairs(CanIMogIt.sourceIDQueue) do local itemLink = select(6, C_TransmogCollection.GetAppearanceSourceInfo(sourceID)) if not string.find(itemLink, '|h%[%]|h') then -- Done cooking! Database:AddItem(itemLink, appearanceID) done[sourceID] = true end end for sourceID, bool in pairs(done) do CanIMogIt.sourceIDQueue[sourceID] = nil end end end