ferronn-dev / ferronnizer

My personal WoW addon
MIT License
1 stars 0 forks source link

state support in custom actions #42

Closed ferronn-dev closed 3 years ago

ferronn-dev commented 3 years ago

This requires enough refactoring such that type handlers don't call protected stuff directly.

ferronn-dev commented 3 years ago

This is tricky and interesting. Current thinking on architecture:

Separate actions from buttons. Actions are instantiated and watch events themselves separate from any button. Similarly, buttons are instantiated and styled into bars, separate from any action.

We then need a way to tie action happenings to button happenings. We don't need the reverse because (at least currently) button presses don't affect actions, except through events the actions would already be listening for (like bag updates).

Action happenings need to just keep happening even if no button is attached. So we need something like "action state" as the bridge. Actions update action state; some new thing (actuator?) applies action state changes to relevant buttons, if any at that time.

So we need to model the action->button mapping, and we need to model "hey actuator, I did a thing". This is modeled today by having the instantiated action event handlers invoked externally and returning updates to action state. One potential complication there was different actions in different button states wanting to listen for different events, which made making a global mapping problematic. However, if we decouple actions from buttons, and we know all actions up front, we can make that global mapping from events to actions with no problem.

ferronn-dev commented 3 years ago

A reasonable starting point would probably be serializing action state somewhere rather than it being used directly to update buttons. This already sort of happens with the "lang" "programs" for things like cooldowns and tooltips, but should be expanded to texture, color, etc.

ferronn-dev commented 3 years ago

In the current structure, action implementations do not have access to their buttons; instead, the event handlers are invoked in a central eventer set up during init where the button and action have the same index and are simultaneously known. This is a connection that needs to be broken.

ferronn-dev commented 3 years ago

https://github.com/ferronn-dev/ferronnizer/blob/6483afc31aeda3795df40a66a976c5c49439a947/actions.lua#L347-L353

ferronn-dev commented 3 years ago

The mapping of button to action has to happen within the secure system. This might mean an attribute on each button, or something else that exists within the header's secure environment but is queryable externally.

ferronn-dev commented 3 years ago

... which is a little annoying because action state is the thing that is updated asynchronously, outside of the secure system. How do we then get from an updated action to the button to update?

ferronn-dev commented 3 years ago

There doesn't seem to be a clear way to "return" values from the restricted environment except through attributes.

ferronn-dev commented 3 years ago

In other words, on an action state update, do a header:GetAttribute(actionid) and it'll return the button id, if any, to actually push the update to.

ferronn-dev commented 3 years ago

Alternatively, the header can update insecure code with the mapping whenever it changes. That might be cheaper/better, but we can consider that an optimization. Either way the header is the owner of that mapping.

ferronn-dev commented 3 years ago

fdc84142fe73307e326dd1856c606087f135d94c gets us going on this journey.

Next steps:

ferronn-dev commented 3 years ago

Macrotext also needs to make it into the header for secure swapping during combat.

ferronn-dev commented 3 years ago

We should decouple this from the keysequence dream by using actionbar changes in the driver.

ferronn-dev commented 3 years ago

We're going to have to reckon with the "lang" buttons, either changing the way they work completely, or else finding a way to disable the right ones on state change.

ferronn-dev commented 3 years ago

It probably makes sense to go back to having actions handle all their own events.

ferronn-dev commented 3 years ago

We do have an example where we have to go from button to action, and that's tooltips. The other examples we have today are events that we could just have action frames listen for.

ferronn-dev commented 3 years ago

Had to dial back a bit of the secure manipulation because of #58, but that just means we need to keep the insecure stuff insecure and the secure stuff secure. And we're not quite ready for secure yet.

The "lang" stuff has been a real pain thinking through. My current thoughts are to separate action state from action button state, so we can run action programs to update action button state, and then connect buttons with action button state as necessary. That second connection won't involve "programs".

ferronn-dev commented 3 years ago

Another important step here is separating action init from button init. In other words, we should be able to init all the actions, and then in a separate step, apply their rendering to the buttons. This brings us closer to changing actions later since we'll be able to do a "full render".

ferronn-dev commented 3 years ago

Rudimentary support as of a0f3a2590775c484ab8009a2396363d463a17df6. Still more to do but the architecture is in place.