Thread Tools Display Modes
04-24-17, 11:17 AM   #1
loff93
A Fallenroot Satyr
Join Date: Apr 2017
Posts: 25
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!
  Reply With Quote
04-24-17, 01:22 PM   #2
jeruku
A Cobalt Mageweaver
 
jeruku's Avatar
AddOn Author - Click to view addons
Join Date: Oct 2010
Posts: 223
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.
__________________
"I have not failed, I simply found 10,000 ways that did not work." - Thomas Edison
  Reply With Quote
04-24-17, 01:45 PM   #3
loff93
A Fallenroot Satyr
Join Date: Apr 2017
Posts: 25
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.
  Reply With Quote
04-24-17, 02:43 PM   #4
Seerah
Fishing Trainer
 
Seerah's Avatar
WoWInterface Super Mod
Featured
Join Date: Oct 2006
Posts: 10,860
Anything beyond what jeruku said will require you to show your code to find out why you're not getting the behavior you want.
__________________
"You'd be surprised how many people violate this simple principle every day of their lives and try to fit square pegs into round holes, ignoring the clear reality that Things Are As They Are." -Benjamin Hoff, The Tao of Pooh

  Reply With Quote
04-24-17, 03:17 PM   #5
Banknorris
A Chromatic Dragonspawn
 
Banknorris's Avatar
AddOn Author - Click to view addons
Join Date: Oct 2014
Posts: 153
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.
__________________
"In this world nothing can be said to be certain, except that fractional reserve banking is a Ponzi scheme and that you won't believe it." - Mandrill

Last edited by Banknorris : 11-20-17 at 01:47 PM.
  Reply With Quote
04-25-17, 04:17 AM   #6
loff93
A Fallenroot Satyr
Join Date: Apr 2017
Posts: 25
Originally Posted by Banknorris View Post
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.
  Reply With Quote
04-25-17, 06:44 AM   #7
jeruku
A Cobalt Mageweaver
 
jeruku's Avatar
AddOn Author - Click to view addons
Join Date: Oct 2010
Posts: 223
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')
__________________
"I have not failed, I simply found 10,000 ways that did not work." - Thomas Edison

Last edited by jeruku : 04-25-17 at 06:53 AM.
  Reply With Quote
04-25-17, 06:54 AM   #8
loff93
A Fallenroot Satyr
Join Date: Apr 2017
Posts: 25
Originally Posted by jeruku View Post
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
  Reply With Quote
04-25-17, 12:00 PM   #9
Banknorris
A Chromatic Dragonspawn
 
Banknorris's Avatar
AddOn Author - Click to view addons
Join Date: Oct 2014
Posts: 153
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.
__________________
"In this world nothing can be said to be certain, except that fractional reserve banking is a Ponzi scheme and that you won't believe it." - Mandrill
  Reply With Quote
04-25-17, 02:41 PM   #10
loff93
A Fallenroot Satyr
Join Date: Apr 2017
Posts: 25
Originally Posted by Banknorris View Post
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
  Reply With Quote
04-25-17, 03:06 PM   #11
Banknorris
A Chromatic Dragonspawn
 
Banknorris's Avatar
AddOn Author - Click to view addons
Join Date: Oct 2014
Posts: 153
Originally Posted by loff93 View Post
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
__________________
"In this world nothing can be said to be certain, except that fractional reserve banking is a Ponzi scheme and that you won't believe it." - Mandrill
  Reply With Quote
04-27-17, 08:48 AM   #12
loff93
A Fallenroot Satyr
Join Date: Apr 2017
Posts: 25
Originally Posted by Banknorris View Post
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?

Last edited by loff93 : 04-27-17 at 09:06 AM.
  Reply With Quote
04-27-17, 02:58 PM   #13
Seerah
Fishing Trainer
 
Seerah's Avatar
WoWInterface Super Mod
Featured
Join Date: Oct 2006
Posts: 10,860
How **exactly** are you trying to use the function?
__________________
"You'd be surprised how many people violate this simple principle every day of their lives and try to fit square pegs into round holes, ignoring the clear reality that Things Are As They Are." -Benjamin Hoff, The Tao of Pooh

  Reply With Quote
04-28-17, 07:42 AM   #14
Kakjens
A Cliff Giant
Join Date: Apr 2017
Posts: 75
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)

Last edited by Kakjens : 04-30-17 at 07:02 PM. Reason: Fixed typp.
  Reply With Quote
04-30-17, 07:42 AM   #15
loff93
A Fallenroot Satyr
Join Date: Apr 2017
Posts: 25
Thumbs up

Originally Posted by Kakjens View Post
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!
  Reply With Quote
04-30-17, 03:16 PM   #16
Ketho
A Pyroguard Emberseer
 
Ketho's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2010
Posts: 1,026
Is it me or are you consistently misspelling GET_ITEM_INFO_RECEIVED as GET_ITEM_INFO_RECIEVED
  Reply With Quote
05-01-17, 01:01 AM   #17
loff93
A Fallenroot Satyr
Join Date: Apr 2017
Posts: 25
Originally Posted by Ketho View Post
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 ^^
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » WoW LUA - cache issue

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off