From 8c4cc405aa03b6a2320c8df25ec033fba19264cd Mon Sep 17 00:00:00 2001 From: omicron Date: Tue, 4 Apr 2023 06:40:29 +0200 Subject: [PATCH] Move ivert logic and trigger logic into Trigger The base Trigger class is now responsible for inverting the trigger state and also for signaling trigger activation to the target/indicator. In addition the following non-function changes also occured: - The triggers moved into their own directory - The trigger code has been annotated to help lua-language-server deduce type information - AuraTrigger was moved into its own file All these changes should make future development of other triggers easier --- src/OmicronFrames.toc | 3 +- src/types/trigger.lua | 151 ----------------------------- src/types/triggers/auratrigger.lua | 94 ++++++++++++++++++ src/types/triggers/trigger.lua | 67 +++++++++++++ src/types/unitframe.lua | 16 +-- 5 files changed, 173 insertions(+), 158 deletions(-) delete mode 100644 src/types/trigger.lua create mode 100644 src/types/triggers/auratrigger.lua create mode 100644 src/types/triggers/trigger.lua diff --git a/src/OmicronFrames.toc b/src/OmicronFrames.toc index 3f96062..024ac65 100644 --- a/src/OmicronFrames.toc +++ b/src/OmicronFrames.toc @@ -9,7 +9,8 @@ main.lua types/types.lua types/object.lua -types/trigger.lua +types/triggers/trigger.lua +types/triggers/auratrigger.lua types/statusbar.lua types/auralist.lua types/indicator.lua diff --git a/src/types/trigger.lua b/src/types/trigger.lua deleted file mode 100644 index 3aebfd4..0000000 --- a/src/types/trigger.lua +++ /dev/null @@ -1,151 +0,0 @@ --- Copyright 2023 --- --- This file is part of Omicron Frames --- --- Omicron Frames is free software: you can redistribute it and/or modify it --- under the terms of the GNU General Public License as published by the Free --- Software Foundation, either version 3 of the License, or (at your option) --- any later version. --- --- Omicron Frames is distributed in the hope that it will be useful, but --- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for --- more details. --- --- You should have received a copy of the GNU General Public License along with --- Omicron Frames. If not, see . -local omi = select(2, ...) -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") -local Trigger = types.Trigger - - --- Initialize a new Trigger object --- indicator: --- The indicator that gets activated by this trigger. -function Trigger:Init(indicator) - self.indicator = indicator -end - --- Returns whether or not the trigger is active -function Trigger:IsActive() - return false -end - --- Reset the trigger to the default state. Deactivates the indicator if it is --- active when Reset is called. -function Trigger:Reset() -end - - ---- --- AuraTrigger is a trigger that can be attached to AuraList as datasource -types.AuraTrigger = types.CreateClass("AuraTrigger", Trigger) -local AuraTrigger = types.AuraTrigger - ---- Initialize a new AuraTrigger object --- indicator --- Indicator that gets controlled by this trigger. --- spellId --- Spell id to trigger on --- own --- Only trigger on auras by the player --- requiredCount=1 --- Number of aura applications to activate trigger --- invert=false --- Whether to invert trigger activation -function AuraTrigger:Init(indicator, spellId, own, requiredCount, invert) - Trigger.Init(self, indicator) - self.spellId = spellId - self.requiredCount = requiredCount or 1 - self.own = own - self.count = 0 - self.invert = invert or false -end - ---- See Trigger:Reset -function AuraTrigger:Reset() - local before = self:IsActive() - self.count = 0 - local after = self:IsActive() - if not before and after then - self.indicator:Show() - elseif before and not after then - self.indicator:Hide() - end -end - ---- Return true if the aura matches the trigger --- aura: --- Must be a valid UnitAuraInfo structure. -function AuraTrigger:IsMatching(aura) - if aura.spellId ~= aura.spellId then - return false - end - if self.own and aura.sourceUnit ~= "player" then - return false - end - return true -end - ---- Inform the trigger about an added aura --- aura: --- Must be a valid UnitAuraInfo -function AuraTrigger:AddAura(aura) - if not self:IsMatching(aura) then - return - end - self.count = self.count + 1 - - -- Be mindful, this works only if count always changes by 1. - if self.count == self.requiredCount then - if self.invert then - self.indicator:Hide() - else - self.indicator:Show() - end - end -end - ---- Inform the trigger about an updated aura --- before: --- Must be a valid UnitAuraInfo for the aura before the update --- after: --- Must be a valid UnitAuraInfo for the aura after the update -function AuraTrigger:UpdateAura(before, after) - -- -end - ---- Inform the trigger about an aura that got removed --- aura: --- Must be a valid UnitAuraInfo for the aura before it got removed -function AuraTrigger:RemoveAura(aura) - if not self:IsMatching(aura) then - return - end - self.count = self.count - 1 - -- Be mindful, this works only if count always changes by 1. - if self.count == self.requiredCount - 1 then - if self.invert then - self.indicator:Show() - else - self.indicator:Hide() - end - end -end - ---- Returns true if the trigger is active, false otherwise -function AuraTrigger:IsActive() - if self.invert then - return self.count < self.requiredCount - else - return self.count >= self.requiredCount - end -end diff --git a/src/types/triggers/auratrigger.lua b/src/types/triggers/auratrigger.lua new file mode 100644 index 0000000..37eac84 --- /dev/null +++ b/src/types/triggers/auratrigger.lua @@ -0,0 +1,94 @@ +-- Copyright 2023 +-- +-- This file is part of Omicron Frames +-- +-- Omicron Frames is free software: you can redistribute it and/or modify it +-- under the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 3 of the License, or (at your option) +-- any later version. +-- +-- Omicron Frames is distributed in the hope that it will be useful, but +-- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +-- more details. +-- +-- You should have received a copy of the GNU General Public License along with +-- Omicron Frames. If not, see . +local omi = select(2, ...) +local types = omi.GetModule("types") +---@class Trigger +local Trigger = types.Trigger + +---AuraTrigger is a Trigger that can be attached to AuraList as datasource +---@class AuraTrigger: Trigger +---@field spellId number +---@field count number +---@field requiredCount number +local AuraTrigger = types.CreateClass("AuraTrigger", Trigger) +types.AuraTrigger = AuraTrigger + +---@return AuraTrigger +function AuraTrigger.new(cls, ...) + --- I really dislike duplicating this everywhere but it makes + --lua-language-server able to deduce the type of Object:new calls and that + --is honestly worth it + return types.Object.new(cls, ...) +end + +--- Initialize a new AuraTrigger object +---@param spellId number +---@param own boolean +---@param requiredCount number | nil +---@param invert boolean | nil +function AuraTrigger:Init(spellId, own, requiredCount, invert) + Trigger.Init(self, invert) + self.spellId = spellId + self.requiredCount = requiredCount or 1 + self.own = own + self.count = 0 +end + +--- Reset the AuraTrigger to the default state +function AuraTrigger:Reset() + self.count = 0 + self:SetState(self.count >= self.requiredCount) +end + +---Check if a given aura matches this AuraTrigger +---@param aura UnitAuraInfo +function AuraTrigger:IsMatching(aura) + if aura.spellId ~= aura.spellId then + return false + end + if self.own and aura.sourceUnit ~= "player" then + return false + end + return true +end + +---Inform the trigger about an added aura +---@param aura UnitAuraInfo +function AuraTrigger:AddAura(aura) + if not self:IsMatching(aura) then + return + end + self.count = self.count + 1 + self:SetState(self.count >= self.requiredCount) +end + +---Inform the trigger about an updated aura +---@param before UnitAuraInfo +---@param after UnitAuraInfo +function AuraTrigger:UpdateAura(before, after) + -- +end + +---Inform the trigger about an aura that got removed +---@param aura UnitAuraInfo +function AuraTrigger:RemoveAura(aura) + if not self:IsMatching(aura) then + return + end + self.count = self.count - 1 + self:SetState(self.count >= self.requiredCount) +end diff --git a/src/types/triggers/trigger.lua b/src/types/triggers/trigger.lua new file mode 100644 index 0000000..3e18802 --- /dev/null +++ b/src/types/triggers/trigger.lua @@ -0,0 +1,67 @@ +-- Copyright 2023 +-- +-- This file is part of Omicron Frames +-- +-- Omicron Frames is free software: you can redistribute it and/or modify it +-- under the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 3 of the License, or (at your option) +-- any later version. +-- +-- Omicron Frames is distributed in the hope that it will be useful, but +-- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +-- more details. +-- +-- You should have received a copy of the GNU General Public License along with +-- Omicron Frames. If not, see . +local omi = select(2, ...) +local types = omi.GetModule("types") + +--- Triggers objects provide a link between indicators and some data source. They +-- can pass data from the data source into the indicator. This is a supertype for +-- all triggers and should not be constructed on its own. +---@class Trigger: Object +---@field active boolean +---@field invert boolean +local Trigger = types.CreateClass("Trigger") +types.Trigger = Trigger + + +--- Initialize a new Trigger object +---@param invert boolean|nil +function Trigger:Init(invert) + invert = invert or false + self.invert = invert + self.active = invert +end + +--- Set the target of the Trigger. +-- The target will get notified every time the trigger changes state. If the trigger +-- is currently active when the target is set, it will get notified immediately. +---@param target Indicator +function Trigger:SetTarget(target) + self.indicator = target +end + +---Set the state of the trigger. Will activate the indicator if needed. +---@param data table | nil +---@param state boolean +function Trigger:SetState(state, data) + state = state ~= self.invert -- state xor inverted + + if self.active ~= state then + if state then + self.indicator:Show(data) + else + self.indicator:Hide() + end + self.active = state + end +end + +-- Reset the trigger to the default state. If this changes the activation of the +-- trigger then the target will be notified. +function Trigger:Reset() + self:SetState(false) +end + diff --git a/src/types/unitframe.lua b/src/types/unitframe.lua index a094126..4e7cfcb 100644 --- a/src/types/unitframe.lua +++ b/src/types/unitframe.lua @@ -19,10 +19,13 @@ local types = omif.GetModule("types") local StatusBar = types.StatusBar local AuraList = types.AuraList local SquareIndicator = types.SquareIndicator + +---@class AuraTrigger local AuraTrigger = types.AuraTrigger -types.UnitFrame = types.CreateClass("UnitFrame") -local UnitFrame = types.UnitFrame +---@class UnitFrame +local UnitFrame = types.CreateClass("UnitFrame") +types.UnitFrame = UnitFrame local colors = { @@ -83,19 +86,20 @@ function UnitFrame:CreateTriggers(triggers) for _, trigger in ipairs(triggers) do local kind = trigger.kind if kind == "AuraTrigger" then - self.auras:AddTrigger( - AuraTrigger:new( - self:CreateIndicator(trigger.indicator), + local indicator = self:CreateIndicator(trigger.indicator) + local at = AuraTrigger:new( trigger.spellId, trigger.own, trigger.requiredCount, trigger.invert - ) ) + at:SetTarget(indicator) + self.auras:AddTrigger(at) end end end + function UnitFrame:CreateIndicator(indicator) local kind = indicator.kind if kind == "SquareIndicator" then