From f07e982c8fe97aee43b7388881f72bae8e682cdc Mon Sep 17 00:00:00 2001 From: Adrian L Lange Date: Fri, 26 Dec 2014 23:29:56 +0100 Subject: [PATCH] Use a modified version of the tags element for the pet health --- elements/tags.lua | 305 +++++++++++++++++++++++++++++++++++++++++++++++++++-- oUF_P3lim.lua | 3 +- 2 files changed, 296 insertions(+), 12 deletions(-) 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) -- 1.7.9.5