Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Proposal] Consider removing widget!() macro #440

Open
kivimango opened this issue Apr 11, 2021 · 1 comment
Open

[Proposal] Consider removing widget!() macro #440

kivimango opened this issue Apr 11, 2021 · 1 comment

Comments

@kivimango
Copy link
Contributor

kivimango commented Apr 11, 2021

Context

Consider removing the widget!() macro in the next release.

Problem description & Solution

Pros:

  • Improved build times
  • Less bloated binary
  • Simpler widget creation
  • Generic widgets now could be created (ListView, TableView), see Generic widgets #322
  • no inherited properties from the widget!() macro: widgets could be defined with components only that they use

Cons:

  • More boilerplate code
  • components registration in the build() method has to be done by programmatically
  • creation of custom widgets may be more confusing to new developers -> need to be documented with examples

The structs would serve as a builder, just like now but without a macro call.
Probably the Template trait could be removed that too, but it would need to refactor the components/properties.

Examples and MockUps

For instance, the TextBlock could be defined and used as:

pub struct TextComponent {
    text: String
}

pub struct TextBlock {}
impl TextBlock {
     pub fn new(text: String) -> TextBlockBuilder {
        TextBlockBuilder::new(text)
    }
}

pub struct TextBlockBuilder {
    text: String
    
}
impl TextBlockBuilder {
    pub fn new(text: String) -> Self {
        self.text = text;
        self
    }
    
    pub fn build(bctx: &mut BuildContext) -> Entity {
        // create entity, then register its components with world
        let entity = bctx.create_entity();
        let text_component = TextComponent { text: self.text.clone() };
        bctx.register_component(entity, text_component);
        entity
    }
}

TextBlock::new("Sample text").build(bctx);

update: added cons

@FloVanGH FloVanGH pinned this issue Apr 16, 2021
@trickypr
Copy link
Contributor

trickypr commented Jan 1, 2022

Out of interest, would the usage of #[derive(...)] be a better fit than widget!()? At least from my rudimentary understanding of macros, it would function as a good alternative. It would probably solve the generic widgets problem and would be more familiar to most rust developers (I was very confused about the widgets macro when I first saw it). However, it would probably increase build times a bit and would have the same amount of bloat.

Mockup

#[derive(Debug, Clone, Default, AsAny)]
pub struct TextBlockState;

impl State for TextBlockState {
    // ...
}

#[derive(Widget)]
#[state(TextBlockState)] // My preferred solution for state, more complex to implement
struct TextBlock {
    // Another solution for state, although less clear to the reader
    #[state]
    state: TextBlockState,

    // Whatever else: ... 
}

impl Template for TextBlock {
    // ...
}

Docs

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants