Replies: 3 comments
-
Thoughts on
|
Beta Was this translation helpful? Give feedback.
-
Standard widget observers
I agree, this is something that we should come to a single cohesive design choice on and promote exactly one pattern for. |
Beta Was this translation helpful? Give feedback.
-
Feathers widgets
I'm still not convinced this is a problem. What challenges are these extra plugins actually causing these users? Why would they bother to onerously configure these plugins? If there's serious performance overhead to these plugins even in the absence of matching widgets that's a distinct problem, which should be resolved separately. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
I've been fortunate over the last several weeks to play with the BSN prototype extensively, and I am starting to get a sense of both its strengths and weaknesses. It should come as no surprise that while BSN does a lot to ease the pain of initially spawning a complex hierarchy, it currently does little or nothing to deal with the complexity of keeping that hierarchy up to date in response to changes in app state. However, the point is not to complain about BSN, but rather to assess the "state of bevy ui" as a whole now that BSN has been added into the picture.
My goal here is not to advocate for a particular approach, but rather to analyze the strengths and weaknesses of various approaches, and gather feedback from readers which will help in ranking them. Also, if this inspires additional experimentation that would be nice too.
I'm going to look at the following code (almost all of which was written by me) and talk about the developer experience of each:
standard_widgetsexamplestandard_widgets_observersexamplebevy_reactor_3experimentsWithin these examples, I am going to focus specifically on the task of widget states: hover, pressed, checked, disabled, and so on.
standard_widgetsThe
standard_widgetsexample relies heavily on ordinary ECS systems to manage widget states. Sadly, this involves a daunting amount of boilerplate: more than 100 lines of code dedicated to buttons alone, with similar amounts of code for each widget type. The pain points here are:Pressedrequire component removal detection. Since query filters don't support this, we have to rely on the awkwardRemovedComponentsAPI. This in turn means separate code paths for adding states as for removing them - we can't have just a single "update style" system.standard_widgets_observersThe
standard_widgets_observersuses observers rather than systems to update the widget styles. The first version had an even worse boilerplate situation than the standard widgets example. @cart 's refactoring of this reduced the amount of boilerplate, but at the cost of some fairly advanced generalizations that are hard to explain to the average user. The pain points are:One point of tension between the "systems" vs. "observers" approach is that each bias the design of components in opposite ways: systems favor mutable components (since change detection is easy, and removal detection is hard), whereas observers favor immutable components (since removal detection is easy and detecting mutations is impossible). This means that people designing their component architecture need to pick one or the other approach based on how they intend to react to changes.
featherswidgetsThe feathers widgets use essentially the same methods as
standard_widgetswith the addition of theming. The main difference is that the problems are mostly swept under the rug by putting all the system registration in a plugin. However, this too comes at a cost: the full set of feathers widgets currently entails installation of 14 plugins (5 for feathers, 5 for standard widgets, and 4 for common functions like focus management). This isn't so much of a problem for people who want to install the jumbo economy plugin, but creates complexity for people who want to include individual widgets a la carte.bevy_reactor effects
Presumably the reader already knows how systems and observers work, so there's no need to go into too much detail. With reactor effects, however, some additional explanation is needed. I'm not trying to "sell"
bevy_reactoras a solution, so much as raising the bar for what we should be trying to achieve.Bevy reactor 3 allows for dynamic effects to be inserted as part of the BSN template, similar to BSN's
onfeature. For example,insert_dynallows for a component, such asBackgroundColor, to be calculated dynamically:This has some advantages and disadvantages:
Advantages:
Disadvantages:
The effects system causes some additional overhead:
Hovered,Pressed, andInteractionDisabledcomponent tick values are compared each frame. (Each reaction contains aHashMapof component/entity tuples, and another of resource ids - these are checked to see if anything changed).The net cost in terms of execution is an exclusive system which runs a small amount of code for every reaction every frame, and a somewhat larger amount of code for reactions whose dependencies changed. This runs in a loop which is not parallelizable.
The other disadvantage of this approach is that the reactive context
Cxis not Bevy-idiomatic. It somewhat resembles the code patterns for writing exclusive systems (where you access everything via aWorldreference). It doesn't look anything like the typical system, there's no queries or dependency injection supported.One other neutral point is that bevy_reactor relies heavily on the "poor woman's trait queries" pattern: that is, it needs something like trait queries, but since that's not a feature supported by Bevy, it works around the issue by using component hooks to update a per-entity cache of dyn trait objects.
So the bottom line here is that the ergonomics are pretty nice, but there are some costs involved in getting this.
@cart
@alice-i-cecile
Beta Was this translation helpful? Give feedback.
All reactions