Code Flow question

So as I was debugging a prior issue I saw some weird behavior which definitely slowed down my debugging. Here is what happens:

The unit selection changes, which causes the selected unit to change. Then the selected Action gets changed which then fires off a selected action change event BEFORE the selected unit change event has triggered.

I guess I could see why this is done. But it is causing the UpdateSelectedVisual() code to be run twice, the first time with stale data on the actionButtonList, the second time with correct data. It doesn’t seem to make sense to disable the stale buttons since you’ll destroy them anyway correct.

The problems it seems to create is

  1. a bit of a performance penalty running code for objects that are just about to be destroyed
  2. it slowed down my debugging for an unrelated issue because the code flow was unexpected

But I can’t think of a simple way to fix this. Curious on thoughts here.

This one, while relatively minor in performance penalty, is rather simple to correct.

    private void SetSelectedUnit(Unit unit)
    {
        selectedUnit = unit;
        OnSelectedUnitChanged?.Invoke(this, EventArgs.Empty);
        SetSelectedAction(unit.GetAction<MoveAction>());
    }

Reversing the two lines will ensure that the OnSelectedUnitChanged fires first, but it does lead to another problem, in that the handler for OnSelectedUnitChanged calls the same method that OnSelectedUnitChanged does in our UnitActionSystemUI. For this, simply comment out/remove the line UpdateSelectedVisual();

Ok I see how that works.

It does create a responsibility then to always call SetSelectedAction immediately after invoking OnSelectedUnitChanged which I guess is no different than it was previously.

What about this one which only fires one event and leaves the UpdateSelectedVisual code as it was?

private void SetSelectedUnit(Unit unit)
{
    selectedUnit = unit;
    selectedAction = unit.GetMoveAction();
    OnSelectedUnitChanged?.Invoke(this, EventArgs.Empty);
}

I guess the root cause of my question is that I am having difficulty with quickly grasping the code flow once we use events. I wish there was some analogous equivalent to doing “ctrl-click” in the visual studio editor on the Invoke call so I can see what the list of event listeners are (without having to run the program). Any advice here?

Thanks again!

Of course, the entire idea of the Observer pattern is that we don’t know who might be listening… I don’t think even JetBrains Rider will do that one, unfortunately.

I had a feeling you’d say that! :stuck_out_tongue_winking_eye: :grinning_face_with_smiling_eyes:

I guess it’s a little different if I’m not only the event sender and the listener but also the one trying to figure out what the right abstraction is… but yes of course, I understand there are countless situations where the abstraction between the two is critical.

Perhaps this choice of abstraction will become clearer to me in a few lessons as we expand upon the list of listeners associated with the actions. It was challenging for me to reason through this particular implementation.

Thank you so much for your patience Brian!

On the bright side, you’re learning one of the inherent challenges of event driven programming, timing.

In this case, the problem (the selected action was updating before being destroyed anyways) is minor, because it’s a very small action, turning a frame on or off based on whether or not it’s the selected action. It’s inconsequential enough that nobody has noticed until somebody was debugging something else. I can be fairly confident that games by big studios have shipped UI that does this with no issues noticed by anybody.

On the other hand, there are other circumstances where such a double transaction could actually cause real harm, not necessarily things related to games and Unity, but by considering how these events can interact now could help us in a future endeavour. Web applications come to mind, where virtually everything is event driven. Fetching an image from a server twice is significantly more of a drain on resources, for example, than turning an image on and off in UI.

Yes. I can vouch for that. My earlier experience is with ecommerce and with B2B SaaS. Not as an engineer but technical enough to be familiar with the issues. What always helped me wrap my head around it was having lots (e.g. 1000’s ) of events and event listeners. The scale sharpened the clarity for me of what each side was responsible for.

Along those lines, I just finished the next lesson now and it’s useful to see the same pattern be re-used within this game.

1 Like

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms