diff --git a/WeakAuras/Libs/LibGetFrame-1.0/AceTimer-3.0/AceTimer-3.0.lua b/WeakAuras/Libs/LibGetFrame-1.0/AceTimer-3.0/AceTimer-3.0.lua
new file mode 100644
index 0000000..5f56dde
--- /dev/null
+++ b/WeakAuras/Libs/LibGetFrame-1.0/AceTimer-3.0/AceTimer-3.0.lua
@@ -0,0 +1,327 @@
+--- **AceTimer-3.0** provides a central facility for registering timers.
+-- AceTimer supports one-shot timers and repeating timers. All timers are stored in an efficient
+-- data structure that allows easy dispatching and fast rescheduling. Timers can be registered
+-- or canceled at any time, even from within a running timer, without conflict or large overhead.\\
+-- AceTimer is currently limited to firing timers at a frequency of 0.01s.
+--
+-- All `:Schedule` functions will return a handle to the current timer, which you will need to store if you
+-- need to cancel the timer you just registered.
+--
+-- **AceTimer-3.0** can be embeded into your addon, either explicitly by calling AceTimer:Embed(MyAddon) or by
+-- specifying it as an embeded library in your AceAddon. All functions will be available on your addon object
+-- and can be accessed directly, without having to explicitly call AceTimer itself.\\
+-- It is recommended to embed AceTimer, otherwise you'll have to specify a custom `self` on all calls you
+-- make into AceTimer.
+-- @class file
+-- @name AceTimer-3.0
+-- @release $Id$
+
+local MAJOR, MINOR = "AceTimer-3.0", 1017 -- Bump minor on changes
+local AceTimer, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
+
+if not AceTimer then return end -- No upgrade needed
+AceTimer.frame = AceTimer.frame or CreateFrame("Frame", "AceTimer30Frame")
+AceTimer.activeTimers = AceTimer.activeTimers or {} -- Active timer list
+local activeTimers = AceTimer.activeTimers -- Upvalue our private data
+
+-- Lua APIs
+local assert, loadstring, rawset, tconcat = assert, loadstring, rawset, table.concat
+local type, unpack, next, error, select = type, unpack, next, error, select
+-- WoW APIs
+local GetTime = GetTime
+
+--[[
+ xpcall safecall implementation
+]]
+local xpcall = xpcall
+
+local function errorhandler(err)
+ return geterrorhandler()(err)
+end
+
+local function CreateDispatcher(argCount)
+ local code = [[
+ local xpcall, eh = ...
+ local method, ARGS
+ local function call() return method(ARGS) end
+
+ local function dispatch(func, ...)
+ method = func
+ if not method then return end
+ ARGS = ...
+ return xpcall(call, eh)
+ end
+
+ return dispatch
+ ]]
+
+ local ARGS = {}
+ for i = 1, argCount do ARGS[i] = "arg"..i end
+ code = code:gsub("ARGS", tconcat(ARGS, ", "))
+ return assert(loadstring(code, "safecall Dispatcher["..argCount.."]"))(xpcall, errorhandler)
+end
+
+local Dispatchers = setmetatable({}, {__index=function(self, argCount)
+ local dispatcher = CreateDispatcher(argCount)
+ rawset(self, argCount, dispatcher)
+ return dispatcher
+end})
+Dispatchers[0] = function(func)
+ return xpcall(func, errorhandler)
+end
+
+local function safecall(func, ...)
+ return Dispatchers[select("#", ...)](func, ...)
+end
+
+local function new(self, loop, func, delay, ...)
+ if delay < 0.01 then
+ delay = 0.01 -- Restrict to the lowest time
+ end
+
+ local timer = {
+ object = self,
+ func = func,
+ looping = loop,
+ argsCount = select("#", ...),
+ delay = delay,
+ timeleft = delay,
+ ends = GetTime() + delay,
+ ...
+ }
+
+ activeTimers[timer] = timer
+
+ return timer
+end
+
+--- Schedule a new one-shot timer.
+-- The timer will fire once in `delay` seconds, unless canceled before.
+-- @param callback Callback function for the timer pulse (funcref or method name).
+-- @param delay Delay for the timer, in seconds.
+-- @param ... An optional, unlimited amount of arguments to pass to the callback function.
+-- @usage
+-- MyAddOn = LibStub("AceAddon-3.0"):NewAddon("MyAddOn", "AceTimer-3.0")
+--
+-- function MyAddOn:OnEnable()
+-- self:ScheduleTimer("TimerFeedback", 5)
+-- end
+--
+-- function MyAddOn:TimerFeedback()
+-- print("5 seconds passed")
+-- end
+function AceTimer:ScheduleTimer(func, delay, ...)
+ if not func or not delay then
+ error(MAJOR..": ScheduleTimer(callback, delay, args...): 'callback' and 'delay' must have set values.", 2)
+ end
+ if type(func) == "string" then
+ if type(self) ~= "table" then
+ error(MAJOR..": ScheduleTimer(callback, delay, args...): 'self' - must be a table.", 2)
+ elseif not self[func] then
+ error(MAJOR..": ScheduleTimer(callback, delay, args...): Tried to register '"..func.."' as the callback, but it doesn't exist in the module.", 2)
+ end
+ end
+ return new(self, nil, func, delay, ...)
+end
+
+--- Schedule a repeating timer.
+-- The timer will fire every `delay` seconds, until canceled.
+-- @param callback Callback function for the timer pulse (funcref or method name).
+-- @param delay Delay for the timer, in seconds.
+-- @param ... An optional, unlimited amount of arguments to pass to the callback function.
+-- @usage
+-- MyAddOn = LibStub("AceAddon-3.0"):NewAddon("MyAddOn", "AceTimer-3.0")
+--
+-- function MyAddOn:OnEnable()
+-- self.timerCount = 0
+-- self.testTimer = self:ScheduleRepeatingTimer("TimerFeedback", 5)
+-- end
+--
+-- function MyAddOn:TimerFeedback()
+-- self.timerCount = self.timerCount + 1
+-- print(("%d seconds passed"):format(5 * self.timerCount))
+-- -- run 30 seconds in total
+-- if self.timerCount == 6 then
+-- self:CancelTimer(self.testTimer)
+-- end
+-- end
+function AceTimer:ScheduleRepeatingTimer(func, delay, ...)
+ if not func or not delay then
+ error(MAJOR..": ScheduleRepeatingTimer(callback, delay, args...): 'callback' and 'delay' must have set values.", 2)
+ end
+ if type(func) == "string" then
+ if type(self) ~= "table" then
+ error(MAJOR..": ScheduleRepeatingTimer(callback, delay, args...): 'self' - must be a table.", 2)
+ elseif not self[func] then
+ error(MAJOR..": ScheduleRepeatingTimer(callback, delay, args...): Tried to register '"..func.."' as the callback, but it doesn't exist in the module.", 2)
+ end
+ end
+ return new(self, true, func, delay, ...)
+end
+
+--- Cancels a timer with the given id, registered by the same addon object as used for `:ScheduleTimer`
+-- Both one-shot and repeating timers can be canceled with this function, as long as the `id` is valid
+-- and the timer has not fired yet or was canceled before.
+-- @param id The id of the timer, as returned by `:ScheduleTimer` or `:ScheduleRepeatingTimer`
+function AceTimer:CancelTimer(id)
+ local timer = activeTimers[id]
+
+ if not timer then
+ return false
+ else
+ timer.cancelled = true
+ activeTimers[id] = nil
+ return true
+ end
+end
+
+--- Cancels all timers registered to the current addon object ('self')
+function AceTimer:CancelAllTimers()
+ for k,v in next, activeTimers do
+ if v.object == self then
+ AceTimer.CancelTimer(self, k)
+ end
+ end
+end
+
+--- Returns the time left for a timer with the given id, registered by the current addon object ('self').
+-- This function will return 0 when the id is invalid.
+-- @param id The id of the timer, as returned by `:ScheduleTimer` or `:ScheduleRepeatingTimer`
+-- @return The time left on the timer.
+function AceTimer:TimeLeft(id)
+ local timer = activeTimers[id]
+ if not timer then
+ return
+ else
+ return timer.ends - GetTime()
+ end
+end
+
+
+-- ---------------------------------------------------------------------
+-- Upgrading
+
+-- Upgrade from old hash-bucket based timers to C_Timer.After timers.
+if oldminor and oldminor < 10 then
+ -- disable old timer logic
+ AceTimer.frame:SetScript("OnUpdate", nil)
+ AceTimer.frame:SetScript("OnEvent", nil)
+ AceTimer.frame:UnregisterAllEvents()
+ -- convert timers
+ for object,timers in next, AceTimer.selfs do
+ for handle,timer in next, timers do
+ if type(timer) == "table" and timer.callback then
+ local newTimer
+ if timer.delay then
+ newTimer = AceTimer.ScheduleRepeatingTimer(timer.object, timer.callback, timer.delay, timer.arg)
+ else
+ newTimer = AceTimer.ScheduleTimer(timer.object, timer.callback, timer.when - GetTime(), timer.arg)
+ end
+ -- Use the old handle for old timers
+ activeTimers[newTimer] = nil
+ activeTimers[handle] = newTimer
+ newTimer.handle = handle
+ end
+ end
+ end
+ AceTimer.selfs = nil
+ AceTimer.hash = nil
+ AceTimer.debug = nil
+elseif oldminor and oldminor < 17 then
+ -- Upgrade from old animation based timers to C_Timer.After timers.
+ AceTimer.inactiveTimers = nil
+ local oldTimers = AceTimer.activeTimers
+ -- Clear old timer table and update upvalue
+ AceTimer.activeTimers = {}
+ activeTimers = AceTimer.activeTimers
+ for handle, timer in next, oldTimers do
+ local newTimer
+ -- Stop the old timer animation
+ local duration, elapsed = timer:GetDuration(), timer:GetElapsed()
+ timer:GetParent():Stop()
+ if timer.looping then
+ newTimer = AceTimer.ScheduleRepeatingTimer(timer.object, timer.func, duration, unpack(timer.args, 1, timer.argsCount))
+ else
+ newTimer = AceTimer.ScheduleTimer(timer.object, timer.func, duration - elapsed, unpack(timer.args, 1, timer.argsCount))
+ end
+ -- Use the old handle for old timers
+ activeTimers[newTimer] = nil
+ activeTimers[handle] = newTimer
+ newTimer.handle = handle
+ end
+
+ -- Migrate transitional handles
+ if oldminor < 13 and AceTimer.hashCompatTable then
+ for handle, id in next, AceTimer.hashCompatTable do
+ local t = activeTimers[id]
+ if t then
+ activeTimers[id] = nil
+ activeTimers[handle] = t
+ t.handle = handle
+ end
+ end
+ AceTimer.hashCompatTable = nil
+ end
+end
+
+-- ---------------------------------------------------------------------
+-- Embed handling
+
+AceTimer.embeds = AceTimer.embeds or {}
+
+local mixins = {
+ "ScheduleTimer", "ScheduleRepeatingTimer",
+ "CancelTimer", "CancelAllTimers",
+ "TimeLeft"
+}
+
+function AceTimer:Embed(target)
+ AceTimer.embeds[target] = true
+ for _,v in next, mixins do
+ target[v] = AceTimer[v]
+ end
+ return target
+end
+
+-- AceTimer:OnEmbedDisable(target)
+-- target (object) - target object that AceTimer is embedded in.
+--
+-- cancel all timers registered for the object
+function AceTimer:OnEmbedDisable(target)
+ target:CancelAllTimers()
+end
+
+for addon in next, AceTimer.embeds do
+ AceTimer:Embed(addon)
+end
+
+AceTimer.frame:SetScript("OnUpdate", function(self, elapsed)
+ for _, timer in next, activeTimers do
+ if not timer.cancelled then
+ if timer.timeleft > elapsed then
+ timer.timeleft = timer.timeleft - elapsed
+ else
+ if type(timer.func) == "string" then
+ -- We manually set the unpack count to prevent issues with an arg set that contains nil and ends with nil
+ -- e.g. local t = {1, 2, nil, 3, nil} print(#t) will result in 2, instead of 5. This fixes said issue.
+ safecall(timer.object[timer.func], timer.object, unpack(timer, 1, timer.argsCount))
+ else
+ safecall(timer.func, unpack(timer, 1, timer.argsCount))
+ end
+
+ if timer.looping and not timer.cancelled then
+ -- Compensate delay to get a perfect average delay, even if individual times don't match up perfectly
+ -- due to fps differences
+ local time = GetTime()
+ local delay = timer.delay - (time - timer.ends)
+ -- Ensure the delay doesn't go below the threshold
+ if delay < 0.01 then delay = 0.01 end
+ timer.ends = time + delay
+ timer.timeleft = timer.delay
+ else
+ activeTimers[timer.handle or timer] = nil
+ end
+ end
+ end
+ end
+end)
\ No newline at end of file
diff --git a/WeakAuras/Libs/LibGetFrame-1.0/AceTimer-3.0/AceTimer-3.0.xml b/WeakAuras/Libs/LibGetFrame-1.0/AceTimer-3.0/AceTimer-3.0.xml
new file mode 100644
index 0000000..38e9021
--- /dev/null
+++ b/WeakAuras/Libs/LibGetFrame-1.0/AceTimer-3.0/AceTimer-3.0.xml
@@ -0,0 +1,4 @@
+
+
+
\ No newline at end of file
diff --git a/WeakAuras/Libs/LibGetFrame-1.0/LICENCE.txt b/WeakAuras/Libs/LibGetFrame-1.0/LICENCE.txt
new file mode 100644
index 0000000..d159169
--- /dev/null
+++ b/WeakAuras/Libs/LibGetFrame-1.0/LICENCE.txt
@@ -0,0 +1,339 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This program 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 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ , 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
diff --git a/WeakAuras/Libs/LibGetFrame-1.0/LibGetFrame-1.0.lua b/WeakAuras/Libs/LibGetFrame-1.0/LibGetFrame-1.0.lua
index ad9fb2f..2bd0c97 100644
--- a/WeakAuras/Libs/LibGetFrame-1.0/LibGetFrame-1.0.lua
+++ b/WeakAuras/Libs/LibGetFrame-1.0/LibGetFrame-1.0.lua
@@ -1,342 +1,724 @@
local MAJOR_VERSION = "LibGetFrame-1.0"
-local MINOR_VERSION = 26
-if not LibStub then error(MAJOR_VERSION .. " requires LibStub.") end
+local MINOR_VERSION = 63
+if not LibStub then
+ error(MAJOR_VERSION .. " requires LibStub.")
+end
local lib = LibStub:NewLibrary(MAJOR_VERSION, MINOR_VERSION)
-if not lib then return end
+if not lib then
+ return
+end
lib.callbacks = lib.callbacks or LibStub("CallbackHandler-1.0"):New(lib)
+lib.timer = lib.timer or LibStub("AceTimer-3.0")
local callbacks = lib.callbacks
-local GetPlayerInfoByGUID, UnitExists, IsAddOnLoaded, UnitIsUnit, SecureButton_GetUnit = GetPlayerInfoByGUID, UnitExists, IsAddOnLoaded, UnitIsUnit, SecureButton_GetUnit
+local GetPlayerInfoByGUID, UnitExists, UnitIsUnit, SecureButton_GetUnit, IsAddOnLoaded =
+ GetPlayerInfoByGUID, UnitExists, UnitIsUnit, SecureButton_GetUnit, IsAddOnLoaded
local tinsert, CopyTable, wipe = tinsert, CopyTable, wipe
+function lib.Mixin(object, ...)
+ for i = 1, select("#", ...) do
+ local mixin = select(i, ...);
+ for k, v in pairs(mixin) do
+ object[k] = v;
+ end
+ end
+ return object;
+end
+
local maxDepth = 50
local defaultFramePriorities = {
- -- raid frames
- "^Vd1", -- vuhdo
- "^Vd2", -- vuhdo
- "^Vd3", -- vuhdo
- "^Vd4", -- vuhdo
- "^Vd5", -- vuhdo
- "^Vd", -- vuhdo
- "^HealBot", -- healbot
- "^GridLayout", -- grid
- "^Grid2Layout", -- grid2
- "^PlexusLayout", -- plexus
- "^ElvUF_RaidGroup", -- elv
- "^oUF_bdGrid", -- bdgrid
- "^oUF_.-Raid", -- generic oUF
- "^LimeGroup", -- lime
- "^SUFHeaderraid", -- suf
- -- party frames
- "^AleaUI_GroupHeader", -- Alea
- "^SUFHeaderparty", --suf
- "^ElvUF_PartyGroup", -- elv
- "^oUF_.-Party", -- generic oUF
- "^PitBull4_Groups_Party", -- pitbull4
- "^CompactRaid", -- blizz
- "^PartyMemberFrame", -- blizz
- -- player frame
- "^SUFUnitplayer",
- "^PitBull4_Frames_Player",
- "^ElvUF_Player",
- "^oUF_.-Player",
- "^PlayerFrame",
+ -- raid frames
+ "^Vd1", -- vuhdo
+ "^Vd2", -- vuhdo
+ "^Vd3", -- vuhdo
+ "^Vd4", -- vuhdo
+ "^Vd5", -- vuhdo
+ "^Vd", -- vuhdo
+ "^HealBot_HealUnit", -- healbot
+ "^hbPet_HealUnit", -- healbot
+ "^HealBot", -- healbot
+ "^GridLayout", -- grid
+ "^Grid2Layout", -- grid2
+ "^NugRaid%d+UnitButton%d+", -- Aptechka
+ "^PlexusLayout", -- plexus
+ "^ElvUF_Raid%d*Group", -- elv
+ "^ElvUF_RaidGroup", -- elv
+ "^oUF_bdGrid", -- bdgrid
+ "^oUF_.-Raid", -- generic oUF
+ "^LimeGroup", -- lime
+ "^InvenRaidFrames3Group%dUnitButton", -- InvenRaidFrames3
+ "^SUFHeaderraid", -- suf
+ "^LUFHeaderraid", -- luf
+ "^AshToAshUnit%d+Unit%d+", -- AshToAsh
+ "^Cell", -- Cell
+ -- party frames
+ "^AleaUI_GroupHeader", -- Alea
+ "^SUFHeaderparty", -- suf
+ "^LUFHeaderparty", -- luf
+ "^ElvUF_PartyGroup", -- elv
+ "^oUF_.-Party", -- generic oUF
+ "^PitBull4_Groups_Party", -- pitbull4
+ "^CompactRaid", -- blizz
+ "^CompactParty", -- blizz
+ "^PartyFrame", -- blizz
+ "^PartyMemberFrame", -- blizz
+ -- player frame
+ "^InvenUnitFrames_Player",
+ "^SUFUnitplayer",
+ "^LUFUnitplayer",
+ "^PitBull4_Frames_Player",
+ "^ElvUF_Player",
+ "^oUF_.-Player",
+ "^PlayerFrame",
}
+local getDefaultFramePriorities = function()
+ return CopyTable(defaultFramePriorities)
+end
+lib.getDefaultFramePriorities = getDefaultFramePriorities
local defaultPlayerFrames = {
- "SUFUnitplayer",
- "PitBull4_Frames_Player",
- "ElvUF_Player",
- "oUF_.-Player",
- "oUF_PlayerPlate",
- "PlayerFrame",
-}
-local defaultTargetFrames = {
- "SUFUnittarget",
- "PitBull4_Frames_Target",
- "ElvUF_Target",
- "oUF_.-Target",
- "TargetFrame",
-}
-local defaultTargettargetFrames = {
- "SUFUnittargetarget",
- "PitBull4_Frames_Target's target",
- "ElvUF_TargetTarget",
- "oUF_.-TargetTarget",
- "oUF_ToT",
- "TargetTargetFrame",
-}
-local defaultPartyFrames = {
- "^AleaUI_GroupHeader",
- "^SUFHeaderparty",
- "^ElvUF_PartyGroup",
- "^oUF_.-Party",
- "^PitBull4_Groups_Party",
- "^PartyMemberFrame",
-}
-local defaultPartyTargetFrames = {
- "SUFChildpartytarget%d",
-}
-local defaultRaidFrames = {
- "^Vd",
- "^HealBot",
- "^GridLayout",
- "^Grid2Layout",
- "^PlexusLayout",
- "^ElvUF_RaidGroup",
- "^oUF_.-Raid",
- "^LimeGroup",
- "^SUFHeaderraid",
- "^RaidPullout",
+ "^InvenUnitFrames_Player",
+ "SUFUnitplayer",
+ "LUFUnitplayer",
+ "PitBull4_Frames_Player",
+ "ElvUF_Player",
+ "oUF_.-Player",
+ "oUF_PlayerPlate",
+ "PlayerFrame",
}
+local getDefaultPlayerFrames = function()
+ return CopyTable(defaultPlayerFrames)
+end
+lib.getDefaultPlayerFrames = getDefaultPlayerFrames
-local GetFramesCache = {}
-local FrameToUnitFresh = {}
-local FrameToUnit = {}
-local UpdatedFrames = {}
+local defaultTargetFrames = {
+ "^InvenUnitFrames_Target",
+ "SUFUnittarget",
+ "LUFUnittarget",
+ "PitBull4_Frames_Target",
+ "ElvUF_Target",
+ "oUF_.-Target",
+ "TargetFrame",
+ "^hbExtra_HealUnit",
+}
+local getDefaultTargetFrames = function()
+ return CopyTable(defaultTargetFrames)
+end
+lib.getDefaultTargetFrames = getDefaultTargetFrames
+
+local defaultTargettargetFrames = {
+ "^InvenUnitFrames_TargetTarget",
+ "SUFUnittargetarget",
+ "LUFUnittargetarget",
+ "PitBull4_Frames_Target's target",
+ "ElvUF_TargetTarget",
+ "oUF_.-TargetTarget",
+ "oUF_ToT",
+ "TargetTargetFrame",
+}
+local getDefaultTargettargetFrames = function()
+ return CopyTable(defaultTargettargetFrames)
+end
+lib.getDefaultTargettargetFrames = getDefaultTargettargetFrames
+
+local defaultPartyFrames = {
+ "^InvenUnitFrames_Party%d",
+ "^AleaUI_GroupHeader",
+ "^SUFHeaderparty",
+ "^LUFHeaderparty",
+ "^ElvUF_PartyGroup",
+ "^oUF_.-Party",
+ "^PitBull4_Groups_Party",
+ "^PartyFrame",
+ "^CompactParty",
+ "^PartyMemberFrame",
+}
+local getDefaultPartyFrames = function()
+ return CopyTable(defaultPartyFrames)
+end
+lib.getDefaultPartyFrames = getDefaultPartyFrames
+
+local defaultPartyTargetFrames = {
+ "SUFChildpartytarget%d",
+}
+local getDefaultPartyTargetFrames = function()
+ return CopyTable(defaultPartyTargetFrames)
+end
+lib.getDefaultPartyTargetFrames = getDefaultPartyTargetFrames
+
+local defaultFocusFrames = {
+ "^InvenUnitFrames_Focus",
+ "ElvUF_FocusTarget",
+ "LUFUnitfocus",
+ "FocusFrame",
+ "^hbExtra_HealUnit",
+}
+local getDefaultFocusFrames = function()
+ return CopyTable(defaultFocusFrames)
+end
+lib.getDefaultFocusFrames = getDefaultFocusFrames
+
+local defaultRaidFrames = {
+ "^Vd",
+ "^HealBot_HealUnit",
+ "^hbPet_HealUnit",
+ "^HealBot",
+ "^GridLayout",
+ "^Grid2Layout",
+ "^PlexusLayout",
+ "^InvenRaidFrames3Group%dUnitButton",
+ "^ElvUF_Raid%d*Group",
+ "^ElvUF_RaidGroup",
+ "^oUF_.-Raid",
+ "^AshToAsh",
+ "^Cell",
+ "^LimeGroup",
+ "^SUFHeaderraid",
+ "^LUFHeaderraid",
+ "^CompactRaid",
+ "^RaidPullout",
+}
+local getDefaultRaidFrames = function()
+ return CopyTable(defaultRaidFrames)
+end
+lib.getDefaultRaidFrames = getDefaultRaidFrames
+--
+local CacheMonitorMixin = {}
+function CacheMonitorMixin:Init(makeDiff)
+ self.data = {}
+ self.cache = {}
+ if makeDiff then
+ self.makeDiff = makeDiff
+ self.added = {}
+ self.updated = {}
+ self.removed = {}
+ end
+end
+-- fill cache, added, updated
+function CacheMonitorMixin:Add(key, ...)
+ local args = select("#", ...)
+ if args > 1 then
+ if self.makeDiff then
+ if type(self.data[key]) == "table" then
+ for i = 1, args do
+ local arg = select(i, ...)
+ if self.data[key][i] ~= arg then
+ self.updated[key] = self.data[key]
+ break
+ end
+ end
+ else
+ self.added[key] = true
+ end
+ end
+ self.cache[key] = {...}
+ else
+ local value = ...
+ if self.makeDiff then
+ if self.data[key] ~= value then
+ if self.data[key] == nil then
+ self.added[key] = true
+ else
+ self.updated[key] = self.data[key]
+ end
+ end
+ end
+ self.cache[key] = value
+ end
+end
+function CacheMonitorMixin:CalcRemoved()
+ if not self.makeDiff then return end
+ for key, value in pairs(self.data) do
+ if self.cache[key] == nil then
+ self.removed[key] = value
+ end
+ end
+end
+function CacheMonitorMixin:WriteCache()
+ local tmp = self.data
+ self.data = self.cache
+ self.cache = tmp
+ wipe(self.cache)
+end
+function CacheMonitorMixin:Reset()
+ if self.makeDiff then
+ wipe(self.updated)
+ wipe(self.removed)
+ wipe(self.added)
+ end
+end
+--
+local FrameToFrameName = {} -- frame adress => frame name
+local FrameToUnit = {} -- frame adress => unitToken
+lib.Mixin(FrameToFrameName, CacheMonitorMixin)
+lib.Mixin(FrameToUnit, CacheMonitorMixin)
+FrameToFrameName:Init()
+FrameToUnit:Init(true)
+
+local profiling = false
+local profileData
+
+local function doNothing()
+end
+
+local StartProfiling = doNothing
+local StopProfiling = doNothing
+
+local function _StartProfiling(id)
+ if not profileData[id] then
+ profileData[id] = {}
+ profileData[id].count = 1
+ profileData[id].start = debugprofilestop()
+ profileData[id].elapsed = 0
+ profileData[id].spike = 0
+ return
+ end
+
+ if profileData[id].count == 0 then
+ profileData[id].count = 1
+ profileData[id].start = debugprofilestop()
+ else
+ profileData[id].count = profileData[id].count + 1
+ end
+end
+
+local function _StopProfiling(id)
+ profileData[id].count = profileData[id].count - 1
+ if profileData[id].count == 0 then
+ local elapsed = debugprofilestop() - profileData[id].start
+ profileData[id].elapsed = profileData[id].elapsed + elapsed
+ if elapsed > profileData[id].spike then
+ profileData[id].spike = elapsed
+ end
+ end
+end
+
+function lib.StartProfile()
+ if profiling then
+ print(MAJOR_VERSION, " (StartProfile) Profiling already started")
+ return false
+ end
+ profiling = true
+ profileData = {}
+ StartProfiling = _StartProfiling
+ StopProfiling = _StopProfiling
+end
+
+function lib.StopProfile()
+ if not profiling then
+ print(MAJOR_VERSION, " (StopProfile) Profiling not running")
+ return false
+ end
+ profiling = false
+ StartProfiling = doNothing
+ StopProfiling = doNothing
+end
+
+function lib.GetProfileData()
+ return profileData or {}
+end
+
+-- if frame doesn't have a name, try to use the key from it's parent
+local function recurseGetName(frame)
+ local name = frame.GetName and frame:GetName() or nil
+ if name then
+ return name
+ end
+ local parent = frame.GetParent and frame:GetParent()
+ if parent then
+ local parentKey
+ for key, child in pairs(parent) do
+ if child == frame then
+ parentKey = key
+ break
+ end
+ end
+ if parentKey then
+ return (recurseGetName(parent) or "") .. "." .. parentKey
+ end
+ end
+end
+
+--local notAUnitFrameTypeAttribute = {
+-- cancelaura = true
+--}
local function ScanFrames(depth, frame, ...)
- if not frame then return end
- if depth < maxDepth then
- local frameType = frame:GetObjectType()
- if frameType == "Frame" or frameType == "Button" then
- ScanFrames(depth + 1, frame:GetChildren())
- end
- if frameType == "Button" then
- local unit = SecureButton_GetUnit(frame)
- local name = frame:GetName()
- if unit and frame:IsVisible() and name then
- GetFramesCache[frame] = name
- if unit ~= FrameToUnit[frame] then
- FrameToUnit[frame] = unit
- UpdatedFrames[frame] = unit
- end
- FrameToUnitFresh[frame] = unit
- end
- end
+ coroutine.yield()
+ if not frame then
+ return
+ end
+ if depth < maxDepth then
+ local frameType = frame:GetObjectType()
+ if frameType == "Frame" or frameType == "Button" then
+ ScanFrames(depth + 1, frame:GetChildren())
end
- ScanFrames(depth, ...)
+ if frameType == "Button" then
+ local typeAttribute = frame:GetAttribute("type")
+ --if not notAUnitFrameTypeAttribute[typeAttribute] then
+ local unit = SecureButton_GetUnit(frame)
+ if unit and frame:IsVisible() then
+ local name = recurseGetName(frame)
+ if name then
+ FrameToFrameName:Add(frame, name)
+ FrameToUnit:Add(frame, unit)
+ end
+ end
+ --end
+ end
+ end
+ ScanFrames(depth, ...)
end
-local wait = false
+local status = "ready"
+local co
+local coroutineFrame = CreateFrame("Frame")
+coroutineFrame:Hide()
local function doScanForUnitFrames()
- wait = false
- wipe(UpdatedFrames)
- wipe(GetFramesCache)
- wipe(FrameToUnitFresh)
- ScanFrames(0, UIParent)
- callbacks:Fire("GETFRAME_REFRESH")
- for frame, unit in pairs(UpdatedFrames) do
- callbacks:Fire("FRAME_UNIT_UPDATE", frame, unit)
- end
- for frame, unit in pairs(FrameToUnit) do
- if FrameToUnitFresh[frame] ~= unit then
- callbacks:Fire("FRAME_UNIT_REMOVED", frame, unit)
- FrameToUnit[frame] = nil
- end
- end
+ if not coroutineFrame:IsShown() then
+ status = "scanning"
+ co = coroutine.create(ScanFrames)
+ coroutineFrame:Show()
+ end
end
-local waitFrame = CreateFrame("Frame")
-local function waitFrame_OnUpdate(self, elapsed)
- self.delay = (self.delay or 1) - elapsed
- if self.delay < 0 then
- doScanForUnitFrames()
- self:SetScript("OnUpdate", nil)
- self.delay = nil
- end
-end
+coroutineFrame:SetScript("OnUpdate", function()
+ local start = debugprofilestop()
+ -- Limit to 5ms per frame
+ StartProfiling("scan frames")
+ while debugprofilestop() - start < 5 and coroutine.status(co) ~= "dead" do
+ coroutine.resume(co, 0, UIParent)
+ end
+ StopProfiling("scan frames")
+ if coroutine.status(co) == "dead" then
+ StartProfiling("callbacks")
+ FrameToFrameName:WriteCache()
+ FrameToUnit:CalcRemoved()
+ FrameToUnit:WriteCache()
+ StartProfiling("callback GETFRAME_REFRESH")
+ callbacks:Fire("GETFRAME_REFRESH")
+ StopProfiling("callback GETFRAME_REFRESH")
+ -- FrameToUnit
+ if next(FrameToUnit.added) then
+ StartProfiling("callback FRAME_UNIT_ADDED")
+ for frame in pairs(FrameToUnit.added) do
+ callbacks:Fire("FRAME_UNIT_ADDED", frame, FrameToUnit.data[frame])
+ end
+ StopProfiling("callback FRAME_UNIT_ADDED")
+ end
+ if next(FrameToUnit.updated) then
+ StartProfiling("callback FRAME_UNIT_UPDATE")
+ for frame, previousUnit in pairs(FrameToUnit.updated) do
+ callbacks:Fire("FRAME_UNIT_UPDATE", frame, FrameToUnit.data[frame], previousUnit)
+ end
+ StopProfiling("callback FRAME_UNIT_UPDATE")
+ end
+ if next(FrameToUnit.removed) then
+ StartProfiling("callback FRAME_UNIT_REMOVED")
+ for frame, unit in pairs(FrameToUnit.removed) do
+ callbacks:Fire("FRAME_UNIT_REMOVED", frame, unit)
+ end
+ StopProfiling("callback FRAME_UNIT_REMOVED")
+ end
+ coroutineFrame:Hide()
+ FrameToFrameName:Reset()
+ FrameToUnit:Reset()
+ StopProfiling("callbacks")
+ if status == "scan_queued" then
+ doScanForUnitFrames("queued")
+ else
+ status = "ready"
+ end
+ end
+end)
local function ScanForUnitFrames(noDelay)
+ if status == "ready" then
if noDelay then
+ doScanForUnitFrames()
+ else
+ status = "scan_delay"
+ lib.timer:ScheduleTimer(function()
doScanForUnitFrames()
- elseif not wait then
- wait = true
- waitFrame.delay = 1
- waitFrame:SetScript("OnUpdate", waitFrame_OnUpdate)
+ end, 1)
end
+ elseif status == "scanning" then
+ status = "scan_queued"
+ end
+end
+
+function lib.ScanForUnitFrames()
+ ScanForUnitFrames(true)
end
local function isFrameFiltered(name, ignoredFrames)
- for _, filter in pairs(ignoredFrames) do
- if name:find(filter) then
- return true
- end
+ for _, filter in pairs(ignoredFrames) do
+ if name:find(filter) then
+ return true
end
- return false
+ end
+ return false
end
local function GetUnitFrames(target, ignoredFrames)
+ if not UnitExists(target) then
+ if type(target) ~= "string" then
+ return
+ end
+ local B = tonumber(target:sub(5, 5), 16)
+ if B and B % 8 == 0 then
+ target = select(6, GetPlayerInfoByGUID(target))
+ else
+ target = target:gsub(" .*", "")
+ end
if not UnitExists(target) then
- if type(target) ~= "string" then return end
- local B = tonumber(target:sub(5, 5), 16)
- if B and B % 8 == 0 then
- target = select(6, GetPlayerInfoByGUID(target))
- else
- target = target:gsub(" .*", "")
- end
- if not UnitExists(target) then
- return
- end
+ return
end
+ end
- local frames
- for frame, frameName in pairs(GetFramesCache) do
- local unit = SecureButton_GetUnit(frame)
- if unit and UnitIsUnit(unit, target)
- and not isFrameFiltered(frameName, ignoredFrames)
- then
- frames = frames or {}
- frames[frame] = frameName
- end
+ local frames
+ for frame, frameName in pairs(FrameToFrameName.data) do
+ local unit = SecureButton_GetUnit(frame)
+ if unit and UnitIsUnit(unit, target) and not isFrameFiltered(frameName, ignoredFrames) then
+ frames = frames or {}
+ frames[frame] = frameName
end
- return frames
+ end
+ return frames
end
local function ElvuiWorkaround(frame)
- if IsAddOnLoaded("ElvUI") and frame and frame:GetName():find("^ElvUF_") and frame.Health then
- return frame.Health
- else
- return frame
- end
+ if IsAddOnLoaded("ElvUI") and frame and frame:GetName() and frame:GetName():find("^ElvUF_") and frame.Health then
+ return frame.Health
+ else
+ return frame
+ end
+end
+
+local function CellGetUnitFrames(target, frames, framePriorities)
+ if not IsAddOnLoaded("Cell") or not Cell.GetUnitFramesForLGF then
+ return frames
+ end
+ return Cell.GetUnitFramesForLGF(target, frames, framePriorities)
end
local defaultOptions = {
- framePriorities = defaultFramePriorities,
- ignorePlayerFrame = true,
- ignoreTargetFrame = true,
- ignoreTargettargetFrame = true,
- ignorePartyFrame = false,
- ignorePartyTargetFrame = true,
- ignoreRaidFrame = false,
- playerFrames = defaultPlayerFrames,
- targetFrames = defaultTargetFrames,
- targettargetFrames = defaultTargettargetFrames,
- partyFrames = defaultPartyFrames,
- partyTargetFrames = defaultPartyTargetFrames,
- raidFrames = defaultRaidFrames,
- ignoreFrames = {
- "PitBull4_Frames_Target's target's target",
- "ElvUF_PartyGroup%dUnitButton%dTarget",
- "ElvUF_FocusTarget",
- "RavenButton"
- },
- returnAll = false,
+ framePriorities = defaultFramePriorities,
+ ignorePlayerFrame = true,
+ ignoreTargetFrame = true,
+ ignoreTargettargetFrame = true,
+ ignorePartyFrame = false,
+ ignorePartyTargetFrame = true,
+ ignoreFocusFrame = true,
+ ignoreRaidFrame = false,
+ playerFrames = defaultPlayerFrames,
+ targetFrames = defaultTargetFrames,
+ targettargetFrames = defaultTargettargetFrames,
+ partyFrames = defaultPartyFrames,
+ partyTargetFrames = defaultPartyTargetFrames,
+ focusFrames = defaultFocusFrames,
+ raidFrames = defaultRaidFrames,
+ ignoreFrames = {
+ "PitBull4_Frames_Target's target's target",
+ "ElvUF_PartyGroup%dUnitButton%dTarget",
+ "RavenButton",
+ "RavenOverlay",
+ "AshToAshUnit%d+ShadowGroupHeaderUnitButton%d+",
+ "InvenUnitFrames_TargetTargetTarget",
+ "CellQuickCastButton",
+ },
+ skipCellOverrides = false,
+ returnAll = false,
}
+local getDefaultOptions = function()
+ return CopyTable(defaultOptions)
+end
+lib.getDefaultOptions = getDefaultOptions
+
+local IterateGroupMembers = function(reversed, forceParty)
+ local unit = (not forceParty and GetNumRaidMembers() > 0) and 'raid' or 'party'
+ local numGroupMembers = unit == 'party' and GetNumPartyMembers() or GetNumRaidMembers()
+ local i = reversed and numGroupMembers or (unit == 'party' and 0 or 1)
+ return function()
+ local ret
+ if i == 0 and unit == 'party' then
+ ret = 'player'
+ elseif i <= numGroupMembers and i > 0 then
+ ret = unit .. i
+ end
+ i = i + (reversed and -1 or 1)
+ return ret
+ end
+end
+
+local unitPetState = {} -- track if unit's pet exists
+
+local saveGetUnitFrame
+local function fixGetUnitFrameIntegrity()
+ lib.GetUnitFrame = saveGetUnitFrame
+ lib.GetFrame = saveGetUnitFrame
+ if WeakAuras and WeakAuras.GetUnitFrame then
+ WeakAuras.GetUnitFrame = saveGetUnitFrame
+ end
+end
local GetFramesCacheListener
local function Init(noDelay)
- GetFramesCacheListener = CreateFrame("Frame")
- GetFramesCacheListener:RegisterEvent("PLAYER_REGEN_DISABLED")
- GetFramesCacheListener:RegisterEvent("PLAYER_REGEN_ENABLED")
- GetFramesCacheListener:RegisterEvent("PLAYER_ENTERING_WORLD")
- GetFramesCacheListener:RegisterEvent("PARTY_MEMBERS_CHANGED")
- GetFramesCacheListener:RegisterEvent("RAID_ROSTER_UPDATE")
- GetFramesCacheListener:SetScript("OnEvent", function() ScanForUnitFrames(false) end)
- ScanForUnitFrames(noDelay)
+ GetFramesCacheListener = CreateFrame("Frame")
+ GetFramesCacheListener:RegisterEvent("PLAYER_REGEN_DISABLED")
+ GetFramesCacheListener:RegisterEvent("PLAYER_REGEN_ENABLED")
+ GetFramesCacheListener:RegisterEvent("PLAYER_ENTERING_WORLD")
+ GetFramesCacheListener:RegisterEvent("RAID_ROSTER_UPDATE")
+ GetFramesCacheListener:RegisterEvent("PARTY_MEMBERS_CHANGED")
+ GetFramesCacheListener:RegisterEvent("UNIT_PET")
+ GetFramesCacheListener:RegisterEvent("INSTANCE_ENCOUNTER_ENGAGE_UNIT")
+ GetFramesCacheListener:SetScript("OnEvent", function(self, event, unit, ...)
+ fixGetUnitFrameIntegrity()
+ if event == "RAID_ROSTER_UPDATE" or "PARTY_MEMBERS_CHANGED" then
+ wipe(unitPetState)
+ for member in IterateGroupMembers() do
+ unitPetState[member] = UnitExists(member .. "pet") and true or nil
+ end
+ end
+ if event == "UNIT_PET" then
+ if not (UnitIsUnit("player", unit) or UnitInParty(unit) or UnitInRaid(unit)) then
+ return
+ end
+ -- skip if unit's pet existance has not changed
+ local exists = UnitExists(unit .. "pet") and true or nil
+ if unitPetState[unit] == exists then
+ return
+ else
+ unitPetState[unit] = exists
+ end
+ end
+ ScanForUnitFrames(false)
+ end)
+ ScanForUnitFrames(noDelay)
end
function lib.GetUnitFrame(target, opt)
- if type(GetFramesCacheListener) ~= "table" then Init(true) end
- opt = opt or {}
- setmetatable(opt, { __index = defaultOptions })
+ if type(GetFramesCacheListener) ~= "table" then
+ Init(true)
+ end
+ opt = opt or {}
+ setmetatable(opt, { __index = defaultOptions })
- if not target then return end
+ if not target then
+ return
+ end
- local ignoredFrames = CopyTable(opt.ignoreFrames)
- if opt.ignorePlayerFrame then
- for _,v in pairs(opt.playerFrames) do
- tinsert(ignoredFrames, v)
- end
+ local ignoredFrames = CopyTable(opt.ignoreFrames)
+ if opt.ignorePlayerFrame then
+ for _, v in pairs(opt.playerFrames) do
+ tinsert(ignoredFrames, v)
end
- if opt.ignoreTargetFrame then
- for _,v in pairs(opt.targetFrames) do
- tinsert(ignoredFrames, v)
- end
+ end
+ if opt.ignoreTargetFrame then
+ for _, v in pairs(opt.targetFrames) do
+ tinsert(ignoredFrames, v)
end
- if opt.ignoreTargettargetFrame then
- for _,v in pairs(opt.targettargetFrames) do
- tinsert(ignoredFrames, v)
- end
+ end
+ if opt.ignoreTargettargetFrame then
+ for _, v in pairs(opt.targettargetFrames) do
+ tinsert(ignoredFrames, v)
end
- if opt.ignorePartyFrame then
- for _,v in pairs(opt.partyFrames) do
- tinsert(ignoredFrames, v)
- end
+ end
+ if opt.ignorePartyFrame then
+ for _, v in pairs(opt.partyFrames) do
+ tinsert(ignoredFrames, v)
end
- if opt.ignorePartyTargetFrame then
- for _,v in pairs(opt.partyTargetFrames) do
- tinsert(ignoredFrames, v)
- end
+ end
+ if opt.ignorePartyTargetFrame then
+ for _, v in pairs(opt.partyTargetFrames) do
+ tinsert(ignoredFrames, v)
end
- if opt.ignoreRaidFrame then
- for _,v in pairs(opt.raidFrames) do
- tinsert(ignoredFrames, v)
- end
+ end
+ if opt.ignoreFocusFrame then
+ for _, v in pairs(opt.focusFrames) do
+ tinsert(ignoredFrames, v)
end
+ end
+ if opt.ignoreRaidFrame then
+ for _, v in pairs(opt.raidFrames) do
+ tinsert(ignoredFrames, v)
+ end
+ end
- local frames = GetUnitFrames(target, ignoredFrames)
- if not frames then return end
+ local frames = GetUnitFrames(target, ignoredFrames)
- if not opt.returnAll then
- for i = 1, #opt.framePriorities do
- for frame, frameName in pairs(frames) do
- if frameName:find(opt.framePriorities[i]) then
- return ElvuiWorkaround(frame)
- end
- end
+ if not (opt.ignoreRaidFrame or opt.skipCellOverrides) then
+ frames = CellGetUnitFrames(target, frames, opt.framePriorities)
+ end
+
+ if not frames then
+ return
+ end
+
+ if not opt.returnAll then
+ for i = 1, #opt.framePriorities do
+ for frame, frameName in pairs(frames) do
+ if frameName:find(opt.framePriorities[i]) then
+ return ElvuiWorkaround(frame)
end
- local next = next
- return ElvuiWorkaround(next(frames))
- else
- for frame in pairs(frames) do
- frames[frame] = ElvuiWorkaround(frame)
- end
- return frames
+ end
end
+ local next = next
+ return ElvuiWorkaround(next(frames))
+ else
+ for frame in pairs(frames) do
+ frames[frame] = ElvuiWorkaround(frame)
+ end
+ return frames
+ end
end
+saveGetUnitFrame = lib.GetUnitFrame
lib.GetFrame = lib.GetUnitFrame -- compatibility
-- nameplates
function lib.GetUnitNameplate(unit)
- if not unit then
- return
- end
- local nameplate = C_NamePlate.GetNamePlateForUnit(unit)
- if nameplate then
- -- credit to Exality for https://wago.io/explosiveorbs
- if nameplate.UnitFrame and nameplate.UnitFrame.Health then
- -- elvui
- return nameplate.UnitFrame.Health
- elseif nameplate.unitFramePlater and nameplate.unitFramePlater.healthBar then
- -- plater
- return nameplate.unitFramePlater.healthBar
- elseif nameplate.kui and nameplate.kui.HealthBar then
- -- kui
- return nameplate.kui.HealthBar
- elseif nameplate.extended and nameplate.extended.visual and nameplate.extended.visual.healthbar then
- -- tidyplates
- return nameplate.extended.visual.healthbar
- elseif nameplate.TPFrame and nameplate.TPFrame.visual and nameplate.TPFrame.visual.healthbar then
- -- tidyplates: threat plates
- return nameplate.TPFrame.visual.healthbar
- elseif nameplate.unitFrame and nameplate.unitFrame.Health then
- -- bdui nameplates
- return nameplate.unitFrame.Health
- elseif nameplate.ouf and nameplate.ouf.Health then
- -- bdNameplates
- return nameplate.ouf.Health
- elseif nameplate.slab and nameplate.slab.components and nameplate.slab.components.healthBar and nameplate.slab.components.healthBar.frame then
- -- Slab
- return nameplate.slab.components.healthBar.frame
- elseif nameplate.UnitFrame and nameplate.UnitFrame.healthBar then
- -- default
- return nameplate.UnitFrame.healthBar
- else
- return nameplate
- end
+ if not unit then
+ return
+ end
+ local nameplate = C_NamePlate.GetNamePlateForUnit(unit)
+ if nameplate then
+ -- credit to Exality for https://wago.io/explosiveorbs
+ if nameplate.UnitFrame and nameplate.UnitFrame.Health then
+ -- elvui bunny
+ return nameplate.UnitFrame.Health
+ elseif nameplate.unitFrame and nameplate.unitFrame.Health then
+ -- elvui someday
+ return nameplate.unitFrame.Health
+ elseif nameplate.unitFramePlater and nameplate.unitFramePlater.healthBar then
+ -- plater
+ -- fallback to default nameplate in case plater is not on screen and uses blizzard default (module disabled, force-blizzard functionality)
+ return nameplate.unitFramePlater.PlaterOnScreen and nameplate.unitFramePlater.healthBar or (nameplate.UnitFrame and nameplate.UnitFrame.healthBar) or nameplate
+ elseif nameplate.kui and nameplate.kui.HealthBar then
+ -- kui
+ return nameplate.kui.HealthBar
+ elseif nameplate.extended and nameplate.extended.visual and nameplate.extended.visual.healthbar then
+ -- tidyplates
+ return nameplate.extended.visual.healthbar
+ elseif nameplate.TPFrame and nameplate.TPFrame.visual and nameplate.TPFrame.visual.healthbar then
+ -- tidyplates: threat plates
+ return nameplate.TPFrame.visual.healthbar
+ elseif nameplate.unitFrame and nameplate.unitFrame.Health then
+ -- bdui nameplates
+ return nameplate.unitFrame.Health
+ elseif nameplate.ouf and nameplate.ouf.Health then
+ -- bdNameplates
+ return nameplate.ouf.Health
+ elseif nameplate.slab and nameplate.slab.components and nameplate.slab.components.healthBar and nameplate.slab.components.healthBar.frame then
+ -- Slab
+ return nameplate.slab.components.healthBar.frame
+ elseif nameplate.UnitFrame and nameplate.UnitFrame.healthBar then
+ -- default
+ return nameplate.UnitFrame.healthBar
+ else
+ return nameplate
end
+ end
end
diff --git a/WeakAuras/Libs/LibGetFrame-1.0/LibGetFrame-1.0.toc b/WeakAuras/Libs/LibGetFrame-1.0/LibGetFrame-1.0.toc
index 5c1c940..cab536a 100644
--- a/WeakAuras/Libs/LibGetFrame-1.0/LibGetFrame-1.0.toc
+++ b/WeakAuras/Libs/LibGetFrame-1.0/LibGetFrame-1.0.toc
@@ -1,10 +1,10 @@
-## Interface: 80200
+## Interface: 33000
## Title: Lib: GetFrame
## Notes: Get unit frame for a unit
## Author: Buds
## X-Category: Library
## X-License: BSD
-## Version: 03cd52d
+## Version: 1.6.3
## DefaultState: Enabled
## LoadOnDemand: 0
diff --git a/WeakAuras/Libs/LibGetFrame-1.0/LibGetFrame-1.0.xml b/WeakAuras/Libs/LibGetFrame-1.0/LibGetFrame-1.0.xml
index 727e88c..9655921 100644
--- a/WeakAuras/Libs/LibGetFrame-1.0/LibGetFrame-1.0.xml
+++ b/WeakAuras/Libs/LibGetFrame-1.0/LibGetFrame-1.0.xml
@@ -2,5 +2,6 @@
..\FrameXML\UI.xsd">
+
diff --git a/WeakAuras/Libs/LibGetFrame-1.0/README.md b/WeakAuras/Libs/LibGetFrame-1.0/README.md
index a1d2c9d..14e9168 100644
--- a/WeakAuras/Libs/LibGetFrame-1.0/README.md
+++ b/WeakAuras/Libs/LibGetFrame-1.0/README.md
@@ -7,92 +7,91 @@ Return unit frame for a given unit
```Lua
local LGF = LibStub("LibGetFrame-1.0")
local frame = LGF.GetUnitFrame(unit , options)
+
+local callback = function(event, frame, unit)
+ if event == "GETFRAME_REFRESH" then
+ -- cache was refreshed
+ end
+ if event == "FRAME_UNIT_UPDATE" then
+ -- 'frame' was updated and is now a match for 'unit'
+ end
+ if event == "FRAME_UNIT_REMOVED" then
+ -- 'frame' was updated and is no longer a match for 'unit'
+ end
+end
+
+LGF.RegisterCallback("MyAddonName", "GETFRAME_REFRESH", callback)
+LGF.RegisterCallback("MyAddonName", "FRAME_UNIT_UPDATE", callback)
+LGF.RegisterCallback("MyAddonName", "FRAME_UNIT_REMOVED", callback)
+
```
-## Options
-
-- framePriorities : array, default :
+## Public functions
```Lua
-{
- -- raid frames
- [1] = "^Vd1", -- vuhdo
- [2] = "^Vd2", -- vuhdo
- [3] = "^Vd3", -- vuhdo
- [4] = "^Vd4", -- vuhdo
- [5] = "^Vd5", -- vuhdo
- [6] = "^Vd", -- vuhdo
- [7] = "^HealBot", -- healbot
- [8] = "^GridLayout", -- grid
- [9] = "^Grid2Layout", -- grid2
- [10] = "^ElvUF_RaidGroup", -- elv
- [11] = "^oUF_bdGrid", -- bdgrid
- [12] = "^oUF.*raid", -- generic oUF
- [13] = "^LimeGroup", -- lime
- [14] = "^SUFHeaderraid", -- suf
- [15] = "^CompactRaid", -- blizz
- -- party frames
- [16] = "^SUFHeaderparty", --suf
- [17] = "^ElvUF_PartyGroup", -- elv
- [18] = "^oUF.*party", -- generic oUF
- [19] = "^PitBull4_Groups_Party", -- pitbull4
- [20] = "^CompactParty", -- blizz
- -- player frame
- [21] = "^SUFUnitplayer",
- [22] = "^PitBull4_Frames_Player",
- [23] = "^ElvUF_Player",
- [24] = "^oUF.*player",
- [25] = "^PlayerFrame",
-}
+LGF:GetUnitFrame(unit, options)
```
+Options:
+
+- framePriorities : array
+
- ignorePlayerFrame : boolean (default true)
- ignoreTargetFrame : boolean (default true)
- ignoreTargettargetFrame : boolean (default true)
-- playerFrames : array, default :
-
-```Lua
-{
- "SUFUnitplayer",
- "PitBull4_Frames_Player",
- "ElvUF_Player",
- "oUF_TukuiPlayer",
- "PlayerFrame",
-}
-```
-
-- targetFrames : array, default :
-
-```Lua
-{
- "SUFUnittarget",
- "PitBull4_Frames_Target",
- "ElvUF_Target",
- "TargetFrame",
- "oUF_TukuiTarget",
-}
-```
-
-- targettargetFrames : array, default :
-
-```Lua
-{
- "SUFUnittargetarget",
- "PitBull4_Frames_TargetTarget",
- "ElvUF_TargetTarget",
- "TargetTargetFrame",
- "oUF_TukuiTargetTarget",
-}
-```
-
-- ignoreFrames : array, default :
-
-```Lua
-{ }
-```
+- ignorePartyFrame : boolean (default false)
+- ignorePartyTargetFrame : boolean (default true)
+- ignoreRaidFrame : boolean (default false)
+- playerFrames : array
+- targetFrames : array
+- targettargetFrames : array
+- partyFrames : array
+- partyTargetFrames : array
+- raidFrames : array
+- ignoreFrames : array
- returnAll : boolean (default false)
+If returnAll is false, GetUnitFrame will return a single best match
+
+For arrays check LibGetFrame-1.0.lua code for defaults
+
+```Lua
+LGF:ScanForUnitFrames()
+```
+
+Ask lib to do a new scan of frames.
+
+This scan can take a few frames to be completed.
+
+You should not expect the cache use by LGF:GetUnitFrame to be updated in the same frame as this ScanForUnitFrames call.
+
+Use lib's callbacks to know when the cache is refresh.
+
+```Lua
+LGF:GetUnitNameplate(unit)
+```
+
+Return health bar for a nameplate unit, works with a variety of addons
+
+
+## Callbacks
+
+```Lua
+-- Fired after a scan complete and cache refreshed
+LGF.RegisterCallback("MyAddonName", "GETFRAME_REFRESH", function(event) end)
+```
+
+```Lua
+-- Fired when a frame is a new match for a unit (it does not test if it is the BEST match!)
+LGF.RegisterCallback("MyAddonName", "FRAME_UNIT_UPDATE", function(event, frame, unit) end)
+```
+
+```Lua
+-- Fired when a frame is not a new match for a unit anymore
+LGF.RegisterCallback("MyAddonName", "FRAME_UNIT_REMOVED", function(event, frame, unit) end)
+```
+
## Examples
### Glow player frame
@@ -115,15 +114,15 @@ local LGF = LibStub("LibGetFrame-1.0")
local LCG = LibStub("LibCustomGlow-1.0")
local frames = LGF.GetUnitFrame("target", {
- ignorePlayerFrame = false,
- ignoreTargetFrame = false,
- ignoreTargettargetFrame = false,
- returnAll = true,
+ ignorePlayerFrame = false,
+ ignoreTargetFrame = false,
+ ignoreTargettargetFrame = false,
+ returnAll = true,
})
for _, frame in pairs(frames) do
- LCG.ButtonGlow_Start(frame)
- --LCG.ButtonGlow_Stop(frame)
+ LCG.ButtonGlow_Start(frame)
+ --LCG.ButtonGlow_Stop(frame)
end
```
@@ -131,8 +130,58 @@ end
```Lua
local frame = LGF.GetUnitFrame("player", {
- ignoreFrames = { "Vd2.*", "Vd3.*" }
+ ignoreFrames = { "Vd2.*", "Vd3.*" }
})
```
+### Glow specific units and update glow when frames changes
+
+```Lua
+local LGF = LibStub("LibGetFrame-1.0")
+local LCG = LibStub("LibCustomGlow-1.0")
+
+-- list of units i want glowing
+local glow_units = {
+ player = true
+}
+-- track which frame is glowing per unit
+local glow_unit_frames = {}
+
+-- glow them using current cache
+for unit in pairs(glow_units) do
+ local frame = LGF.GetUnitFrame("player")
+ if frame then
+ LCG.ButtonGlow_Start(frame)
+ glow_unit_frames[unit] = frame
+ end
+end
+
+local callback = function(event, frame, unit)
+ if not glow_units[unit] then
+ return
+ end
+ -- new match for GetUnitFrame(unit), check if it's different from previous "best match" returned
+ local new_best_match = LGF.GetUnitFrame(unit)
+ if new_best_match == nil then
+ -- didn't found a best match for this unit
+ if glow_unit_frames[unit] then
+ -- stop previous glow
+ LCG.ButtonGlow_Stop(glow_unit_frames[unit])
+ glow_unit_frames[unit] = nil
+ end
+ elseif new_best_match ~= glow_unit_frames[unit] then
+ -- best match found, but different from previous one
+ if glow_unit_frames[unit] then
+ -- stop previous glow
+ LCG.ButtonGlow_Stop(glow_unit_frames[unit])
+ end
+ LCG.ButtonGlow_Start(new_best_match)
+ glow_unit_frames[unit] = new_best_match
+ end
+end
+
+LGF.RegisterCallback("MyAddonName", "FRAME_UNIT_UPDATE", callback)
+LGF.RegisterCallback("MyAddonName", "FRAME_UNIT_REMOVED", callback)
+```
+
[GitHub Project](https://github.com/mrbuds/LibGetFrame)
diff --git a/WeakAuras/Libs/LibGetFrame-1.0/stylua.toml b/WeakAuras/Libs/LibGetFrame-1.0/stylua.toml
new file mode 100644
index 0000000..7eb975a
--- /dev/null
+++ b/WeakAuras/Libs/LibGetFrame-1.0/stylua.toml
@@ -0,0 +1,5 @@
+indent_type = "Spaces"
+indent_width = 2
+column_width = 180
+line_endings = "Unix"
+quote_style = "ForceDouble"
\ No newline at end of file
diff --git a/WeakAuras/Profiling.lua b/WeakAuras/Profiling.lua
index 649597b..7427afe 100644
--- a/WeakAuras/Profiling.lua
+++ b/WeakAuras/Profiling.lua
@@ -4,7 +4,7 @@ local AddonName, Private = ...
local WeakAuras = WeakAuras
local L = WeakAuras.L
local prettyPrint = WeakAuras.prettyPrint
---local LGF = LibStub("LibGetFrame-1.0")
+local LGF = LibStub("LibGetFrame-1.0")
local profileData = {}
profileData.systems = {}
@@ -245,7 +245,7 @@ function WeakAuras.StartProfile(startType)
Private.StopProfileSystem = StopProfileSystem
Private.StopProfileAura = StopProfileAura
Private.StopProfileUID = StopProfileUID
- --LGF.StartProfile()
+ LGF.StartProfile()
end
local function doNothing()
@@ -268,7 +268,7 @@ function WeakAuras.StopProfile()
Private.StopProfileSystem = doNothing
Private.StopProfileAura = doNothing
Private.StopProfileUID = doNothing
- --LGF.StopProfile()
+ LGF.StopProfile()
currentProfileState = nil
RealTimeProfilingWindow:UnregisterAllEvents()
@@ -442,11 +442,11 @@ function WeakAuras.PrintProfile()
end
end
- --popup:AddText("")
- --popup:AddText("|cff9900ffLibGetFrame:|r")
- --for id, map in pairs(LGF.GetProfileData()) do
- -- PrintOneProfile(popup, id, map)
- --end
+ popup:AddText("")
+ popup:AddText("|cff9900ffLibGetFrame:|r")
+ for id, map in pairs(LGF.GetProfileData()) do
+ PrintOneProfile(popup, id, map)
+ end
popup:Show()
end