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

Field types created by impl_singleton! are opaque #15

Open
dhardy opened this issue Dec 1, 2019 · 4 comments
Open

Field types created by impl_singleton! are opaque #15

dhardy opened this issue Dec 1, 2019 · 4 comments

Comments

@dhardy
Copy link
Collaborator

dhardy commented Dec 1, 2019

When creating a widget with make_widget!{ .. }, fields cannot be accessed from outside the defining macro due to the anonymous type.

I had hoped this could be fixed with some type of type alias feature, but alas, this appears limited to trait implementations.

To some extent this can be worked around with traits, e.g. from the stopwatch example:

#[widget] display: impl HasText = make_widget!{
    frame => EmptyMsg;
    struct {
        #[widget] display: Label = Label::from("0.000"),
    }
    impl HasText {
        fn get_text(&self) -> &str {
            self.display.get_text()
        }
        fn set_string(&mut self, tk: &mut dyn TkWindow, text: String) {
            self.display.set_text(tk, text);
        }
    }
},

allowing self.display.set_text(tk, &self.dur_buf); to be called from the outer widget later.

Ideally in the above, it would be possible to directly call self.display.display.set_text(tk, ..).


Proposal: build_widget! macro

Move most of the make_widget! code into a separate macro, defining the type, and allow direct use of this.

Issue: implicit typing within make_widget! uses generics, thus the resulting type requires parameterisation on use. Ideally, we would not have to use generics but could use some type of "magic type alias".

@dhardy
Copy link
Collaborator Author

dhardy commented Dec 17, 2019

RFC 2524 should fix this.

dhardy added a commit that referenced this issue Apr 10, 2020
Yet another layer of hack on this macro. Yuck. But without
a fix for #15 or an alternative to make_widget! (which is
the only way to use grid layouts) we have no choice.
@dhardy
Copy link
Collaborator Author

dhardy commented Sep 22, 2021

Since this issue was created, the make_widget! macro has been separated from derive(Widget) and a few work-arounds added, however the fundamental issue remains: something like RFC 2524 is required to make it work properly (replacing use of generics with various hacky bounds, and allowing visibility outside of the generated code without explicit typing).

@dhardy
Copy link
Collaborator Author

dhardy commented Jul 16, 2022

Note: this is still an issue, but the macro in question has been renamed to impl_singleton!.

@dhardy dhardy changed the title No internal visibility on widgets created by make_widget! Field types created by impl_singleton! are opaque Oct 3, 2022
@dhardy
Copy link
Collaborator Author

dhardy commented Oct 3, 2022

As an experiment, tried using type_alias_impl_trait instead of type generics to declare inferred field types:

let ty = make_ident(format_args!("{singleton_ty}{}", &ty_name[1..]), span);
pre_items.append_all(quote! { type #ty = impl #bound; });

// or, for widgets with omitted type:
pre_items.append_all(quote! { type #ty = impl ::kas::Widget; });

The result appears to function identically (except where there are zero bounds, but such fields are only useful for extending the life of some object). It does not solve the issue of opaque types, nor offers any other advantage.

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

1 participant