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

micro components #49

Closed
mskorkowski opened this issue Nov 5, 2021 · 2 comments
Closed

micro components #49

mskorkowski opened this issue Nov 5, 2021 · 2 comments

Comments

@mskorkowski
Copy link
Contributor

Let's take micro components discussion here.

To make live easier I'm pasting original comments about the micro component way of working here:

I already mentioned "micro components". In this case two micro components would have to share state (using Rc<RefCell> which usually works fine). If micro components then had an update_view() method, you wouldn't even need to send a message but could just call that method.
For this a tracker that supports multiple views would also be interesting for efficient UI updates.

Anyway, to make my idea more tangible, I've written down some Rust-like code that represents the concept of "micro-components". Micro-components are "loose" so they need the parent to attach the root widget to its widgets. They don't need to store a clone of their parents sender but have a "data" field that holds (currently immutable) data that can be used to store senders and other stuff according to the needs of the user (to make them more flexible). They can easily be modified by their parent component and also handle messages. The view function can be called manually by using update_view(). Of course there are some possible panics but they should be easy to debug and the only other option to RefCell would be unsafe code.

What do you think? Would that make things easier for you? Is there a use-case that isn't properly covered?

struct MicroComponent<Model: MicroModel> {
   model: Rc<RefCell<Model>>,
   widgets: Rc<RefCell<Model::Widgets>>,
   data: Mode::Data, // for additional data such as senders to other components
   sender: Sender<Model::Msg>,
}

impl<Model: MicroModel> MicroComponent<Model> {
   fn new(model: Model, data: Model::Data) -> Self { ... }
   fn update_view(&self) { ... }
   fn model(&self) -> &Model { ... }
   fn model_mut(&self) -> &mut Model { ... }
   fn widgets(&self) -> &Model::Widgets { ... }
   fn send(&self, msg: Model::Msg) { ... }
   fn sender(&self) -> Sender<Model::Msg> { ... }
}

trait MicroModel {
   type Msg;
   type Widgets: MicroWidgets<Self>;
   type Data;
   
   fn update(&mut self, msg: Self::Msg, data: &Data, sender: Sender<Self::Msg>);
}

trait MicroWidgets<Model: MicroModel> {
   type Root;
   
   fn init_view(&mut self, model: &Model, sender: Sender<Mode::Msg>) -> Self;
   fn view(&mut self, model: &Model, sender: Sender<Mode::Msg>);
   fn root_widget(&self) -> Self::Root;
}
This was referenced Nov 5, 2021
@mskorkowski
Copy link
Contributor Author

For data store I've ended up writing my own variation about it. Without experiencing micro components I would not be able to do it again so either way they were useful.

@AaronErhardt I think all is ready in micro components. Can you review?

@mskorkowski
Copy link
Contributor Author

Code was merged by @AaronErhardt 3 days ago, so I'm closing this issue

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

No branches or pull requests

1 participant