WoWInterface

WoWInterface (https://www.wowinterface.com/forums/index.php)
-   Lua/XML Help (https://www.wowinterface.com/forums/forumdisplay.php?f=16)
-   -   WoW LUA - cache issue (https://www.wowinterface.com/forums/showthread.php?t=55352)

loff93 04-24-17 11:17 AM

WoW LUA - cache issue
 
Hello!

Just started working with lua and WoW addons. It's pretty fun and I have already made some simple addons.
My only issue so far is the cache. When the items I try to use is not in the local cache and I end up getting errors. How can I manage to get the item info right away, to avoid GetItemInfo(id) being equal to "nil" unless I already have it in cache?
I'm pretty new to lua even if I have worked with programming so try to explain it in a simple way if possible.

Thanks!

jeruku 04-24-17 01:22 PM

The first time you call it it is either a disk and/or network request. Calling it with an itemID that is not currently cached will then eventually trigger the event GET_ITEM_INFO_RECEIVED indicating that the item is now cached, calling it any time after that will return properly.

loff93 04-24-17 01:45 PM

yeah I figured that so I made a update that checks if the status has changed from nil to the correct value then allowing user to actually open the addon. However, this isn't good enough for me, it takes between 1-20 seconds before I can open the addon. I don't believe other addons does it like this. For example atlas loot would take ages compared to my little script if they did what I do.

Seerah 04-24-17 02:43 PM

Anything beyond what jeruku said will require you to show your code to find out why you're not getting the behavior you want.

Banknorris 04-24-17 03:17 PM

1) You call GetItemInfo(item_id) to get item information if it is available or otherwise to force the item to be cached.
2) If you get a nil then register for event GET_ITEM_INFO_RECEIVED if not nil then you can just use the returned information already
3) When the item is ready (which should happen very quickly) you will get a GET_ITEM_INFO_RECEIVED with arg1 equal to the item_id
4) You can call GetItemInfo(item_id) now (from the event handler) and the infor will be available.

loff93 04-25-17 04:17 AM

Quote:

Originally Posted by Banknorris (Post 323040)
1) You call GetItemInfo(item_id) to force the item to be cached, otherwise it can really take a lot of time for the item to be cached.
2) If you get a null then register for event GET_ITEM_INFO_RECEIVED if not then you can just use the returned information already
3) When the item is ready (which should happen very quickly) you will get a GET_ITEM_INFO_RECEIVED with arg1 equal to the item_id
4) You can call GetItemInfo(item_id) now

Nice, thanks.
How can I use "GET_ITEM_INFO_RECEIVED" to trigger an event however? Assume I can't use it like:
function GET_ITEM_INFO_RECEIVED(Item_ID)()
-- stuff
end

Will play around with it when I get home from Uni.

jeruku 04-25-17 06:44 AM

Quick and dirty example.

Lua Code:
  1. local frame = CreateFrame('Frame')
  2. local tab = {}
  3. local wait = {}
  4.  
  5. frame:SetScript('OnEvent', function(self, event, ...)
  6.    if event == 'BAG_UPDATE_DELAYED' then
  7.       -- do checks and stuff and get the desired itemID
  8.       local name, link, quality, iLevel, reqLevel, class, subclass, maxStack, equipSlot, texture, vendorPrice = GetItemInfo(itemID)
  9.       if not name then
  10.         wait[itemID] = {}
  11.      else
  12.         -- this may just create a library so you may have to put them in individually with something like tinsert(tab[itemID], name)...
  13.         tab[itemID] = {name, link, quality, iLevel, reqLevel, class, subclass, maxStack, equipSlot, texture, vendorPrice}
  14.      end
  15.    elseif event == 'GET_ITEM_INFO_RECIEVED' then
  16.       -- the info is now downloaded and cached
  17.       local itemID = ...
  18.       if wait[itemID] then
  19.          tab[itemID] = {GetItemInfo(itemID)}
  20.          wait[itemID] = nil
  21.       end
  22.    end
  23. end
  24.  
  25. frame:RegisterEvent('BAG_UPDATE_DELAYED')
  26. frame:RegisterEvent('GET_ITEM_INFO_RECIEVED')

loff93 04-25-17 06:54 AM

Quote:

Originally Posted by jeruku (Post 323061)
Quick and dirty example.

Lua Code:
  1. local frame = CreateFrame('Frame')
  2. local tab = {}
  3. local wait = {}
  4.  
  5. frame:SetScript('OnEvent', function(self, event, ...)
  6.    if event == 'BAG_UPDATE_DELAYED' then
  7.       -- do checks and stuff and get the desired itemID
  8.       local name, link, quality, iLevel, reqLevel, class, subclass, maxStack, equipSlot, texture, vendorPrice = GetItemInfo(itemID)
  9.       if not name then
  10.         wait[itemID] = {}
  11.      else
  12.         -- this may just create a library so you may have to put them in individually with something like tinsert(tab[itemID], name)...
  13.         tab[itemID] = {name, link, quality, iLevel, reqLevel, class, subclass, maxStack, equipSlot, texture, vendorPrice}
  14.      end
  15.    elseif event == 'GET_ITEM_INFO_RECIEVED' then
  16.       -- the info is now downloaded and cached
  17.       local itemID = ...
  18.       if wait[itemID] then
  19.          tab[itemID] = {GetItemInfo(itemID)}
  20.          wait[itemID] = nil
  21.       end
  22.    end
  23. end
  24.  
  25. frame:RegisterEvent('BAG_UPDATE_DELAYED')
  26. frame:RegisterEvent('GET_ITEM_INFO_RECIEVED')

Cool, thanks for taking your time to help out.
Will test it when I get the chance :)

Banknorris 04-25-17 12:00 PM

Quote:

How can I use "GET_ITEM_INFO_RECEIVED" to trigger an event however?
A failled call (nil return) from GetItemInfo() will trigger GET_ITEM_INFO_RECEIVED after a little bit.

loff93 04-25-17 02:41 PM

Quote:

Originally Posted by Banknorris (Post 323067)
A failled call (nil return) from GetItemInfo() will trigger GET_ITEM_INFO_RECEIVED after a little bit.

Yeah I understood that but I ment like - when GET_ITEM_INFO_RECEIVED is triggered, it would be nice to make that one trigger another function I have if possible :)

Banknorris 04-25-17 03:06 PM

Quote:

Originally Posted by loff93 (Post 323076)
Yeah I understood that but I ment like - when GET_ITEM_INFO_RECEIVED is triggered, it would be nice to make that one trigger another function I have if possible :)

In Jeruku code lines 16-21 are just that. You could also call a funcion there like

Lua Code:
  1. elseif event == 'GET_ITEM_INFO_RECIEVED' then
  2.     local itemID = ...
  3.     --call your function here
  4. end

loff93 04-27-17 08:48 AM

Quote:

Originally Posted by Banknorris (Post 323077)
In Jeruku code lines 16-21 are just that. You could also call a funcion there like

Lua Code:
  1. elseif event == 'GET_ITEM_INFO_RECIEVED' then
  2.     local itemID = ...
  3.     --call your function here
  4. end

ah fair enough , had not looked too well into the scrip yet. Was going to study it when I had time to sit down with it.

I tried to make the script work but I get error from this line:
Code:

local name, link, quality, iLevel, reqLevel, class, subclass, maxStack, equipSlot, texture, vendorPrice = GetItemInfo(itemID)
Code:

Message: Interface\AddOns\Tore\main.lua:187: Usage: GetItemInfo(itemID|"name"|"itemlink")
Time: 04/27/17 16:56:26
Count: 1
Stack: [C]: in function `GetItemInfo'
Interface\AddOns\Tore\main.lua:187: in function <Interface\AddOns\Tore\main.lua:184>

Locals: (*temporary) = nil

Tried to pass a value/input like "felwort" or the ID but I guess I'm not doing it right as it says it's nil.

Extra: What script software do you guys use?

Seerah 04-27-17 02:58 PM

How **exactly** are you trying to use the function?

Kakjens 04-28-17 07:42 AM

Maybe a bit more understandable example:
Lua Code:
  1. local darkmoonflasks = {
  2.     [1] = 124642, --"Darkmoon Draught of Supremacy",
  3.     [2] = 124659, --"Darkmoon Tincture of Supremacy",
  4.     [3] = 124646, --"Darkmoon Draught of Flexibility",
  5.     [4] = 124658, --"Darkmoon Tincture of Flexibility",
  6.     [5] = 124645, --"Darkmoon Draught of Precision",
  7.     [6] = 124657, --"Darkmoon Tincture of Precision",
  8.     [7] = 124648, --"Darkmoon Draught of Divergence",
  9.     [8] = 124655, --"Darkmoon Tincture of Divergence",
  10.     [9] = 124647, --"Darkmoon Draught of Alacrity",
  11.     [10] = 124656, --"Darkmoon Tincture of Alacrity",
  12.     [11] = 124650, --"Darkmoon Draught of Deftness",
  13.     [12] = 124653, --"Darkmoon Tincture of Deftness",
  14.     [13] = 124651, --"Darkmoon Draught of Deflection",
  15.     [14] = 124652, --"Darkmoon Tincture of Deflection",
  16.     [15] = 124649, --"Darkmoon Draught of Defense",
  17.     [16] = 124654, --"Darkmoon Tincture of Defense",
  18. }
  19.  
  20. local numFlasks = #darkmoonFlasks
  21. local function do_something(itemID)
  22.     --put here code what you want to do with the item
  23.     print(itemID)
  24. end
  25.  
  26. local wait = {}
  27. local cache_writer = CreateFrame('Frame')
  28. cache_writer:RegisterEvent('GET_ITEM_INFO_RECEIVED')
  29. cache_writer:SetScript('OnEvent', function(self, event, ...)
  30.     if event == 'GET_ITEM_INFO_RECEIVED' then
  31.         -- the info is now downloaded and cached
  32.         local itemID = ...
  33.         if wait[itemID] then
  34.             print("received",itemID)
  35.             do_something(itemID)
  36.             wait[itemID] = nil
  37.         end
  38.     end
  39. end)
  40.  
  41. local function normal_loop()
  42.     --using for instead of ipairs because want to preserve order
  43.     for index = 1, numFlasks, 1 do
  44.         local itemID = darkmoonFlasks[index]
  45.         local name = GetItemInfo(itemID)
  46.         if name then
  47.             do_something(itemID)
  48.         else
  49.             --add item to wait list
  50.             wait[itemID] = {}  
  51.         end
  52.     end
  53. end
  54.  
  55. local initframe = CreateFrame("Frame", "MyInitFrame", UIParent)
  56. initframe:RegisterEvent("PLAYER_LOGIN")
  57. initframe:SetScript("OnEvent", function(self, event, ...)
  58.     if event == "PLAYER_LOGIN" then
  59.         normal_loop()
  60.     end
  61. end)

loff93 04-30-17 07:42 AM

Quote:

Originally Posted by Kakjens (Post 323126)
Maybe a bit more understandable example:
Lua Code:
  1. local darkmoonflasks = {
  2.     [1] = 124642, --"Darkmoon Draught of Supremacy",
  3.     [2] = 124659, --"Darkmoon Tincture of Supremacy",
  4.     [3] = 124646, --"Darkmoon Draught of Flexibility",
  5.     [4] = 124658, --"Darkmoon Tincture of Flexibility",
  6.     [5] = 124645, --"Darkmoon Draught of Precision",
  7.     [6] = 124657, --"Darkmoon Tincture of Precision",
  8.     [7] = 124648, --"Darkmoon Draught of Divergence",
  9.     [8] = 124655, --"Darkmoon Tincture of Divergence",
  10.     [9] = 124647, --"Darkmoon Draught of Alacrity",
  11.     [10] = 124656, --"Darkmoon Tincture of Alacrity",
  12.     [11] = 124650, --"Darkmoon Draught of Deftness",
  13.     [12] = 124653, --"Darkmoon Tincture of Deftness",
  14.     [13] = 124651, --"Darkmoon Draught of Deflection",
  15.     [14] = 124652, --"Darkmoon Tincture of Deflection",
  16.     [15] = 124649, --"Darkmoon Draught of Defense",
  17.     [16] = 124654, --"Darkmoon Tincture of Defense",
  18. }
  19.  
  20. local numFlasks = #darkmoonFlasks
  21. local function do_something(itemID)
  22.     --put here code what you want to do with the item
  23.     print(itemID)
  24. end
  25.  
  26. local wait = {}
  27. local cache_writer = CreateFrame('Frame')
  28. cache_writer:RegisterEvent('GET_ITEM_INFO_RECIEVED')
  29. cache_writer:SetScript('OnEvent', function(self, event, ...)
  30.     if event == 'GET_ITEM_INFO_RECIEVED' then
  31.         -- the info is now downloaded and cached
  32.         local itemID = ...
  33.         if wait[itemID] then
  34.             print("received",itemID)
  35.             do_something(itemID)
  36.             wait[itemID] = nil
  37.         end
  38.     end
  39. end)
  40.  
  41. local function normal_loop()
  42.     --using for instead of ipairs because want to preserve order
  43.     for index = 1, numFlasks, 1 do
  44.         local itemID = darkmoonFlasks[index]
  45.         local name = GetItemInfo(itemID)
  46.         if name then
  47.             do_something(itemID)
  48.         else
  49.             --add item to wait list
  50.             wait[itemID] = {}  
  51.         end
  52.     end
  53. end
  54.  
  55. local initframe = CreateFrame("Frame", "MyInitFrame", UIParent)
  56. initframe:RegisterEvent("PLAYER_LOGIN")
  57. initframe:SetScript("OnEvent", function(self, event, ...)
  58.     if event == "PLAYER_LOGIN" then
  59.         normal_loop()
  60.     end
  61. end)

Awesome. Thanks!
By the way - thanks to everyone replying to the thread. Totally new to this language, wow addons and this forum and I'm overwhelmed by all the help and fast replies!

Ketho 04-30-17 03:16 PM

Is it me or are you consistently misspelling GET_ITEM_INFO_RECEIVED as GET_ITEM_INFO_RECIEVED

loff93 05-01-17 01:01 AM

Quote:

Originally Posted by Ketho (Post 323168)
Is it me or are you consistently misspelling GET_ITEM_INFO_RECEIVED as GET_ITEM_INFO_RECIEVED

haha I don't know. Thanks for the heads up at least ^^


All times are GMT -6. The time now is 05:37 AM.

vBulletin © 2024, Jelsoft Enterprises Ltd
© 2004 - 2022 MMOUI