Rework the way triggers and indicators work
Triggers are now a link between link between a datasource (for now only AuraList) and an indicator (for now only SquareIndicator).
This commit is contained in:
@@ -18,6 +18,7 @@ local omi = select(2, ...)
|
|||||||
local types = omi.GetModule("types")
|
local types = omi.GetModule("types")
|
||||||
local AuraTrigger = types.AuraTrigger
|
local AuraTrigger = types.AuraTrigger
|
||||||
|
|
||||||
|
--- AuraList keeps track of all the auras attached to a unitframe
|
||||||
local AuraList = types.CreateClass("AuraList")
|
local AuraList = types.CreateClass("AuraList")
|
||||||
types.AuraList = AuraList
|
types.AuraList = AuraList
|
||||||
|
|
||||||
@@ -38,6 +39,8 @@ local statusLists = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
-- helper function that goes over several aura slots for a unit. Runs a
|
||||||
|
-- callback function with UnitAuraInfo table as argument
|
||||||
local function ForEachAuraSlots(unit, fn, continuationToken, ...)
|
local function ForEachAuraSlots(unit, fn, continuationToken, ...)
|
||||||
local GetAuraDataBySlot = C_UnitAuras.GetAuraDataBySlot
|
local GetAuraDataBySlot = C_UnitAuras.GetAuraDataBySlot
|
||||||
local n = select('#', ...)
|
local n = select('#', ...)
|
||||||
@@ -48,6 +51,7 @@ local function ForEachAuraSlots(unit, fn, continuationToken, ...)
|
|||||||
return continuationToken
|
return continuationToken
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Helper function that goes over all aura slots for a given filter
|
||||||
local function ForEachAuraFiltered(unit, filter, fn)
|
local function ForEachAuraFiltered(unit, filter, fn)
|
||||||
local UnitAuraSlots = UnitAuraSlots
|
local UnitAuraSlots = UnitAuraSlots
|
||||||
local continuationToken = nil
|
local continuationToken = nil
|
||||||
@@ -63,6 +67,9 @@ local function ForEachAura(unit, fn)
|
|||||||
ForEachAuraFiltered(unit, "HARMFUL", fn)
|
ForEachAuraFiltered(unit, "HARMFUL", fn)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Initialize AuraList
|
||||||
|
-- unitframe
|
||||||
|
-- The unitframe this list belongs to
|
||||||
function AuraList:Init(unitframe)
|
function AuraList:Init(unitframe)
|
||||||
self.unitframe = unitframe
|
self.unitframe = unitframe
|
||||||
self.unit = unitframe.unit
|
self.unit = unitframe.unit
|
||||||
@@ -75,20 +82,20 @@ function AuraList:Init(unitframe)
|
|||||||
self.triggersBySpell = {}
|
self.triggersBySpell = {}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Add an AuraTrigger to this AuraList
|
||||||
|
-- trigger
|
||||||
|
-- an AuraTrigger object
|
||||||
function AuraList:AddTrigger(trigger)
|
function AuraList:AddTrigger(trigger)
|
||||||
table.insert(self.triggers, trigger)
|
table.insert(self.triggers, trigger)
|
||||||
if trigger:IsInstanceOf(AuraTrigger) then
|
|
||||||
local spellId = trigger.spellId
|
local spellId = trigger.spellId
|
||||||
if self.triggersBySpell[spellId] == nil then
|
if self.triggersBySpell[spellId] == nil then
|
||||||
self.triggersBySpell[spellId] = {}
|
self.triggersBySpell[spellId] = {}
|
||||||
end
|
end
|
||||||
table.insert(self.triggersBySpell[spellId], trigger)
|
table.insert(self.triggersBySpell[spellId], trigger)
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
-- Scan all the auras of the owning unit and build the aura list from scratch
|
--- Reset the AuraList and do a full aura scan on the unit
|
||||||
-- This should only ever happen when the unit is first assigned to the frame
|
-- This also resets all the triggers that are attached to this AuraList
|
||||||
function AuraList:Reset()
|
function AuraList:Reset()
|
||||||
self.auras = {}
|
self.auras = {}
|
||||||
|
|
||||||
@@ -103,6 +110,9 @@ function AuraList:Reset()
|
|||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Add an aura to the AuraList
|
||||||
|
-- aura
|
||||||
|
-- A UnitAuraInfo table for a newly added aura
|
||||||
function AuraList:AddAura(aura)
|
function AuraList:AddAura(aura)
|
||||||
local statusChanged = false
|
local statusChanged = false
|
||||||
self.auras[aura.auraInstanceID] = aura
|
self.auras[aura.auraInstanceID] = aura
|
||||||
@@ -126,7 +136,9 @@ function AuraList:AddAura(aura)
|
|||||||
return statusChanged
|
return statusChanged
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Returns a table with every status that applies to the given aura
|
--- Return a sequence table with all status names that match the given aura
|
||||||
|
-- aura
|
||||||
|
-- A UnitAuraInfo table
|
||||||
function AuraList:GetStatusForAura(aura)
|
function AuraList:GetStatusForAura(aura)
|
||||||
local status = {}
|
local status = {}
|
||||||
if aura.dispelName and aura.isHarmful then
|
if aura.dispelName and aura.isHarmful then
|
||||||
@@ -140,6 +152,9 @@ function AuraList:GetStatusForAura(aura)
|
|||||||
return status
|
return status
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Add an aura to the AuraList
|
||||||
|
-- aura
|
||||||
|
-- A UnitAuraInfo table for a newly added aura
|
||||||
function AuraList:UpdateAura(aura)
|
function AuraList:UpdateAura(aura)
|
||||||
for _, trigger in ipairs(self.triggersBySpell[aura.spellId] or {}) do
|
for _, trigger in ipairs(self.triggersBySpell[aura.spellId] or {}) do
|
||||||
trigger:UpdateAura(self.auras[aura.auraInstanceId], aura)
|
trigger:UpdateAura(self.auras[aura.auraInstanceId], aura)
|
||||||
@@ -147,6 +162,9 @@ function AuraList:UpdateAura(aura)
|
|||||||
self.auras[aura.auraInstanceID] = aura
|
self.auras[aura.auraInstanceID] = aura
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Remove an aura from the AuraList
|
||||||
|
-- iid
|
||||||
|
-- The instance id for a removed aura
|
||||||
function AuraList:RemoveAura(iid)
|
function AuraList:RemoveAura(iid)
|
||||||
local aura = self.auras[iid]
|
local aura = self.auras[iid]
|
||||||
if aura == nil then
|
if aura == nil then
|
||||||
@@ -174,6 +192,9 @@ function AuraList:RemoveAura(iid)
|
|||||||
return statusChanged
|
return statusChanged
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Update an aura in the AuraList
|
||||||
|
-- info
|
||||||
|
-- The new UnitAuraInfo structure
|
||||||
function AuraList:Update(info)
|
function AuraList:Update(info)
|
||||||
local GetAuraDataByAuraInstanceID = C_UnitAuras.GetAuraDataByAuraInstanceID
|
local GetAuraDataByAuraInstanceID = C_UnitAuras.GetAuraDataByAuraInstanceID
|
||||||
local statusChanged = false
|
local statusChanged = false
|
||||||
|
@@ -18,13 +18,35 @@ local omi = select(2, ...)
|
|||||||
local types = omi.GetModule("types")
|
local types = omi.GetModule("types")
|
||||||
local AuraTrigger = types.AuraTrigger
|
local AuraTrigger = types.AuraTrigger
|
||||||
|
|
||||||
|
--- Indicator is a type for any kind of visual indicator. This type has no
|
||||||
|
-- function and should not be created. All functional indicators derive from
|
||||||
|
-- this type.
|
||||||
local Indicator = types.CreateClass("Indicator")
|
local Indicator = types.CreateClass("Indicator")
|
||||||
types.Indicator = Indicator
|
types.Indicator = Indicator
|
||||||
|
|
||||||
-- TODO: make different indicators, such as texture, text, border
|
--- Show the indicator and supply it with data
|
||||||
-- TODO: spellid feels out of place but I wanna quickly get something for now.
|
function Indicator:Show(data)
|
||||||
-- Should rethink this when Trigger is its own class
|
end
|
||||||
function Indicator:Init(unitframe, auralist, size, point, x, y, color, spellId)
|
|
||||||
|
--- Update the indicator with new data
|
||||||
|
function Indicator:Update(data)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Hide the indicator
|
||||||
|
function Indicator:Hide()
|
||||||
|
end
|
||||||
|
|
||||||
|
--- SquareIndicator is an indicator that displays a colored square texture
|
||||||
|
local SquareIndicator = types.CreateClass("SquareIndicator", Indicator)
|
||||||
|
types.SquareIndicator = SquareIndicator
|
||||||
|
|
||||||
|
--- Initialize a new SquareIndicator
|
||||||
|
-- unitframe Unitframe it is attached to
|
||||||
|
-- size Size of the indicator square
|
||||||
|
-- point Attachment point to the unitframe's overlay frame
|
||||||
|
-- x, y x and y offset for the attachment point
|
||||||
|
-- color Color of the square
|
||||||
|
function SquareIndicator:Init(unitframe, size, point, x, y, color)
|
||||||
local frame = unitframe.overlays
|
local frame = unitframe.overlays
|
||||||
|
|
||||||
local texture = frame:CreateTexture(nil, "ARTWORK")
|
local texture = frame:CreateTexture(nil, "ARTWORK")
|
||||||
@@ -36,26 +58,21 @@ function Indicator:Init(unitframe, auralist, size, point, x, y, color, spellId)
|
|||||||
self:SetColor(color)
|
self:SetColor(color)
|
||||||
texture:SetVertexColor(unpack(color))
|
texture:SetVertexColor(unpack(color))
|
||||||
texture:SetDrawLayer("ARTWORK")
|
texture:SetDrawLayer("ARTWORK")
|
||||||
|
|
||||||
local fn = function(activate)
|
|
||||||
if activate then
|
|
||||||
self:Show()
|
|
||||||
else
|
|
||||||
self:Hide()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
local trigger = AuraTrigger:new(fn, spellId, true)
|
|
||||||
auralist:AddTrigger(trigger)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function Indicator:SetColor(color)
|
--- Set the color of the Square Indicator
|
||||||
|
-- color: a sequence table with 3 color channels {r, g, b}
|
||||||
|
function SquareIndicator:SetColor(color)
|
||||||
self.texture:SetVertexColor(unpack(color))
|
self.texture:SetVertexColor(unpack(color))
|
||||||
end
|
end
|
||||||
|
|
||||||
function Indicator:Show()
|
--- Show the square indicator.
|
||||||
|
-- data: ignored for now
|
||||||
|
function SquareIndicator:Show(data)
|
||||||
self.texture:Show()
|
self.texture:Show()
|
||||||
end
|
end
|
||||||
|
|
||||||
function Indicator:Hide()
|
--- Hide the square indicator.
|
||||||
|
function SquareIndicator:Hide()
|
||||||
self.texture:Hide()
|
self.texture:Hide()
|
||||||
end
|
end
|
||||||
|
@@ -17,47 +17,52 @@
|
|||||||
local omi = select(2, ...)
|
local omi = select(2, ...)
|
||||||
local types = omi.GetModule("types")
|
local types = omi.GetModule("types")
|
||||||
|
|
||||||
|
---
|
||||||
|
-- Trigger objects provide a link between indicators and some data source. They
|
||||||
|
-- can pass data from the data source into the trigger. This is just a
|
||||||
|
-- supertype for all indicators and should not be constructed on its own. It
|
||||||
|
-- has no functionality other than providing default implementations that do
|
||||||
|
-- nothing.
|
||||||
types.Trigger = types.CreateClass("Trigger")
|
types.Trigger = types.CreateClass("Trigger")
|
||||||
local Trigger = types.Trigger
|
local Trigger = types.Trigger
|
||||||
|
|
||||||
|
|
||||||
-- Constructor for Trigger.
|
-- Initialize a new Trigger object
|
||||||
-- fn:
|
-- indicator:
|
||||||
-- The callback function that gets called every time this trigger changes
|
-- The indicator that gets activated by this trigger.
|
||||||
-- states between active and inactive. Function takes one boolean argument.
|
function Trigger:Init(indicator)
|
||||||
function Trigger:Init(fn)
|
self.indicator = indicator
|
||||||
self.fn = fn
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Returns whether the trigger is active
|
-- Returns whether or not the trigger is active
|
||||||
function Trigger:IsActive()
|
function Trigger:IsActive()
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Reset the trigger to the default state. Does run the untrigger callback if
|
-- Reset the trigger to the default state. Deactivates the indicator if it is
|
||||||
-- the trigger is active when Reset is called.
|
-- active when Reset is called.
|
||||||
function Trigger:Reset()
|
function Trigger:Reset()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
-- AuraTrigger is a trigger that can be attached to AuraList as datasource
|
||||||
types.AuraTrigger = types.CreateClass("AuraTrigger", Trigger)
|
types.AuraTrigger = types.CreateClass("AuraTrigger", Trigger)
|
||||||
local AuraTrigger = types.AuraTrigger
|
local AuraTrigger = types.AuraTrigger
|
||||||
|
|
||||||
-- Constructor for AuraTrigger
|
--- Initialize a new AuraTrigger object
|
||||||
-- fn:
|
-- indicator
|
||||||
-- The callback function that gets called every time this trigger changes
|
-- Indicator that gets controlled by this trigger.
|
||||||
-- states between active and inactive. Function takes one boolean argument.
|
-- spellId
|
||||||
--
|
-- Spell id to trigger on
|
||||||
-- requiredCount = 1:
|
-- own
|
||||||
-- The minimum number of conditions that must be met before the trigger
|
-- Only trigger on auras by the player
|
||||||
-- activates. What exactly this means depends on the trigger, examples are
|
-- requiredCount=1
|
||||||
-- # of matching auras, # of stacks.
|
-- Number of aura applications to activate trigger
|
||||||
--
|
-- invert=false
|
||||||
-- invert = false:
|
-- Whether to invert trigger activation
|
||||||
-- If the trigger is inverted it will activate when count < requiredCount.
|
function AuraTrigger:Init(indicator, spellId, own, requiredCount, invert)
|
||||||
-- If the trigger is not inverted it will activate when count >= requiredCount.
|
Trigger.Init(self, indicator)
|
||||||
function AuraTrigger:Init(fn, spellId, own, requiredCount, invert)
|
|
||||||
Trigger.Init(self, fn)
|
|
||||||
self.spellId = spellId
|
self.spellId = spellId
|
||||||
self.requiredCount = requiredCount or 1
|
self.requiredCount = requiredCount or 1
|
||||||
self.own = own
|
self.own = own
|
||||||
@@ -65,18 +70,19 @@ function AuraTrigger:Init(fn, spellId, own, requiredCount, invert)
|
|||||||
self.invert = invert or false
|
self.invert = invert or false
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Reset the trigger to the default state. Does run the untrigger callback if
|
--- See Trigger:Reset
|
||||||
-- the trigger is active when it is called
|
|
||||||
function AuraTrigger:Reset()
|
function AuraTrigger:Reset()
|
||||||
local before = self:IsActive()
|
local before = self:IsActive()
|
||||||
self.count = 0
|
self.count = 0
|
||||||
local after = self:IsActive()
|
local after = self:IsActive()
|
||||||
if before ~= after then
|
if not before and after then
|
||||||
self.fn(after)
|
self.indicator:Show()
|
||||||
|
elseif before and not after then
|
||||||
|
self.indicator:Hide()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Return true if the aura matches the trigger
|
--- Return true if the aura matches the trigger
|
||||||
-- aura:
|
-- aura:
|
||||||
-- Must be a valid UnitAuraInfo structure.
|
-- Must be a valid UnitAuraInfo structure.
|
||||||
function AuraTrigger:IsMatching(aura)
|
function AuraTrigger:IsMatching(aura)
|
||||||
@@ -89,7 +95,7 @@ function AuraTrigger:IsMatching(aura)
|
|||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Inform the trigger about an added aura
|
--- Inform the trigger about an added aura
|
||||||
-- aura:
|
-- aura:
|
||||||
-- Must be a valid UnitAuraInfo
|
-- Must be a valid UnitAuraInfo
|
||||||
function AuraTrigger:AddAura(aura)
|
function AuraTrigger:AddAura(aura)
|
||||||
@@ -100,11 +106,15 @@ function AuraTrigger:AddAura(aura)
|
|||||||
|
|
||||||
-- Be mindful, this works only if count always changes by 1.
|
-- Be mindful, this works only if count always changes by 1.
|
||||||
if self.count == self.requiredCount then
|
if self.count == self.requiredCount then
|
||||||
self.fn(not self.invert)
|
if self.invert then
|
||||||
|
self.indicator:Hide()
|
||||||
|
else
|
||||||
|
self.indicator:Show()
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Inform the trigger about an updated aura
|
--- Inform the trigger about an updated aura
|
||||||
-- before:
|
-- before:
|
||||||
-- Must be a valid UnitAuraInfo for the aura before the update
|
-- Must be a valid UnitAuraInfo for the aura before the update
|
||||||
-- after:
|
-- after:
|
||||||
@@ -113,7 +123,8 @@ function AuraTrigger:UpdateAura(before, after)
|
|||||||
--
|
--
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Inform the trigger about an aura that got removed
|
--- Inform the trigger about an aura that got removed
|
||||||
|
-- aura:
|
||||||
-- Must be a valid UnitAuraInfo for the aura before it got removed
|
-- Must be a valid UnitAuraInfo for the aura before it got removed
|
||||||
function AuraTrigger:RemoveAura(aura)
|
function AuraTrigger:RemoveAura(aura)
|
||||||
if not self:IsMatching(aura) then
|
if not self:IsMatching(aura) then
|
||||||
@@ -122,11 +133,15 @@ function AuraTrigger:RemoveAura(aura)
|
|||||||
self.count = self.count - 1
|
self.count = self.count - 1
|
||||||
-- Be mindful, this works only if count always changes by 1.
|
-- Be mindful, this works only if count always changes by 1.
|
||||||
if self.count == self.requiredCount - 1 then
|
if self.count == self.requiredCount - 1 then
|
||||||
self.fn(self.invert)
|
if self.invert then
|
||||||
|
self.indicator:Show()
|
||||||
|
else
|
||||||
|
self.indicator:Hide()
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Returns true if the trigger is active, false otherwise
|
--- Returns true if the trigger is active, false otherwise
|
||||||
function AuraTrigger:IsActive()
|
function AuraTrigger:IsActive()
|
||||||
if self.invert then
|
if self.invert then
|
||||||
return self.count < self.requiredCount
|
return self.count < self.requiredCount
|
||||||
|
@@ -18,7 +18,8 @@ local omif = select(2, ...)
|
|||||||
local types = omif.GetModule("types")
|
local types = omif.GetModule("types")
|
||||||
local StatusBar = types.StatusBar
|
local StatusBar = types.StatusBar
|
||||||
local AuraList = types.AuraList
|
local AuraList = types.AuraList
|
||||||
local Indicator = types.Indicator
|
local SquareIndicator = types.SquareIndicator
|
||||||
|
local AuraTrigger = types.AuraTrigger
|
||||||
|
|
||||||
types.UnitFrame = types.CreateClass("UnitFrame")
|
types.UnitFrame = types.CreateClass("UnitFrame")
|
||||||
local UnitFrame = types.UnitFrame
|
local UnitFrame = types.UnitFrame
|
||||||
@@ -59,11 +60,29 @@ function UnitFrame:Init(unit, width, height, hideInRaid)
|
|||||||
overlays:Show()
|
overlays:Show()
|
||||||
self.overlays = overlays
|
self.overlays = overlays
|
||||||
self:CreateName()
|
self:CreateName()
|
||||||
self.indicators = {
|
|
||||||
Indicator:new(self, self.auras, 14, "TOPLEFT", 2, -2, colors.white, 383648),
|
self.auras:AddTrigger(
|
||||||
Indicator:new(self, self.auras, 14, "TOPLEFT", 2, -2, colors.white, 974),
|
AuraTrigger:new(
|
||||||
Indicator:new(self, self.auras, 14, "BOTTOMLEFT", 2, 2, colors.cyan, 61295)
|
SquareIndicator:new(self, 14, "TOPLEFT", 2, -2, colors.white),
|
||||||
}
|
383648, -- Second Earthshield on self
|
||||||
|
true
|
||||||
|
)
|
||||||
|
)
|
||||||
|
self.auras:AddTrigger(
|
||||||
|
AuraTrigger:new(
|
||||||
|
SquareIndicator:new(self, 14, "TOPLEFT", 2, -2, colors.white),
|
||||||
|
974, -- Earthshield
|
||||||
|
true
|
||||||
|
)
|
||||||
|
)
|
||||||
|
self.auras:AddTrigger(
|
||||||
|
AuraTrigger:new(
|
||||||
|
SquareIndicator:new(self, 14, "BOTTOMLEFT", 2, 2, colors.cyan),
|
||||||
|
61295, -- Riptide
|
||||||
|
true
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
self:RegisterEvents()
|
self:RegisterEvents()
|
||||||
self:Enable()
|
self:Enable()
|
||||||
end
|
end
|
||||||
|
Reference in New Issue
Block a user