Skip to content

[Proposal] Consider refactoring Systems #441

@kivimango

Description

@kivimango

Context

Consider refactoring some systems in the next release.

Problem description & Solution

As of now, some states contains logic that could be moved to systems.
Pros:

  • to be more ECS-y: components holds data, systems holds logics (States is still a component i think)
  • composition: if you want a specific behavior, just add the component to the widget, and it will automatically "inherit" the desired behavior by executing logic in systems that operates on that components.
  • easier to debug and benchmark: since logic would be in systems, the developers have to look up in one place only (now some logic is scattered all around the codebase)

I think the following systems could be added:

  • TextInputSystem: it would operate on widgets that has the TextComponent, a FocusComponent and the TextInputComponent:
  • TextRenderingSystem: we already have the code for rendering text, it should be moved into a TextRenderingSystem: after all,
    all text rendering is the same.It would operate on widgets that has TextCompnonent and FontComponent.
  • LocalizationSystem: it would operate on widgets that has the TextComponent and LocalizationComponent.

The components must be documented with examples, and mention what systems they used by.
The Systems must be documented too: what components they operate on.

Examples and MockUps

For instance, text input and text rendering logic could be moved into a TextInputSystem and a TextRenderingSystem.

pub struct TextComponent {
    text: String
}

pub struct FocusComponent {
    tab_index: usize,
    focused: bool.
    request_focus: bool,
}

pub struct TextInputComponent {
    char: u8,
    event: KeyboardEvent
}

pub struct TextInputComponent {
   // a closure that runs after a key strike: contains a custom logic that handles the key event
    callback: TextInputCallback
}

impl  TextInputComponent {
    fn run(&mut self) {
        // receive key strike events from shell
        // select widget that is focused and has the TextInputcomponent, TextComponent and FocusComponent
        // fetch and run custom callback
    }
}

TextRenderingSystem:

pub enum FontStyle {
    Bold,
    Normal,
    Italic,
    Underlined,
    Strikethrough
}

pub struct FontComponent {
    font_family: String,
    font_size: usize,
    font_style: FontStyle
}

pub struct TextRenderingSystem {
    renderer: Renderer
}

impl TextRenderingSystem {
    fn run(&mut self, world: &mut World) {
        for(text, font) in world.entities() {
            renderer.render_font(text, font.font_family, font.font_size);
        }
    }
    
}

LocalizationSystem:

pub enum Locale {
    us_US,
    de_DE,
    hu_HU
}

pub struct LocalizationComponent {
    dictionary: HashMap<String, String>,
    locale: Locale,
    key: String,
}

pub struct LocalizationComponent {}

impl LocalizationComponent {
    fn run(&mut self, world: &mut World) {
        // change the text of the widget based on its localization
        for entity in world.entities() {
            let text = world.get::<TextComponent>(entity);
            let loc = world.get::<LocalizationComponent>(entity);
            text.text = loc.dictionary.get(loc.key);
            world.set::<TextComponent>(text, entity);
        }
    }
}

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions