orbtk
                                
                                
                                
                                    orbtk copied to clipboard
                            
                            
                            
                        [Proposal] Consider refactoring Systems
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);
        }
    }
}
                                    
                                    
                                    
                                
Like Mando would say: This is the way ;-)
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.
As I mentioned in issue #112 , SVG is used to represent glyphs in colored vector fonts. I believe it's part of Adobe Creative Suite so that Adobe Illustrator can be used to edit lettering as well as icons and images. This could also allow the same vector format to be used so that there will not need to be a redundant glyph renderer for icons and fonts.