TellMeWhen

TellMeWhen

24M Downloads

[CF 1285] Aura tracking branch (updated)

tmw-issue-import opened this issue ยท 8 comments

commented

New url for repository is here https://wow.curseforge.com/addons/tellmewhen/repositories/auratracker3/

Can you point me to where I could find in the source code the event handling for when a icon or condition is enabled/disabled/deleted or has the spell parameters changed?

Also, I saw another ticket about feral bleed strength, and wanted to share another library I wrote based on the aura tracking one that handles the logic for that: https://www.wowace.com/addons/libferalbleeds/


Posted by CurseForge user srobins6 | Imported from CurseForge issue #1285 | Raw

commented

When you ask for the event handling for those things, do you mean during configuration? The same with spell parameters - do you mean the "what to track" input in icon configuration?

I'm happy to help, but it might be more helpful if I knew what your end goal was in asking for this.


Posted by CurseForge user Cybeloras

commented

@Cybeloras: Go

Yes exactly this, when users are doing config of the spells that are being tracked.

I wrote my library so that it stops tracking anything that is no longer needed to be tracked, and then wipes all recorded data for that spell as soon as nothing needs it. Like if I called the library from libstub from both tellmewhen, and some other addon, and both of them told the library they wanted to track moonfires applied by the player, it would register both of those requests, and wouldn't stop tracking it until both sources requested it to.

And my overall goal is to replace the existing tellmewhen logic for all buff tracking with my library so that pandemic refreshes can be calculated without having redundant tracking.


Posted by CurseForge user srobins6

commented

If that's the case, then you don't want to be watching for when things happen during configuration. There are lots of things that this would miss. For example, a group's icons stop updating because the player switched to a spec that the group is configured to not be active with. Or, an icon is imported from an external source.

The best way to do this would be to listen for TMW_GLOBAL_UPDATE and unregister everything that TMW has requested when that happens. Then, as things get setup again, do your re-registration there.

For the aura percentage conditions, you should be doing that registration in the funcstr method on the condition, looking roughly like this:

funcstr = function(c)
		TMW.AuraTracker:Track(TMW:GetSpells(c.Name).First, "HELPFUL" .. (c.Checked and " PLAYER" or ""))
		
		return [[AuraDur(c.Unit, c.NameFirst, c.NameString, "HELPFUL]] .. (c.Checked and " PLAYER" or "") .. [[") c.Operator c.Level]]
	end,


Edited Aug 27, 2016

Posted by CurseForge user Cybeloras

commented

In regards to replacing all TMW's buff logic with your library, I can't say that I would be in favor of this. Tracking the percentage of auras should be fairly uncommon thing - just look at how long it took to get a request to put the functionality back in after I took it out. In most cases it isn't even needed since you can determine the 30% mark of the vast majority of things with a calculator.

1 year, 9 months, and 4 days passed between when I took these out and when I put them back in after I got a single request to do so. This suggests that basically nobody cared about these conditions in the first place. I don't think the minor performance impact of your library tracking these things individually is worth imposing the overhead of your library on the entirety of TMW, where buff tracking is already pretty well optimized.

A library for caching buff/debuff information isn't a new idea - it goes back at least as far as 2007: https://forums.wowace.com/showthread.php?t=15310. I've also written my own attempt at one of these libraries, but I eventually scrapped it when I realized how bad the overhead (both memory and CPU) was - there was effectively no performance gain. User taledin (from that 2007 thread) mentioned back in 2009 that work was under way on a LibUnitAura, but this is the only record that I can find of it, suggesting that this attempt also never saw the light of day once the issues with such a project were realized: http://infobot.rikers.org/%23wowace/20090905.html.gz

For cases like this where you need to determine information that isn't available through the API, a library is perhaps the right answer, but in the general case, it often adds more overhead than what it's worth.


Posted by CurseForge user Cybeloras

commented

@Cybeloras: Go

I didn't know about these previous attempts, and your points about performance concerns have swayed me. I'll limit the use of this to just the debuff/buff duration % conditions.


Posted by CurseForge user srobins6

commented

So I've boiled down the actual needed changes to tmw's code to this:

In the main TellMeWhen.lua file, just need to add this. I'm not really sure how to use libstub when it comes to optional dependencies, but if you do it that way instead, like it only loads the aura tracking library if it can find it but doesn't break tmw if it doesn't, the way I wrote the changes to the other file should just revert to your original functions.

TMW.AuraTracker = LibStub("LibAuraTracker-1.0"):New()

In the Core/Conditions/Categories/BuffsDebuffs.lua file, I modified the Env.AuraPercent function and added a new one called Env.AuraPandemicDur which is used in the anticipate function for the two percentage based conditions. Just replace "AuraDur" with "AuraPandemicDur" in those two anticipate functions.

Let me know if you need any more info from me, or want me to do anything else to make this better for adding to tellmewhen. Thanks!

function Env.AuraPandemicDur(unit, name, nameString, filter) local isID = isNumber[name] local spell = isID or nameString local dur, actualDuration, expirationTime = Env.AuraDur(unit, name, nameString, filter) local duration = (TMW.AuraTracker and TMW.AuraTracker:AuraPandemic(unit, spell, nil, filter)) or actualDuration return dur, duration, expirationTime end

function Env.AuraPercent(unit, name, nameString, filter) local isID = isNumber[name] local spell = isID or nameString if TMW.AuraTracker then TMW.AuraTracker:Track(spell, filter) end local dur, actualDuration, expirationTime = Env.AuraDur(unit, name, nameString, filter) local percent = TMW.AuraTracker and TMW.AuraTracker:AuraPercent(unit, spell, filter) or expirationTime == 0 and 1 or ((expirationTime - TMW.time) / actualDuration) return percent end


Posted by CurseForge user srobins6

commented

While I appreciate the work you did on this, I don't think I'll be implementing it into TMW.

 

However, you're welcome to release it as a plugin to TMW.

 

All you would need to do is register your own conditions that use your functions instead of the default ones that TMW uses.

Add a dependency of TMW to your .toc file, and then in your addon's code, add the following:

 

 

if not TMW then return end

local TMW = TMW
local L = TMW.L

local CNDT = TMW.CNDT
local Env = CNDT.Env
local isNumber = TMW.isNumber
local strlowerCache = TMW.strlowerCache
local huge = math.huge

local UnitAura = UnitAura


function Env.AuraPandemicDur(unit, name, nameString, filter)
    local isID = isNumber[name]
    local spell = isID or nameString
    local dur, actualDuration, expirationTime = Env.AuraDur(unit, name, nameString, filter)
    local duration = (TMW.AuraTracker and TMW.AuraTracker:AuraPandemic(unit, spell, nil, filter)) or actualDuration
    return dur, duration, expirationTime
end

function Env.AuraPandemicPercent(unit, name, nameString, filter)
	local isID = isNumber[name]
    local spell = isID or nameString
    TMW.AuraTracker:Track(spell, filter)
    local dur, actualDuration, expirationTime = Env.AuraDur(unit, name, nameString, filter)
    local percent = TMW.AuraTracker and TMW.AuraTracker:AuraPercent(unit, spell, filter) or expirationTime == 0 and 1 or ((expirationTime - TMW.time) / actualDuration)
    return percent
end

ConditionCategory:RegisterCondition(2.5, "BUFFPERCPANDEMIC", {
	text = L["ICONMENU_BUFF"] .. " - " .. L["DURATION"] .. " - Pandemic " .. L["PERCENTAGE"],
	min = 0,
	max = 100,
	percent = true,
	name = function(editbox)
		editbox:SetTexts(L["BUFFTOCHECK"], L["BUFFCNDT_DESC"])
	end,
	useSUG = true,
	check = function(check)
		check:SetTexts(L["ONLYCHECKMINE"], L["ONLYCHECKMINE_DESC"])
	end,
	formatter = TMW.C.Formatter.PERCENT,
	icon = "Interface\\Icons\\spell_holy_circleofrenewal",
	tcoords = CNDT.COMMON.standardtcoords,
	funcstr = function(c)
		return [[AuraPandemicPercent(c.Unit, c.NameFirst, c.NameString, "HELPFUL]] .. (c.Checked and " PLAYER" or "") .. [[") c.Operator c.Level]]
	end,
	events = function(ConditionObject, c)
		return
			ConditionObject:GetUnitChangedEventString(CNDT:GetUnit(c.Unit)),
			ConditionObject:GenerateNormalEventString("UNIT_AURA", CNDT:GetUnit(c.Unit))
	end,
	anticipate = function(c)
        return [[local dur, duration, expirationTime = AuraPandemicDur(c.Unit, c.NameFirst, c.NameString, "HELPFUL]] .. (c.Checked and " PLAYER" or "") .. [[")
		local VALUE
		if dur and dur > 0 then
			VALUE = expirationTime and (expirationTime - c.Level*duration) or 0
		else
			VALUE = 0
		end]]
	end,
})

 You will probably want to change the icon for the condition, and you'll want to add the corresponding condition for debuffs as well, but other than that, this should work just fine as a standalone addon. That's why TMW has a documented API in the first place - for things like this.


Edited Nov 26, 2016

Posted by CurseForge user Cybeloras

commented

Oh, and you won't need to store your AuraTracker on TMW - you can just store it as a local in that file.


Edited Nov 26, 2016

Posted by CurseForge user Cybeloras