changeset 40:67ad1101ee10

Added an asynchronous loading mechanism for item and battle pet data. The wow objects loading is delayed until all the necessary data is available.
author madcatzinc@35b17cf1-18cd-47ff-9ca3-31d6b526ef09
date Thu, 25 Apr 2013 23:02:39 +0000
parents ce4ddefb68c2
children 841191e42919
files CyborgMMO7.lua MainPage.xml
diffstat 2 files changed, 114 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/CyborgMMO7.lua	Thu Apr 25 18:16:03 2013 +0000
+++ b/CyborgMMO7.lua	Thu Apr 25 23:02:39 2013 +0000
@@ -30,6 +30,7 @@
 end
 
 local VarsLoaded = false
+local AsyncDataLoaded = false
 local EnteredWorld = false
 local BindingsLoaded = false
 local SettingsLoaded = false
@@ -118,6 +119,17 @@
 	end
 end
 
+local KnownOldObjectTypes = {
+	item = true,
+	macro = true,
+	spell = true,
+	petaction = true,
+	merchant = true,
+	companion = true,
+	equipmentset = true,
+	callback = true,
+}
+
 local function ConvertOldRatData(oldData)
 	local newData = {}
 	for mode,modeData in ipairs(oldData) do
@@ -168,7 +180,7 @@
 					type = type,
 					detail = buttonData.Detail,
 				}
-			elseif type then
+			elseif not KnownOldObjectTypes[type] then
 				-- maybe it's an item type
 				local id = buttonData.Detail
 				local class = select(6, GetItemInfo(id)) -- :NOTE: this may fail if the item is not yet in the cache
@@ -187,6 +199,102 @@
 	return newData
 end
 
+------------------------------------------------------------------------------
+
+local PreloadFrame
+local step_timeout = 1
+local total_timeout = 15
+
+local function PreloadFrameUpdate(self, dt)
+	self.step_timeout = self.step_timeout - dt
+	self.total_timeout = self.total_timeout - dt
+	if self.step_timeout < 0 then
+		local items,pets = 0,0
+		-- check items
+		for itemID in pairs(self.itemIDs) do
+			if GetItemInfo(itemID) then
+				self.itemIDs[itemID] = nil
+			else
+				items = items + 1
+			end
+		end
+		-- check pets
+		for petID in pairs(self.petIDs) do
+			if C_PetJournal.GetPetInfoByPetID(petID) then
+				self.petIDs[petID] = nil
+			else
+				pets = pets + 1
+			end
+		end
+		CyborgMMO_DPrint("PreloadFrameUpdate step", self.total_timeout, "items:", items, "pets:", pets)
+		if self.total_timeout < 0 or next(self.itemIDs)==nil and next(self.petIDs)==nil then
+			-- when done destroy the frame and throw an event for further loading
+			self:Hide()
+			self:SetParent(nil)
+			PreloadFrame = nil
+			CyborgMMO_Event(nil, "CYBORGMMO_ASYNC_DATA_LOADED")
+		else
+			self.step_timeout = step_timeout
+		end
+	end
+end
+
+function PreLoad(data)
+	-- create ID sets to sync
+	local itemIDs = {}
+	local petIDs = {}
+	
+	-- gather all needed IDs (and trigger sync while doing so)
+	if data.Rat then
+		for mode=1,RAT7.MODES do
+			for button=1,RAT7.BUTTONS do
+				local data = data.Rat[mode][button]
+				if data then
+					if data.type=='item' then
+						local itemID = data.detail
+						if not GetItemInfo(itemID) then
+							itemIDs[itemID] = true
+						end
+					elseif data.type=='battlepet' then
+						local petID = data.detail
+						if not C_PetJournal.GetPetInfoByPetID(petID) then
+							petIDs[petID] = true
+						end
+					end
+				end
+			end
+		end
+	end
+	-- gather IDs from old unconverted data (in case we need to convert it)
+	if data[SaveName] and data[SaveName].Rat then
+		for mode=1,RAT7.MODES do
+			for button=1,RAT7.BUTTONS do
+				local data = data[SaveName].Rat[mode][button]
+				if data then
+					-- items actually had their class overwrite the Type field
+					if not KnownOldObjectTypes[data.Type] and type(data.Detail)=='number' then
+						local itemID = data.Detail
+						if not GetItemInfo(itemID) then
+							itemIDs[itemID] = true
+						end
+					end
+				end
+			end
+		end
+	end
+	
+	-- create frame for regular updates
+	PreloadFrame = CreateFrame("Frame")
+	PreloadFrame.itemIDs = itemIDs
+	PreloadFrame.petIDs = petIDs
+	PreloadFrame.total_timeout = total_timeout
+	PreloadFrame.step_timeout = step_timeout
+	PreloadFrame:SetScript("OnUpdate", PreloadFrameUpdate)
+	PreloadFrame:Show()
+end
+
+------------------------------------------------------------------------------
+
 function CyborgMMO_Event(self, event, ...)
 	if event == "VARIABLES_LOADED" then
 		VarsLoaded = true
@@ -194,6 +302,9 @@
 		if not CyborgMMO7SaveData then
 			CyborgMMO7SaveData = {}
 		end
+		PreLoad(CyborgMMO7SaveData)
+	elseif event == "CYBORGMMO_ASYNC_DATA_LOADED" then
+		AsyncDataLoaded = true
 		-- convert old profile
 		if CyborgMMO7SaveData[SaveName] and not CyborgMMO7SaveData.Settings then
 			local oldData = CyborgMMO7SaveData[SaveName]
@@ -211,7 +322,7 @@
 	end
 
 	-- Fire Loading if and only if the player is in the world and vars are loaded
-	if not BindingsLoaded and VarsLoaded and EnteredWorld then
+	if not BindingsLoaded and VarsLoaded and AsyncDataLoaded and EnteredWorld then
 		local data = CyborgMMO_GetSaveData()
 
 		CyborgMMO_RatPageModel:LoadData()
@@ -241,8 +352,6 @@
 
 		local xmin,ymin = Minimap:GetLeft(),Minimap:GetBottom()
 		CyborgMMO_MiniMapButtonReposition(math.deg(math.atan2(ymin, xmin)))
-		-- Close the main window for now
-		CyborgMMO_Close()
 	end
 end
 
--- a/MainPage.xml	Thu Apr 25 18:16:03 2013 +0000
+++ b/MainPage.xml	Thu Apr 25 23:02:39 2013 +0000
@@ -40,7 +40,7 @@
 	</Button>
 
 	<!-- The Main Form -->
-	<Frame name="CyborgMMO_MainPage" movable="true" enableMouse="true" clampedtoscreen="true" frameStrata="MEDIUM">
+	<Frame name="CyborgMMO_MainPage" movable="true" enableMouse="true" clampedtoscreen="true" frameStrata="MEDIUM" hidden="true">
 		<TitleRegion>
 			<Size x="512" y="512"/>
 			<Anchors>