Thread Tools Display Modes
05-16-13, 10:40 PM   #1
gmarco
An Onyxian Warder
 
gmarco's Avatar
AddOn Author - Click to view addons
Join Date: Dec 2009
Posts: 362
LDB initialization.

I was used to have tekability as my default LDB durability feeder.
Tekability also put the durability value inside the char frame slots. It is a nice features, but:
1) I don't use so much because I usually have autorepair and so I often repair all the items.
2) it conflicts with other addon that write on the same char slots :-)

So I decided to write my minimalist LDB durability feeder (mydurability). It does only the LDB part and show the minimum durability value.

Now the question after all the p.r things :-)

I used this code:

Lua Code:
  1. local ldb = LibStub:GetLibrary("LibDataBroker-1.1")
  2. local dataobj = ldb:NewDataObject("MyDurability", {
  3.     type = "data source",
  4.     icon = "Interface\\Minimap\\Tracking\\Repair",
  5.     text = "100%",
  6. })

but I don't include external libraries to my addon itself thinking that these libraries ( es: LibDataBroker-1.1 and CallbackHandler-1.0.lua ) should be provided by the LDB display manager.

Is this a correct assumption ?

P.s.
The addon works fine ... :-)

The code for any welcome review is:

Lua Code:
  1. local ADDON = ...
  2.  
  3. local math_min = math.min
  4. local string_format = string.format
  5. local prgname = "mydurability"
  6. local perc
  7. local format_color = "|cff%02x%02x%02x%s"
  8.  
  9. local slots = {
  10.    "HeadSlot",
  11.    "ShoulderSlot",
  12.    "ChestSlot",
  13.    "WristSlot",
  14.    "HandsSlot",
  15.    "WaistSlot",
  16.    "LegsSlot",
  17.    "FeetSlot",
  18.    "MainHandSlot",
  19.    "SecondaryHandSlot",
  20. }
  21.  
  22. local text_color = {
  23.     {0,1,0},
  24.     {1,1,0},
  25.     {1,0.5,0},
  26.     {1,0,0},
  27. }
  28.  
  29. local ldb = LibStub:GetLibrary("LibDataBroker-1.1")
  30. local dataobj = ldb:NewDataObject("MyDurability", {
  31.     type = "data source",
  32.     icon = "Interface\\Minimap\\Tracking\\Repair",
  33.     text = "100%",
  34. })
  35.  
  36. local frame_md = CreateFrame("Frame", ADDON.."_LDB")
  37. frame_md:RegisterEvent("UPDATE_INVENTORY_DURABILITY")
  38.  
  39. frame_md:SetScript("OnEvent", function(self, event, ...)
  40.    
  41.     local mindurability = 1
  42.  
  43.     for i=1, #slots do
  44.        local slotid = GetInventorySlotInfo(slots[i])
  45.        local durability, maxdurability = GetInventoryItemDurability(slotid)  
  46.        if durability and maxdurability and maxdurability ~= 0 then
  47.           mindurability = math_min(durability/maxdurability, mindurability)      
  48.        end
  49.     end
  50.    
  51.     if     mindurability >= 0  and  mindurability < 0.25   then perc = 4
  52.     elseif mindurability >= 0.25 and  mindurability < 0.50   then perc = 3
  53.     elseif mindurability >= 0.50 and  mindurability < 0.75   then perc = 2
  54.     elseif mindurability >= 0.75 and mindurability <= 1 then perc = 1
  55.     end
  56.    
  57.     dataobj.text = string_format(format_color, text_color[perc][1]*255, text_color[perc][2]*255, text_color[perc][3]*255, string_format("%d%%",mindurability*100)).."|r"
  58.  
  59. end
  60. )

Thanks anyone for attention
__________________
This is Unix-Land. In quiet nights, you can hear the Windows machines reboot.

Last edited by gmarco : 05-16-13 at 11:21 PM.
  Reply With Quote
05-17-13, 02:15 AM   #2
gmarco
An Onyxian Warder
 
gmarco's Avatar
AddOn Author - Click to view addons
Join Date: Dec 2009
Posts: 362
A little bit more complete :-)

Lua Code:
  1. local ADDON = ...
  2.  
  3. local math_min = math.min
  4. local string_format = string.format
  5. local string_gsub = string.gsub
  6. local table_insert = table.insert
  7. local prgname = "mydurability"
  8. local idx, perc
  9. local format_color = "|cff%02x%02x%02x%s"
  10.  
  11. local durabilities = {}
  12.  
  13. local slots = {
  14.    "HeadSlot",
  15.    "ShoulderSlot",
  16.    "ChestSlot",
  17.    "WristSlot",
  18.    "HandsSlot",
  19.    "WaistSlot",
  20.    "LegsSlot",
  21.    "FeetSlot",
  22.    "MainHandSlot",
  23.    "SecondaryHandSlot",
  24. }
  25.  
  26. local text_color = {
  27.     {0,1,0},
  28.     {1,1,0},
  29.     {1,0.5,0},
  30.     {1,0,0},
  31. }
  32.  
  33. local ldb = LibStub:GetLibrary("LibDataBroker-1.1")
  34. local dataobj = ldb:NewDataObject("MyDurability", {
  35.     type = "data source",
  36.     icon = "Interface\\Minimap\\Tracking\\Repair",
  37.     text = "100%",
  38. })
  39.  
  40. local frame_md = CreateFrame("Frame", ADDON.."_LDB")
  41. frame_md:RegisterEvent("UPDATE_INVENTORY_DURABILITY")
  42. frame_md:SetScript("OnEvent", function(self, event, ...)
  43.    
  44.     local mindurability = 1
  45.     durabilities = {}
  46.    
  47.     for idx=1, #slots do
  48.         local slotid = GetInventorySlotInfo(slots[idx])
  49.         local durability, maxdurability = GetInventoryItemDurability(slotid)  
  50.         if durability and maxdurability and maxdurability ~= 0 then
  51.             table_insert(durabilities, tostring(string_format("%d", (durability/maxdurability)*100)))
  52.             mindurability = math_min(durability/maxdurability, mindurability)        
  53.         end
  54.     end
  55.    
  56.     if     mindurability >= 0  and  mindurability < 0.25   then perc = 4
  57.     elseif mindurability >= 0.25 and  mindurability < 0.50   then perc = 3
  58.     elseif mindurability >= 0.50 and  mindurability < 0.75   then perc = 2
  59.     elseif mindurability >= 0.75 and mindurability <= 1 then perc = 1
  60.     end
  61.    
  62.     dataobj.text = string_format(format_color, text_color[perc][1]*255, text_color[perc][2]*255, text_color[perc][3]*255, string_format("%d%%",mindurability*100)).."|r"
  63.  
  64. end
  65. )
  66.  
  67. function dataobj:OnEnter()
  68.     GameTooltip:SetOwner(self, "ANCHOR_NONE")
  69.     GameTooltip:SetPoint("TOPLEFT", self, "BOTTOMLEFT")
  70.     GameTooltip:ClearLines()
  71.     dataobj.OnTooltipShow(GameTooltip)
  72.     GameTooltip:Show()
  73. end
  74.  
  75. function dataobj:OnTooltipShow()
  76.     -- GameTooltip:AddLine(prgname .. " v" .. GetAddOnMetadata(prgname, "Version"))
  77.     GameTooltip:AddLine(prgname)
  78.     GameTooltip:AddLine(" ")
  79.     for idx=1, #slots do
  80.         if durabilities[idx] then
  81.             GameTooltip:AddDoubleLine(string_gsub(slots[idx],"Slot",""), durabilities[idx],1,1,1, 1,1,1)
  82.         end
  83.     end
  84. end
  85.  
  86. function dataobj:OnLeave()
  87.     GameTooltip:Hide()
  88. end
__________________
This is Unix-Land. In quiet nights, you can hear the Windows machines reboot.

Last edited by gmarco : 05-17-13 at 02:30 AM.
  Reply With Quote
05-17-13, 08:35 AM   #3
Rilgamon
Premium Member
 
Rilgamon's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Sep 2009
Posts: 822
Every library your addon needs should be included or your toc should have them listed as standalone requirements. You cant make sure that your addon is loaded after the broker display addon (I tried it ... thats why my broker addons start with zz_ ).
__________________
The cataclysm broke the world ... and the pandas could not fix it!
  Reply With Quote
05-17-13, 09:31 AM   #4
gmarco
An Onyxian Warder
 
gmarco's Avatar
AddOn Author - Click to view addons
Join Date: Dec 2009
Posts: 362
Hi Rilgamon,

I imagined this thing, but after a few tries with different broker display (only 2 addons, a display and mine) it always works even if my addon was loaded before.
I am saying this thinking the addon are loaded in alpha order, so MyDurability is loaded before TitanPanel for example :-)

If there is no broker display I have no output (obviusly) but also no error :-)

Btw it is not a problem to include the 3 libs in the toc and in the addon itself ... It was more a curiosity to know how it should be setup :-)

P.s.
I saw your addons a lot of times and I always tried to figure why their name begin with zz_ :-))

Thanks for your reply.
__________________
This is Unix-Land. In quiet nights, you can hear the Windows machines reboot.
  Reply With Quote
05-17-13, 10:03 AM   #5
myrroddin
A Pyroguard Emberseer
 
myrroddin's Avatar
AddOn Author - Click to view addons
Join Date: Oct 2008
Posts: 1,240
Originally Posted by gmarco View Post
but I don't include external libraries to my addon itself thinking that these libraries ( es: LibDataBroker-1.1 and CallbackHandler-1.0.lua ) should be provided by the LDB display manager.

Is this a correct assumption ?
Incorrect, for two reasons: you are making an assumption that a different author has done his or her job correctly, which by not bundling required libraries, you are not doing your job correctly, thus creating your own problem; the other reason is that if your Broker plugin requires those libraries, then you should include them as standard practice, after all, they are required.
  Reply With Quote
05-17-13, 12:16 PM   #6
gmarco
An Onyxian Warder
 
gmarco's Avatar
AddOn Author - Click to view addons
Join Date: Dec 2009
Posts: 362
Originally Posted by myrroddin View Post
Incorrect, for two reasons: you are making an assumption that a different author has done his or her job correctly, which by not bundling required libraries, you are not doing your job correctly, thus creating your own problem; the other reason is that if your Broker plugin requires those libraries, then you should include them as standard practice, after all, they are required.
Hi myrroddin,
thanks for the reply. As stated above I already suppose that I should include those libs (and I did in the final addon package as published).

Just to explain why I wrote that question...
My thoughts about not including them were: if my addon need (like all others LDB addons those 3 libs) it should logical that only the broker display load them for all the addons that use the display (it is mandatory otherwhise the addons don't work at all) and those libs too. But as pointed out by Rilgamon it can happens (and surely happens :-) that there is a load order problem. If the display broker is loaded after the addon without libs probably this fails to load.

Btw I have learned that is not important who loads the libs ... the important thing is that those libs will go in memory for all :-)

Thanks again for your answer again.
__________________
This is Unix-Land. In quiet nights, you can hear the Windows machines reboot.
  Reply With Quote
05-17-13, 12:26 PM   #7
ravagernl
Proceritate Corporis
Premium Member
AddOn Author - Click to view addons
Join Date: Feb 2006
Posts: 1,176
Originally Posted by gmarco View Post
Hi myrroddin,
thanks for the reply. As stated above I already suppose that I should include those libs (and I did in the final addon package as published).

Just to explain why I wrote that question...
My thoughts about not including them were: if my addon need (like all others LDB addons those 3 libs) it should logical that only the broker display load them for all the addons that use the display (it is mandatory otherwhise the addons don't work at all) and those libs too. But as pointed out by Rilgamon it can happens (and surely happens :-) that there is a load order problem. If the display broker is loaded after the addon without libs probably this fails to load.

Btw I have learned that is not important who loads the libs ... the important thing is that those libs will go in memory for all :-)

Thanks again for your answer again.
LibStub makes sure only one copy of every different library stays in memory by using version checking. If a libstub library is loaded, the lib checks if LibStub has the same version or a newer version of the same library. In that case, the script uses the language construct "return" to exit the script, so there is no script being run. This will affect loading times a little, but not by much.

If you include a LibStub library, you have to set the library in the OptDeps field in the toc when the library can be installed standalone (like people downloading Ace libraries through the curse client). This way, you can make sure the standalone library is not being loaded after your addon.

More info: http://www.wowace.com/addons/libstub/

This is why both data source display addons and data source addons should both include LibDataBroker.

Last edited by ravagernl : 05-17-13 at 12:33 PM.
  Reply With Quote
05-18-13, 01:34 AM   #8
gmarco
An Onyxian Warder
 
gmarco's Avatar
AddOn Author - Click to view addons
Join Date: Dec 2009
Posts: 362
After having understood the library problem I'd like to ask another thing if possible.

I am doing 2 different for cycle, one to find the min durability and one to fill the gametooltip.

I have tried to use only a cycle in this way:

Lua Code:
  1. for idx=1, #slots do
  2.  
  3.         local slotid = GetInventorySlotInfo(slots[idx])
  4.  
  5.         local durability, maxdurability = GetInventoryItemDurability(slotid)  
  6.  
  7.         if durability and maxdurability and maxdurability ~= 0 then
  8.            
  9.             GameTooltip:AddDoubleLine(string_gsub(slots[idx],"Slot",""), tostring(string_format("%d", (durability/maxdurability)*100)))
  10.             -- table_insert(durabilities, tostring(string_format("%d", (durability/maxdurability)*100)))
  11.  
  12.             mindurability = math_min(durability/maxdurability, mindurability)        
  13.  
  14.         end
  15.  
  16.     end
  17.  
  18.    
  19.  
  20.     if     mindurability >= 0  and  mindurability < 0.25   then perc = 4
  21.  
  22.     elseif mindurability >= 0.25 and  mindurability < 0.50   then perc = 3
  23.  
  24.     elseif mindurability >= 0.50 and  mindurability < 0.75   then perc = 2
  25.  
  26.     elseif mindurability >= 0.75 and mindurability <= 1 then perc = 1
  27.  
  28.     end
  29.  
  30.    
  31.  
  32.     dataobj.text = string_format(format_color, text_color[perc][1]*255, text_color[perc][2]*255, text_color[perc][3]*255, string_format("%d%%",mindurability*100)).."|r"

to fill the gametooltip while I am finding the min value, thinking that I can fill the tooltip and later only call the hide and show to manage it on the enter/leave event.

But it does not work and so I found the solution to fill a table of durabilities while looking for the min durability cycle and then used another cycle on the slots and durabilities table to fill the tooltip on event.

Any clues ?

Thanks very much to everyone for attention.
__________________
This is Unix-Land. In quiet nights, you can hear the Windows machines reboot.
  Reply With Quote
05-18-13, 03:23 AM   #9
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
Your one-loop method does not work because the GameTooltip is used by many addons and many parts of the default UI. Every time something else shows the GameTooltip, its previous contents are erased, so you cannot add something to the tooltip and expect it to still be there 5 minutes later after the tooltip has been shown and hidden 742 times for units, items, quests, spells, and dozens of other things.

However, since the tooltip is not shown frequently, and is probably never shown in speed-critical situations, I wouldn't even bother with keeping a table of durability values; just ask for them again when the user requests a tooltip.

Here is a 90-second strip-down of tekability that only does the Broker stuff:
Code:
local SLOTIDS, SLOTS = {}, { "Head", "Shoulder", "Chest", "Waist", "Legs", "Feet", "Wrist", "Hands", "MainHand", "SecondaryHand" }
for _, slot in pairs(SLOTS) do
	SLOTIDS[slot] = GetInventorySlotInfo(slot .. "Slot")
end

local dataobj = LibStub("LibDataBroker-1.1"):NewDataObject("Durability", {
	type = "data source",
	icon = "Interface\\Minimap\\Tracking\\Repair",
	text = "100%",
	OnTooltipShow = function(tooltip)
		tooltip:AddLine("Durability", 1, 1, 1)
		for slot, id in pairs(SLOTIDS) do
			local v1, v2 = GetInventoryItemDurability(id)
			if v1 and v2 and v2 ~= 0 then
				local val = string.format("%d%%", v1/v2*100)
				tooltip:AddDoubleLine(slot, val, nil, nil, nil, GetGradientColor(v1 / v2))
			end
		end
		tooltip:Show()
	end,
})

local function GetGradientColor(perc)
	local relperc = perc * 2 % 1
	if perc <= 0 then
		return 1, 0, 0
	elseif perc < 0.5 then
		return 1, relperc, 0
	elseif perc == 0.5 then
		return 1, 1, 0
	elseif perc < 1.0 then
		return 1 - relperc, 1, 0
	else
		return 0, 1, 0
	end
end

local frame = CreateFrame("Frame")
frame:RegisterEvent("UPDATE_INVENTORY_DURABILITY")
frame:SetScript("OnEvent", function()
	local min = 1
	for _, slot in ipairs(SLOTDS) do
		local v1, v2 = GetInventoryItemDurability(SLOTIDS[slot])
		if v1 and v2 and v2 ~= 0 then
			min = math.min(v1/v2, min)
		end
	end

	local r, g, b = GetGradientColor(min)
	dataobj.text = string.format("|cff%02x%02x%02x%d%%", r * 255, g * 255, b * 255, min * 100)
end
__________________
Retired author of too many addons.
Message me if you're interested in taking over one of my addons.
Don’t message me about addon bugs or programming questions.
  Reply With Quote
05-18-13, 02:58 PM   #10
gmarco
An Onyxian Warder
 
gmarco's Avatar
AddOn Author - Click to view addons
Join Date: Dec 2009
Posts: 362
Originally Posted by Phanx View Post
Your one-loop method does not work because the GameTooltip is used by many addons and many parts of the default UI.
Aargh ... and I that I thought it was only mine :-)

Btw thanks again Phanx. You are amazing as always ... now I'll check your code and try to use it on my addon to perfect it.
__________________
This is Unix-Land. In quiet nights, you can hear the Windows machines reboot.
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » LDB initialization.


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