SecondHalfGames / yakui

yakui is a declarative Rust UI library for games
Apache License 2.0
237 stars 21 forks source link

Create a generic `Graphics` trait for rendering backends to implement #88

Open kanerogers opened 1 year ago

kanerogers commented 1 year ago

Motivation

Writing a Yakui renderer is pretty easy, as the yakui-app crate is simple and well documented. However, it would be even easier if there was a single trait that a renderer had to implement. This would also open the door to being able to easily test different backends.

First draft trait

I'm not particularly good at writing generic Rust code, so I'm sure there's much easier ways to approach this. But something like this might be a good jumping off point:

trait Graphics {
    /// A wrapper the developer can populate with whatever "context" is required to communicate with the
    /// underlying graphics API.
    type GraphicsContext;

    /// A wrapper around the information required to create a "user managed" texture with this graphics API
    type TextureCreateInfo;

    /// Paint the Yakui API
    fn paint(&mut self, yak: &yakui::Yakui, context: Self::GraphicsContext);

    /// Resize the underlying surface
    fn resize_surface(&mut self, new_height: f32, new_width: f32, context: Self::GraphicsContext);

    /// Create a new "user managed" texture with the underlying graphics API and return a handle to it
    fn add_user_texture(
        &mut self,
        create_info: Self::TextureCreateInfo,
        context: Self::GraphicsContext,
    ) -> yakui::TextureId;
}
Ralith commented 1 year ago

I prefer yakui's current approach of exposing plain data which can be passed wherever. It's generally easier to dispatch data to different locations than it is to dispatch between traits, especially non-object-safe ones like the above.

LPGhatguy commented 1 year ago

I don't think we'd ever get rid of the way that the backends work today. I proposed that we implement a Graphics trait like this to effectively use only as part of yakui-app, to make it easier to test the examples across several backends.

Ralith commented 1 year ago

That sounds good, but I remain uncertain how the above could be easier to work with than, say, fn(&PaintDom).