From 1f3704d685c332f229f72d67a2e93906259d3b7c Mon Sep 17 00:00:00 2001 From: Alice Cecile Date: Thu, 15 Apr 2021 16:52:15 -0400 Subject: [PATCH 01/16] Initial outline --- rfcs/system-driven-ui.md | 129 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 129 insertions(+) create mode 100644 rfcs/system-driven-ui.md diff --git a/rfcs/system-driven-ui.md b/rfcs/system-driven-ui.md new file mode 100644 index 00000000..40fd8f3f --- /dev/null +++ b/rfcs/system-driven-ui.md @@ -0,0 +1,129 @@ +# Feature Name: `system-driven-ui` + +## Summary + +UI widgets' behavior is defined entirely by the components they have, and the data within those components. +The logic to execute the UI is handled by Bevy systems, operating in parallel over the relevant UI widgets. + +## Motivation + +In larger teams, UI is commonly built with visual tools, rather than from code, which enables non-programming team members like artists and UI designers to participate directly. +As a result, an intermediate asset-like representation is needed, allowing large teams to organize assets cleanly rather than scattering them across the code base. + +Doing so pushes us towards a data-driven workflow that fits naturally with our ECS, and in particular, scenes. +By controlling the behavior of our widgets with components and systems, we can support this use case while allowing for seamless integration of code-driven and asset-driven UI workflows while allowing for performant and easily extensible widget behavior. + +## Guide-level explanation + +Widgets, as previously discussed in [UI Building Blocks and Styles](https://github.com/bevyengine/rfcs/pull/1) are simply entities with various components on them. +Rather than merely controlling the cosmetic style of our widgets, we can attach **functional components** to our widgets as well. + +Just like when we're using the ECS to control our game's logic, these components both store data and control behavior, by determining which systems apply to each particular `Widget` entity. +Suppose we want to create a radio-button widget. +Rather than trying to create an object with a `RadioButtonWidget` type, like we might in an object-oriented UI framework, +we create an entity with all of the components required to accomplish the desired behavior. +Think of components as behaving in an analogous fashion to traits, with the radio button behavior having trait bounds for each of the required components. + +Breaking it down into the constituents, we want our radio button to BEHAVIORS. + +Turning this into code, we get a `RadioButton` component and a couple of supporting systems. + +```rust +struct RadioButton { + // These can't be pub fields, and instead must rely on accessor methods + // to ensure internal invariants hold + options: Vec