Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

groups 2: dynamic boogaloo #3094

Draft
wants to merge 12 commits into
base: main
Choose a base branch
from

Conversation

emptyrivers
Copy link
Contributor

@emptyrivers emptyrivers commented May 16, 2021

IM BACK BABY!!!!!111
...and i have some new changes to dynamic groups to make them better. This is a preview of some new features, please feel free to checkout this branch (or install the build artifact) to try it out!

This is a mild rewrite of the Dynamic Group system, to improve perfomance in some areas, and flexibility/expressiveness in other areas. Specifically:

  • Group Per Frame is gone. That system was constraining our ability to innovate somewhat. Grow functions are back to only supporting the original format.
  • Added distributors to dynamic groups. This is essentially a function that, when given a regionData object spits out the appropriate anchor that the region should be attached to. Specifically, a distributor would look something like this:
function(regionData)
  return anchorType, anchorLocation, anchorId
end

where anchorType is one of "self", "nameplate", "unit", anchorLocation (for nameplate/unit anchor types) defines which unit frame/nameplate is desired, and anchorId is any string. The anchorType, anchorLocation, and anchorId together uniquely define an anchor, and every child of the group is distributed onto exactly one anchor. Each anchor is then sorted as per whatever options are chosen in the UI, just like normal. Then, once sorted, each anchor is fed into the grow function individually. The practical upshot is that the dynamic group will be split into multiple mini groups, each anchored to a different place.

The benefits of this system are twofold: First, we can simplify layout functions somewhat, since the grow function is no longer responsible for choosing the correct frame to anchor to. Second, we can improve performance in some common use cases, such as putting buff icons on unit frames, since we no longer need to iterate over the majority of minigroups anytime any of the other minigroups is updated.

What about my existing dynamic groups??

In this revision, the new system exists specifically on a new region type, "dynamicgroup2". Existing dynamic groups are entirely unaffected.

Type of change

  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update (i'll do it eventually in the wiki, but for now refer back to this PR)

This PR is unfinished: Here's what I know needs to be done

  • Verify that unitframe/nameplate/frame anchoring actually works
  • Various TODOs in changeset need to be addressed (lots of them are bikesheds on terminology/user facing strings, so whatever reviewers agree on is what I'll go with)
  • Nail down list of builtin distributors, and also types of anchors we want to support.
  • Nail down shape of distributor - should distributors also include the point (CENTER, TOPLEFT, etc) on the anchor? What about initial x/y offsets? Should it be a table with named fields, to allow for more tweaks in the future, or is multireturn fine? etc
  • Teach the grow function which anchor we're layouting, in case we want to design anchors to have different look/feel.
  • Layout helpers (bonus points for this - not necessary for core functionality)
  • Bikeshed the UI design some, I threw it together in a couple of hours
  • Bikeshed/learn how we're going to handle the incompatibility between old dynamic groups and the new system.

@emptyrivers emptyrivers added 🎨 Enhancement This pull request implements a new feature. 🆕 Feature Preview This is a draft intended to show a preview of an upcoming feature. labels May 16, 2021
order = order,
}
order = order + 1
local icon, title, messages = OptionsPrivate.Private.AuraWarnings.FormatWarnings(data.uid)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You want a not isTmpGroup check here and change the old comment to something like:

-- Warnings
-- One Aura/Group: Show warning of aura/group
-- Multi-selection: Nothing

The story behind that is, that for the information tab almost every setting behaves in a non-standard way. E.g. url is set on everything selected, whereas description is only edited on one aura. That doesn't fit the old common options code, and I didn't want to add even more baggage to it.

So the information code is very bare-bones and does the merging itself with some duplicated code. The idea being that some day in the future I'll rewrite it to something better and then port the other pages to a new common infrastructure...

@emptyrivers
Copy link
Contributor Author

Here's a useful toy example.

!WA:2!vB5FZnXXzCCRkC7WfifCZqiqkJqPaMMouhtm0KM0j6SLWU1b7E6SnqsR8E3TNUfoT3XU7zzzk9hQekn9hmJZ0)VJEjO)O)DhEf8mE6lGo(p6laEf0NDpjWySHMo5pA9mw60QND3N973pppRkS8yYjNHU2yTglySGh8rBse(Zt5nvr37y9cysLG5LPOE(zsvsRTizQOeXcPkwcxA1hdinM0XLUUQ8zs3SPijlDo)e(X)AV2eDBkybUDsPLDMPVxIiGkMojor8JluOqXUIK21tj(0IcIVzXUKJureklVqgNjJSSX3uwDBJtCfbjT7kdFqKOi6zuWomHRspsnbBJs)0msGGOiLCDtpAEUoJj5nzF6FnmJB2MXf0M4BZGHEERubJRg)CDOYsSsKwLezCoJ38CN3Qe(hlS0td(cSG3htSGXlhw(8LuruUjg9FcQktWlvwsJdl)9kHby(kASKUVXWtuddJhyH)BhNqcQ5PiXuU6yoTYIvmlBzk1)yWXTC8JjsP(jBjBdQ(bbHZAru0OTKrKGK2xBHWqjvvSxEoR19Tc6WjTy(gxzYTrBbvyUQgk4jcpNkZm3s1FuUXKp5d2tL4VgviXf44fA8xg4AZXnlCiBDAWkSaKmoeUIQyghN4sUZp3vRUDEK2e)BfisstpIDmBJniIGsUjj4rj1X3y9fX)gKWxpFpFZrspYo9lJD9V2t7ApnL4K2uX4N)Lyo3rH6rPpSu5meQqdioX3Wq6H0amvGdMMG4GEe3fwC(Q1ClF391i)YTE2l46UWhVZLm307fMfhpnt4htxDOkOlLwknaDwh6AilSnwXLGgnZ3i92vWp2f1PMnrF6eNvm4X73lG6LfgQ9DXSvNFXAlnVTojDizcYKDrskoEUaP12YmpZcxhJMTE)gtxPUBJ6UvCCT1hgV803bjhQ0cMWBwkjwf9KPTOGItZP(IvNF(nZ4d2ER(O)M1INxs7jibSm59ou3mjDEwlMkYHeZAY9MU6vDR60dxmhJlkT6LFSRNiuPFNvOKBvbZx5f0FUI0hfjSG8oLr9GmhpGUE57UL3aiB6He1IfN4ct1v3mOowC8gE5SyuV83Rg0KME063oJiOLQHcEPvIyk6GVvpJrTL4UbhWgluA74m3vM1DZ8QlmdVeCOApIsK06kHPT43aUSnpHJvxyIQJOHwMfskwFfi7QdvBcWY2TimEnyjCcWYWkW1GRJVF4DpsFc3hBPUOgwGRi6Kxwm7Fx9z1)NJmYiosTKEWhJFlvWjXlNxE(ZeRpmqVsheJBeXnrHKf2XwZzBQB0KVKKYSGUxL2(k6UaosFSdtX(Hc0EXtekRfFCEcutpKoZ9QpTt1Qx1jwBCVIa7zOD4cE45lK10AtDBDdloA)8k5N2vVNwdydUBGXdte5IO1KzSG(xFw7Pc)bR8EtQMAm)B8G3folCUEmCk1tYe(0cWOwPV9oUrPr(8BK2qXArBmOBwdvKGkJsId6aV9Boc8jWv2YhBYGjcVEBwkwkvA)xK8pva((WeW7atcVc6VwWHTGx1cU4Pol8U)n0B(GTrUTbjUnPd2skJUk8(WpmFmpev8(4KaCSj6n9toTWhbvG3ZsZ7n0vrRcFa8HWpYcMcUeyBHR79nJCz4aWbspXtAVD(Hnu0BJUTq)8Ybdt5HsVkt64hr9VfMV4ALxdkFuTfCMUAJLwCMkUvhoLiwa1rFidWDm9O6RvxJ6MxFQZ4rtp5EQl5pa)A4N)jp(wuAAf9TokhTXfbEE5nVW2lsmze6BCGgfGXGVfmRLxeL1msDA4y1GxxFRe8gMxpH51tAED(ZbFAH9CR5d36LHVDXUd9WOH)OIH)oc4BchboLTguGpFv4Rx(mC4MwoT1i4PtFR93RtfuFMUyPi29jnIum91gUj6OX7BiEX0Gi7nssAvawfiWBPV2dlyCQXqWh(UMlSaArieAcU6Eb7UE(gV8kCiPpV1gx82R9oTQ0rI)Md9vS0Ohnmz0DOIGytfeCM7DiGBbTSYRpGBRllaXtyDqUk8C87RAq4NYVqMbzH1qkfApaoH1xvtKAmCVOsOdSbCh4xKdAWDHFj8RqOW2c(nJcDn4b8BrGaUh8z7abG7BC)t(CU)Rp09)Dg)vFO0NTpTaCk4ZXZxUrM0FQ4BV0nvtmEZPwd(IiJq)hnsEUCR1ruo3HCVRro8ZnYFo6z8sV6MwZWdla)PIWF40dD1BAbBgzGRbs)V3qBpicPSNr8njkM37N6V7Uh7R6)c6j8FO6RZ29q9Fb1EASzGdGNS8JO2d1MawnHIWa5afgu3rfc1PDPGoUrmrW)98)G6h0Dt63A9lZvT)jsVzQQLFeSFHG)lt7))eYhXDtxSCrhp0j9LX15r0PRMoBTVI4(h(S9W8QHxRQI0M5EW9AUy3CpAbFz668)0CV2T2n3JsV2bqCApWEuME4ZDjqiQFFLG9QB4iw2DJLRfDrT6BW6bYpYg59ghBT)X1(3)

Copy link
Contributor

@InfusOnWoW InfusOnWoW left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I read through all the changes once, there quite a few repeated comments, which I repeated just to mark all points where a similar change would be good.

There are a few areas which I want to study in more detail, hopefully in the next few days.

The general idea of introducing distribute functions, which are run per regionData, and thus make updates localized to a group is pretty good. Although the combination of distributor + anchorer is currently not as powerful as the previous version.

WeakAurasOptions/RegionOptions/Group.lua Outdated Show resolved Hide resolved
.luacheckrc Outdated Show resolved Hide resolved
nameplate = function(self, anchorLocation) return WeakAuras.GetUnitNameplate(anchorLocation) end,
unit = function(self, anchorLocation) return WeakAuras.GetUnitFrame(anchorLocation) end,
frame = function(self, anchorLocation) return Private.GetSanitizedGlobal(anchorLocation) end,
aura = function(self, anchorLocation) return WeakAuras.GetRegion(anchorLocation) end, --? do we actually want this?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, my first guess would be no.

local ok, result = xpcall(distributeFunc, geterrorhandler(), regionData)
Private.ActivateAuraEnvironment()
if ok then
return result
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As far as I can see this means that a custom distributor has to use a standard anchorer for the anchorLocation -> frame mapping. And due to how the "frame" anchorer works, that makes it impossible to anchor to frames that don't have global names?

Do we need a different anchorer or a custom anchorer for that.

The old anchorers returned actual frame, instead of a frame name.

E.g. LibGetFrame's GetUnit actually has a second parameter, a options table. Currently it looks impossible to use that.

(Or maybe I haven't dug deep enough into how everything fits together.)

WeakAuras/RegionTypes/DynamicGroup.lua Outdated Show resolved Hide resolved
WeakAurasOptions/OptionsFrames/MoverSizer.lua Outdated Show resolved Hide resolved
WeakAurasOptions/WeakAurasOptions.lua Outdated Show resolved Hide resolved
WeakAurasOptions/WeakAurasOptions.lua Outdated Show resolved Hide resolved
WeakAurasOptions/WeakAurasOptions.lua Outdated Show resolved Hide resolved
WeakAurasOptions/WeakAurasOptions.lua Outdated Show resolved Hide resolved
@InfusOnWoW
Copy link
Contributor

The changes to dynamic groups from 30365b3 went missing.

local anchorers = {
self = function(self, anchorLocation) return self end,
nameplate = function(self, anchorLocation) return WeakAuras.GetUnitNameplate(anchorLocation) end,
unit = function(self, anchorLocation) return WeakAuras.GetUnitFrame(anchorLocation) end,
Copy link
Contributor

@InfusOnWoW InfusOnWoW Jun 6, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is unfourtunately a bit more involved than this.

Since some unit frames addons (Vuhdo!) have a delay until they create a frame matching a unit, the LibGetFrame library has a callback interface where we are informed if a unit -> frame mapping changed.

That's the code in the old dynamic group involving dyngroup_unitframe_monitor, which does need some massaging to make work. The existing code probably needs some changes to support you too. @mrbuds wrote that part of the code (and LibGetFrame).

Edit: That delay is also the point of the "WeakAuras.HiddenFrames" fallback in the old Unit frame anchorer.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LibGetFrame fire 3 callbacks https://github.com/mrbuds/LibGetFrame/blob/master/LibGetFrame-1.0.lua#L134
GETFRAME_REFRESH after each scan of all children of UIParent
FRAME_UNIT_UPDATE => frame, unit when a frame is associated with a new unit
FRAME_UNIT_REMOVED => frame, unit when unit is no longer associated with frame

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🎨 Enhancement This pull request implements a new feature. 🆕 Feature Preview This is a draft intended to show a preview of an upcoming feature.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants