Skip to content

Full rewrite & redesign of PreonEngine #4

@Hugo4IT

Description

@Hugo4IT

Why

As proven by the lack of useful commits lately, this giant codebase is getting hard to maintain. This is mostly due to the inconsistency of it. Adding features is getting hard, because the point of PreonEngine was to not require a lot of code for a basic app, which as you might have notices, is going the wrong way. For example:

  • Adding a texture requires defining a PreonStaticRenderData, adding the texture there, remembering the index or storing it in a constant, then finally add .start_texture() to the UI.
  • Labels are very confusing at the moment
  • Can't really use the .empty_*() functions, because default styling makes them too small to see. You almost always have to write .start_*().min_size(..).expand_horizontally().

Idea

The redesigned system will look like bevy and rocket.rs, create a new builder, attach stuff (modules), start.

pub struct MyApplication {}

// PreonModule contains all functions for event handling, with default implementations
// for all of them.
impl PreonModule for MyApplication {
  fn new(config: PreonModuleConfiguration<Self>) -> Self {
    Self {
      
    }
  }

  // Blocking event handlers (not async) get fired *before* async ones, so you can
  // for example, disable the clicked button to prevent the user from clicking the
  // button twice and making the expensive, long task happen twice.
  fn button_clicked(&mut self, button: usize) {
    println!("Button({}): \"Ow!\"", button)
  }

  // For non-blocking event handlers, use the _async suffix for asynchronous versions.
  // I haven't done any multithreading/concurrency with Rust yet, so I don't know
  // how possible this idea is
  async fn button_clicked_async(&mut self, button: &mut PreonComponent) {
    // Instead of ids being strings (like in javascript), they're numbers (usize)
    // so you can define a constant like LARGE_TASK_BUTTON and use that to identify
    // your desired button.
    if button.id == LARGE_TASK_BUTTON {
      // Some long task here
    }
  }

  // Another blocking event handler
  fn window_closed(&mut self) {
    println!("Goodbye world.")
  }
}

fn main() {
  // preon_module_xml -> preon::xml
  let (ui, config) = preon::xml::from_str(include_str!("../res/app/home.xml"));

  PreonEngine::new()
    // fn attach_module<T: PreonModule>(config: PreonModuleConfiguration<T>)
    .attach_module::<PreonRenderModuleWGPU>(PreonModuleConfiguration::default())
    // I hope type inference can handle the generics for PreonModuleConfiguration
    .attach_module::<MyApplication>(PreonModuleConfiguration::default())
    // I also decided that a custom struct should be used for the root component,
    // either PreonComponentTree or PreonUI/PreonUserInterface. This would then
    // become one of the return types of preon_module_xml
    .attach_ui(ui)
    // The new PreonStaticRenderData, though I'm not sure about this one.
    .attach_data(static_data)
    // Things like window size, behaviour.
    .configure(config)
    // Now open the app
    .start();
}

File structure

File structure and naming should also be reconsidered, it can be confusing, for example:

  • PreonEngine has a rendering module, even though it doesn't include a RenderModule by default. preon_engine/rendering adds support for implementing your own RenderModules by including definitions for PreonShape and PreonRenderPass. The name makes sense, but it's confusing to newcomers.
  • In contrast to preon_engine/rendering, the preon_engine/components file is gigantic and houses all logic, rendering, layout systems and definitions for all default components, and all code to make your own. 1100+ line files are just hard to maintain, especially when it does almost everything and code is randomly placed
  • preon_module_wgpu is just kinda messed up

Currently, I am only happy with the organisation of preon_engine/types, it is very big and could possibly be split up by type. But as it isn't edited much, and it's sorted by type, that isn't top priority.

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-2 | consistencySome code seems off compared to other codeC-2 | ease of useSomething seems much harder to do than it should beM-0 | preon_engineThis issue applies solely to the preon_engine crateM-0 | preon_module_xmlThis issue applies solely to the preon_module_xml crate

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions