Skip to content

Conversation

DJMcNab
Copy link
Member

@DJMcNab DJMcNab commented Apr 30, 2024

Functionally, this code works, but there's a lot of complexity around the different traits which have been added, which is unfortunate.

That is, the ergonomics are good, but that comes at the cost of some how understandable it is.

@DJMcNab DJMcNab requested a review from Philipp-M April 30, 2024 15:36
@DJMcNab
Copy link
Member Author

DJMcNab commented May 1, 2024

Marking as draft because the distribution of "responsibilities" between the traits isn't very clear.

I still think this pattern is viable, but the implementation is really messy

@DJMcNab DJMcNab marked this pull request as draft May 1, 2024 20:57
Copy link
Contributor

@Philipp-M Philipp-M left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but that comes at the cost of some how understandable it is.

Yep, took me some time to dive through this...
Pretty clever stuff, neat trick to do this with the SequenceCompatible trait.

What I think though, is that we should document this thoroughly (at some time, not necessarily in this PR), to avoid scaring off new Contributors with that added complexity. But what I like, is that the added complexity is mostly internal at the core, so I don't think it's necessary to have a deep understanding of all of this to just add simple stuff (widgets etc.), unless a completely new ViewSequence<SpliceElement> context is necessary (like FlexElement).

I guess we need the differentiation between the traits MasonryView and View because of FlexElement?
(I can see some use cases with having a "generic" View though anyway, maybe we somehow are able to marry/merge xilem_web with xilem_masonry with that at some point?)

One thing I'm wondering is, how much compilation time this adds (for reasonbly large view logic functions), because of added associated trait bounds (which seem to be the main culprit for added compilation time).

(Btw. related, but I prefer this, i.e. strong-typed at the expense of complexity as long as it only stays (mostly) inside of xilems implementation over dynamic typing.)

I'm cautiously approving this, but I think it's a good idea to discuss this tomorrow before merging.

};
let new_child = new_flex_child(params.into(), widget);
*child = new_child;
// TODO
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are these TODO comments, a result of copy paste, or is there really something todo? (and what?)

Btw. I think the two lines below this, could be summed up with

        self.ctx.children_changed();

couldn't it?

}

impl<'a, W: Widget + StoreInWidgetMut> WidgetMut<'a, W> {
pub(crate) fn new(parent_widget_state: &'a mut WidgetState, inner: W::Mut<'a>) -> Self {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think all of this unsafe code is only "safe" because it's only possible to construct this type within masonry isn't it?

Not super comfortable with this, because it's... well unsafe as well as (slightly) complex (not the best combination). Not sure whether all of that could be achieved with just some reference counting.


pub trait ViewElement {
type Mut<'a>;
type Erased: ViewElement;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be good to at least add some basic documentation to this trait. E.g. that this is type-erased and not necessarily a deleted element.

) -> R;
}

impl<SourceElement: ViewElement, SequenceElement: ViewElement> SequenceCompatible<SourceElement>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe put all the bounds into the where clause (for ease of understanding this)? Or is this intended?

}
}

pub struct TrivialWrapper<T>(T);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see any use of this, is this a remnant from previous experiments?

@@ -113,11 +176,16 @@ pub struct OptionSeqState<InnerState> {
}

// TODO(DJMcNab): Add the generation to the id path
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not related to this PR, but I don't think that comment is necessary anymore?

use crate::{
sequence::SequenceCompatible, ChangeFlags, ElementSplice, MasonryView, VecSplice, View,
ViewElement, ViewSequence,
};

// TODO: Allow configuring flex properties. I think this actually needs its own view trait?
pub fn flex<VT, Marker>(sequence: VT) -> Flex<VT, Marker> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(not directly related to that PR)

I'm not sure whether we actually should add the type bounds here (generally for these "component" functions).

I think for one it helps a little bit with error messages, and since I think it should only be used inside a View context, it also shows, what is actually allowed here as sequence. (But well, unfortunately it adds a lot of generic parameters obviously)

@@ -16,6 +19,13 @@ pub fn flex<VT, Marker>(sequence: VT) -> Flex<VT, Marker> {
}
}

pub fn flex_item<V>(view: V, params: impl Into<FlexParams>) -> FlexWrapper<V> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More of a UX thing and not entirely relevant to that PR, we could also achieve this via an extension trait. So that this is possible via the builder pattern (maybe also within MasonryView, to avoid extra traits? (see also e.g. here))

@DJMcNab
Copy link
Member Author

DJMcNab commented May 22, 2024

This track of work is continuing in #310

@DJMcNab DJMcNab closed this May 22, 2024
@DJMcNab DJMcNab deleted the consequential branch May 22, 2024 15:38
DJMcNab added a commit to DJMcNab/xilem that referenced this pull request May 23, 2024
DJMcNab added a commit to DJMcNab/xilem that referenced this pull request May 24, 2024
DJMcNab added a commit to DJMcNab/xilem that referenced this pull request Jun 3, 2024
github-merge-queue bot pushed a commit that referenced this pull request Jun 6, 2024
…#310)

This:
1) Renames the current/old `xilem_core` to `xilem_web_core` and moves it
to the `xilem_web/xilem_web_core` folder
2) Creates a new `xilem_core`, which does not use (non-tuple) macros and
instead contains a `View` trait which is generic over the `Context` type
3) Ports `xilem` to this `xilem_core`, but with some functionality
missing (namely a few of the extra views; I expect these to
straightforward to port)
4) Ports the `mason` and `mason_android` examples to this new `xilem`,
with less functionality.

This continues ideas first explored in #235 

The advantages of this new View trait are:
1) Improved support for ad-hoc views, such as views with additional
attributes.
This will be very useful for layout algorithms, and will also enable
native *good* multi-window (and potentially menus?)
2) A lack of macros, to better enable using go-to-definition and other
IDE features on the traits

Possible disadvantages:
1) There are a few more traits to enable the flexibility
2) It can be less clear what `Self::Element::Mut` is in the `rebuild`
function, because of how the resolution works
3) When implementing `View`, you need to specify the context (i.e.
`impl<State, Action> View<State, Action, [new] ViewCtx> for
Button<State, Action>`.

---------

Co-authored-by: Philipp Mildenberger <philipp@mildenberger.me>
github-merge-queue bot pushed a commit that referenced this pull request Jul 19, 2024
…or `Flex` in xilem (#428)

Takes ideas from #235 (in particular the masonry side).

This implements support for explicit spacers in the `Flex` view and flex
parameters for views (see examples `flex` and `mason` for more details).
It also adds a way (`AnyFlexChild`) to dynamically switch between
spacers and widgets (with optional flex parameters).
`masonry::widget::Flex::layout` is also updated to be in sync with
current druid.

---------

Co-authored-by: Daniel McNab <36049421+DJMcNab@users.noreply.github.com>
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

Successfully merging this pull request may close these issues.

2 participants