-
-
Notifications
You must be signed in to change notification settings - Fork 317
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
Allstates helper methods #5195
base: main
Are you sure you want to change the base?
Allstates helper methods #5195
Conversation
An experimental build of WeakAuras with the changes in this pull request is available here. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like the idea, in general.
have you considered "just" making those functions be part of a mixin so that they magically appear as methods of tsu states param? or is that maybe going too far 🤔
allstates:Update(state, key) create or update a state table key is nilable and default to "" state.show and state.changed are automatically set allstates:Remove(key) set state.show = false & state.changed = true for allstates[key] allstates:RemoveAll() set state.show = false & state.changed = true for each state of allstates Each method return true if any change was made to the allstates table
WeakAuras/TSUHelpers.lua
Outdated
return changed | ||
end | ||
|
||
---@type fun(states: states, newState: state, key: key): boolean |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That feels like the wrong order to me, "key, state" feels a lot more natural to me.
I know you did that for key to be optional, but I still feel that its the wrong order.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
swapped them, and made update function check differences recursively (eg. for overlays)
It's not impossible that we could magic that inconvenience away, though it might be considered breaking. Currently, we apply new state to its region if:
In order for changes to be applied, author must return true. Common shibboleth is to just always return true and the end of TSU. But consider this:
In order for changes to be applied, author can simply let the function fall through without returning (thus, no ... so after writing it out, it's definitely a breaking change (though, possibly low impact - how many people actually use the TSU return value as designed?), but it does afford us the nice advantage of not having to manually track if any state is changed. main downsides:
|
well, that is all probably beyond the scope of this ticket anyways. |
What if states:Update/Remove/RemoveAll set a hidden flag RunTriggerFunc : -- if( (ok and returnValue) or optionsEvent) then
++ if( (ok and (returnValue or (returnValue ~= false and allStates.__changed))) or optionsEvent) then
++ allStates.__changed = nil
for id, state in pairs(allStates) do
if (state.changed) then
if (Private.ActivateEvent(id, triggernum, data, state)) then
updateTriggerState = true; |
edit: i'm an idiot, should have edited the code block a few lines up |
This require usage of allstates' Update/Remove/RemoveAll
@emptyrivers with 3b04d7a there is no need to return true when Update|Remove|RemoveAll functions made a change to allStates table. |
@@ -639,9 +639,10 @@ local function RunTriggerFunc(allStates, data, id, triggernum, event, arg1, arg2 | |||
else | |||
ok, returnValue = xpcall(data.triggerFunc, errorHandler, allStates, event, arg1, arg2, ...); | |||
end | |||
if (ok and returnValue) then | |||
if (ok and (returnValue or (returnValue ~= false and allStates.__changed))) then |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it is perhaps a tiny bit weird that code which doesn't use the utility functions can set __changed = true
but on balance i think it's fine
technically a breaking change for any code that used |
So, I have lots of thoughts about this. When I designed the new trigger state mechanism a long tiem ago, I did consider various ways in which triggers communicate what has changed with the rest of WA. The ideal interface is that the user just writes to the states table and each state, and WA handles the syncing of that to the display/conditions/text replacement/dynamic groups and so on. I rejected that, because this makes the case that nothing has actually changed pretty expensive, and that's not an uncommon case at all. That's why the user and triggers have to return true, and why the have to set .changed to true. Similarly the only purpose of .show = false, is that it's easier to check for than a missing cloneId. The second tricky question back then, how granular should the change tracking be. I quickly settled on one changed flag. I've been thinking about a new trigger state framework, which rexamines those two things and maybe gets us that ideal interface and a finer change tracking and even some further optimization potential, though it's been on the always long future ideas list. (It's not too unsimilar to what rivers did to the dynamic group,) Now, so the question for me is, is that an idea I'll ever come around to, and if so, how does this PR interact with that. I'll try to do a bit of experimentation |
In practice people are lazy and i see all the time auras that overwrite allstates table without caring if anything was changed, and return true in any case, even if allstates table wasn't touched (like CLEU:SPELL_AURA_APPLIED => guid ~= myGUID => return true) This keep old behavior, while giving access to simplified method to make code that doesn't fall in these traps (and you can still return false) I was also thinking this would help with idea to convert current generic triggers to small/efficient/readable enough TSU |
Yes I agree that in pratice people don't use changed very much, so in that sense the API is less than ideal and certainly your changes are an improvement as that makes editing states easier. The concern I have is that introducing such a convenient API might clash with future changes on how TSU triggers work. That is if we add a TSUv2, where the api is just setting up states and WA handles the rest automatically, without any requirement to set .changed or even return true, then this might be a dead-end API, and adding it will just confuse users. I've started a bit of research if that "perfect" api is possible and so far so good. My small prototype does behave like I want it to behave, and I want to push it a bit further to decide whether that's going to be the next "big" project I want to tackle. It's something I have been considering for a while and it would unlock a bunch of potential features. In any case, I don't intend to take too long to figure out what the right direction is. |
I'm glad this PR is giving you motivation for greater changes, but take the time you need |
Add methods to the states/allstates table that helps with creating, updating or remove states in an optimized way
Advantage of using this function instead of doing a states[key] = { ... }
progressType
,expirationTime
,icon
,show
,changed
return true
when using these functions and any change was madeExamples
with clones
maintaining value of the variablechanged
when editing multiple clones is not great :(