How do I represent application state ergonomically?

I spent a bunch of time this evening looking over the bevy docs. There’s some parts that seem like they don’t easily lend themselves to ratatui and some parts that do:

  • Each event is a Struct (or enum) that carries data for the event
  • apps are structured in systems - methods that have params that pull in their necessary parts - e.g. a system that draws to the terminal might look like:
    fn draw(terminal: ResMut<Terminal>, other_params) {
      terminal.draw(...);
    }
    
    To handle an event, you just define a method that accepts that event and whatever other components / resources it needs and register it as a system.
  • there’s a neat approach to schedules (steps that repeat in order (e.g. {pre,post,}startup, first, {pre,post,}update etc. systems can be attached to run in various steps
  • SubApp for rendering that can copy data out of app and render it while the app is still continuing to work on the next frame in another thread.
  • neat approach to writing the startup logic as plugins that add systems / resources etc. to the app when it’s being configured. A ratatui bevy app might look something like
      App::new()
          .add_plugins((
              MinimalPlugins.set(ScheduleRunnerPlugin::run_loop(frame_rate)),
              RatatuiPlugin,
          ))
          .add_systems(/* your app logic */)
          .run();
    
  • There’s a good state approach (e.g. MainScreen, SomeOtherScreen) and it includes OnEnter/OnExit events.
  • The docs have some stuff which explains things in ways obviously targeted at rust newbies in ways that I think would work well in ratatui too (like highlighting pain points, things about implementation of traits, etc.)

Downsides:

  • There seems to be a lot of stuff we’d throw away to do terminal stuff (most of the layout, style, rendering, 3d, camera, … stuff)
  • adding complexity in order to simplify apps
  • it could be worth rewriting the terminal struct and crossterm backend entirely to fit the bevy rendering ideas better (i.e. basically keep widgets and layout from Ratatui)
  • I think it might be difficult to match the Widget concepts with the systems concept (but if this works, it might be easy to make most widgets work with mouse events etc.)

I think this is something that will someday change (more likely provided by crates on top of Ratatui) I know a few people have tried various versions of things and the ideas bounce around and go into apps and then come out of apps into libs etc. E.g. crates.io: Rust Package Registry is kinda interesting as is GitHub - fiadliel/fiadtui: Simple TUI wrapper for ratatui with tokio and crossterm