diff --git a/elements/tags.lua b/elements/tags.lua
index 3ded96c..34a90ab 100644
--- a/elements/tags.lua
+++ b/elements/tags.lua
@@ -1,4 +1,8 @@
-local tags = select(2, ...).oUF.Tags
+local oUF = select(2, ...).oUF
+local tags = oUF.Tags
+local tagMethods = tags.Methods
+local tagEvents = tags.Events
+local tagSharedEvents = tags.SharedEvents
local gsub = string.gsub
local format = string.format
@@ -89,14 +93,14 @@ for tag, func in next, {
return floor(cur / max * 100)
end
end,
- pethp = function()
- if(UnitIsUnit('pet', 'vehicle')) then return end
+ pethp = function(unit)
+ if(UnitIsUnit(unit, 'vehicle')) then return end
- local cur = UnitHealth('pet')
- local max = UnitHealthMax('pet')
+ local cur = UnitHealth(unit)
+ local max = UnitHealthMax(unit)
if(cur > 0) then
return format('%s%d%%|r', Hex(ColorGradient(cur, max, 1, 0, 0, 1, 1, 0, 1, 1, 1)), cur / max * 100)
- elseif(UnitIsDead('pet')) then
+ elseif(UnitIsDead(unit)) then
return DEAD_TEXTURE
end
end,
@@ -187,10 +191,289 @@ for tag, func in next, {
end,
status = Status
} do
- tags.Methods['p3lim:' .. tag] = func
- tags.Events['p3lim:' .. tag] = events[tag]
+ tagMethods['p3lim:' .. tag] = func
+ tagEvents['p3lim:' .. tag] = events[tag]
+end
+
+-- Modified version of the tags element
+local events = {}
+local frame = CreateFrame('Frame')
+frame:SetScript('OnEvent', function(self, event, unit)
+ local strings = events[event]
+ if(strings) then
+ for _, fs in next, strings do
+ if(fs:IsVisible() and (tagSharedEvents[event] or fs.parent.unit == unit or fs.overrideUnit == unit)) then
+ fs:UpdateTag()
+ end
+ end
+ end
+end)
+
+local OnUpdates = {}
+local eventlessUnits = {}
+
+local function createOnUpdate(timer)
+ local OnUpdate = OnUpdates[timer]
+ if(not OnUpdate) then
+ local total = timer
+ local strings = eventlessUnits[timer]
+
+ local frame = CreateFrame('Frame')
+ frame:SetScript('OnUpdate', function(self, elapsed)
+ if(total >= timer) then
+ for _, fs in next, strings do
+ if(fs.parent:IsShown() and (UnitExists(fs.parent.unit) or UnitExists(fs.overrideUnit))) then
+ fs:UpdateTag()
+ end
+ end
+
+ total = 0
+ end
+
+ total = total + elapsed
+ end)
+
+ OnUpdates[timer] = frame
+ end
+end
+
+local function OnShow(self)
+ for _, fs in next, self.__tags do
+ fs:UpdateTag()
+ end
+end
+
+local function getTagName(tag)
+ local s = (tag:match('>+()') or 2)
+ local e = tag:match('.*()<+')
+ e = (e and e - 1) or -2
+
+ return tag:sub(s, e), s, e
+end
+
+local function RegisterEvent(fs, event)
+ if(not events[event]) then
+ events[event] = {}
+ end
+
+ frame:RegisterEvent(event)
+ table.insert(events[event], fs)
+end
+
+local _PATTERN = '%[..-%]+'
+local function RegisterEvents(fs, tagStr)
+ for tag in tagStr:gmatch(_PATTERN) do
+ tag = getTagName(tag)
+
+ local events = tagEvents[tag]
+ if(events) then
+ for event in events:gmatch('%S+') do
+ RegisterEvent(fs, event)
+ end
+ end
+ end
+end
+
+local function UnregisterEvents(fs)
+ for event, data in next, events do
+ for key, fs2 in next, data do
+ if(fs2 == fs) then
+ if(#data == 1) then
+ frame:UnregisterEvent(event)
+ end
+
+ table.remove(data, key)
+ end
+ end
+ end
+end
+
+local tagPool = {}
+local funcPool = {}
+local tmp = {}
+
+local function Tag(self, fs, tagStr)
+ if(not fs or not tagStr) then
+ return
+ end
+
+ if(not self.__tags) then
+ self.__tags = {}
+ table.insert(self.__elements, OnShow)
+ else
+ -- Since people ignore everything that is good practice;
+ -- Unregister the tag if it already exists.
+ for _, tag in next, self.__tags do
+ if(fs == tag) then
+ -- We don't need to remove it from the __tags table as Untag
+ -- handles that for us.
+ self:Untag(fs)
+ end
+ end
+ end
+
+ fs.parent = self
+
+ local func = tagPool[tagStr]
+ if(not func) then
+ local format, numTags = tagStr:gsub('%%', '%%%%'):gsub(_PATTERN, '%%s')
+ local args = {}
+
+ for bracket in tagStr:gmatch(_PATTERN) do
+ local tagFunc = funcPool[bracket] or tagMethods[bracket:sub(2, -2)]
+ if(not tagFunc) then
+ local tagName, s, e = getTagName(bracket)
+ local tag = tagMethods[tagName]
+ if(tag) then
+ s = s - 2
+ e = e + 2
+
+ if(s ~= 0 and e ~= 0) then
+ local pre = bracket:sub(2, s)
+ local ap = bracket:sub(e, -2)
+
+ tagFunc = function(u, r)
+ local str = tag(u, r)
+ if(str) then
+ return pre .. str .. ap
+ end
+ end
+ elseif(s ~= 0) then
+ local pre = bracket:sub(2, s)
+
+ tagFunc = function(u, r)
+ local str = tag(u, r)
+ if(str) then
+ return pre .. str
+ end
+ end
+ elseif(e ~= 0) then
+ local ap = bracket:sub(e, -2)
+
+ tagFunc = function(u, r)
+ local str = tag(u, r)
+ if(str) then
+ return str .. ap
+ end
+ end
+ end
+
+ funcPool[bracket] = tagFunc
+ end
+ end
+
+ if(tagFunc) then
+ table.insert(args, tagFunc)
+ else
+ return error(('Attempted to use invalid tag %s.'):format(bracket), 3)
+ end
+ end
+
+ if(numTags == 1) then
+ func = function(self)
+ local parent = self.parent
+ local unit = parent.unit
+ local overrideUnit = self.overrideUnit
+
+ -- _ENV._COLORS = parent.colors
+ return self:SetFormattedText(
+ format,
+ args[1](overrideUnit or unit, overrideUnit and unit) or ''
+ )
+ end
+ elseif(numTags == 2) then
+ func = function(self)
+ local parent = self.parent
+ local unit = parent.unit
+ local overrideUnit = self.overrideUnit
+
+ -- _ENV._COLORS = parent.colors
+ return self:SetFormattedText(
+ format,
+ args[1](overrideUnit or unit, overrideUnit and unit) or '',
+ args[2](overrideUnit or unit, overrideUnit and unit) or ''
+ )
+ end
+ elseif(numTags == 3) then
+ func = function(self)
+ local parent = self.parent
+ local unit = parent.unit
+ local overrideUnit = self.overrideUnit
+
+ -- _ENV._COLORS = parent.colors
+ return self:SetFormattedText(
+ format,
+ args[1](overrideUnit or unit, overrideUnit and unit) or '',
+ args[2](overrideUnit or unit, overrideUnit and unit) or '',
+ args[3](overrideUnit or unit, overrideUnit and unit) or ''
+ )
+ end
+ else
+ func = function(self)
+ local parent = self.parent
+ local unit = parent.unit
+ local overrideUnit = self.overrideUnit
+
+ -- _ENV._COLORS = parent.colors
+ for i, func in next, args do
+ tmp[i] = func(overrideUnit or unit, overrideUnit and unit) or ''
+ end
+
+ -- We do 1, numTags because tmp can hold several unneeded variables.
+ return self:SetFormattedText(format, unpack(tmp, 1, numTags))
+ end
+ end
+
+ tagPool[tagStr] = func
+ end
+ fs.UpdateTag = func
+
+ local unit = self.unit
+ if(self.__eventless or fs.frequentUpdates) then
+ local timer
+ if(type(fs.frequentUpdates) == 'number') then
+ timer = fs.frequentUpdates
+ else
+ timer = 1/2
+ end
+
+ if(not eventlessUnits[timer]) then
+ eventlessUnits = {}
+ end
+
+ table.insert(eventlessUnits[timer], fs)
+
+ createOnUpdate(timer)
+ else
+ RegisterEvents(fs, tagStr)
+ end
+
+ table.insert(self.__tags, fs)
+end
+
+local function Untag(self, fs)
+ if(not fs) then
+ return
+ end
+
+ UnregisterEvents(fs)
+
+ for _, timers in next, eventlessUnits do
+ for key, fs2 in next, timers do
+ if(fs2 == fs) then
+ table.remove(timers, key)
+ end
+ end
+ end
+
+ for key, fs2 in next, self.__tags do
+ if(fs2 == fs) then
+ table.remove(self.__tags, key)
+ end
+ end
+
+ fs.UpdateTag = nil
end
--- This is really bad haste
-tags.SharedEvents.UNIT_HEALTH_FREQUENT = true
-tags.SharedEvents.UNIT_MAXHEALTH = true
+oUF:RegisterMetaFunction('CustomTag', Tag)
+oUF:RegisterMetaFunction('CustomUntag', Untag)
diff --git a/oUF_P3lim.lua b/oUF_P3lim.lua
index 38d9384..e5c42d0 100644
--- a/oUF_P3lim.lua
+++ b/oUF_P3lim.lua
@@ -162,7 +162,8 @@ local UnitSpecific = {
PetHealth:SetPoint('RIGHT', self.HealthValue, 'LEFT', -2, 0)
PetHealth:SetFont(FONT, 8, 'OUTLINEMONOCHROME')
PetHealth:SetJustifyH('RIGHT')
- self:Tag(PetHealth, '[p3lim:pethp< :]')
+ PetHealth.overrideUnit = 'pet'
+ self:CustomTag(PetHealth, '[p3lim:pethp< :]')
local PowerValue = self.StringParent:CreateFontString(nil, 'OVERLAY')
PowerValue:SetPoint('LEFT', self.Health, 2, 0)