#Weird lifetime issue

201 messages · Page 1 of 1 (latest)

tardy garden
#

```error: implementation of iced::application::View is not general enough
--> src/main.rs:262:5
|
262 | iced::run("main", MyApp::update, |arg0: &MyApp| MyApp::view(&mut *arg0))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of iced::application::View is not general enough
|
= note: {closure@src/main.rs:262:38: 262:52} must implement iced::application::View<'0, MyApp, Message, MyTheme, iced_renderer::fallback::Renderer<iced_wgpu::Renderer, iced_tiny_skia::Renderer>>, for any lifetime '0...
= note: ...but it actually implements iced::application::View<'1, MyApp, Message, MyTheme, iced_renderer::fallback::Renderer<iced_wgpu::Renderer, iced_tiny_skia::Renderer>>, for some specific lifetime '1

fn main() -> iced::Result {
iced::run(..., |arg0: &MyApp| MyApp::view(&mut *arg0))
}```

    fn view(&mut self) -> iced::Element<'_, Message, MyTheme>{
        
        let grid: Grid<GridMessage, MyTheme> = Grid::new(
            self.grid.rows_mut_iter().map(|row| RowData {
                cells: std::mem::take(&mut row.cells), // Move `cells` instead of cloning
            }),
            container::Style {
                background: Some(Background::Color(Color::WHITE)),
                ..Default::default()
            },
            |_offset: iced::widget::scrollable::AbsoluteOffset| GridMessage::Sync,
            400.0,
            400.0,
            Size::new(100.0, 100.0),
            MyTheme::Main
        );
         iced::Element::new(Wrapper {
             content: Box::new(&self.grid),
             target: Style,
             theme: self.grid.theme.clone(),
             style: self.grid.style,
         })
     }```
Repo:
https://github.com/SpiderUnderUrBed/iced-calendar-rs/tree/testing
My relevent library (I am working on it, so i am willing to make changes, the whole calender thing is a proof of concept):
https://github.com/SpiderUnderUrBed/iced_grid/tree/testing2
crimson plank
tardy garden
# crimson plank the problem is the `&mut *arg` pretty sure. why does your view method need an `&...

That is because I needed to make veiw a mutable version of itself, otherwise i get this issue
cannot borrow `self.grid` as mutable, as it is behind a `&` reference `self` is a `&` reference, so the data it refers to cannot be borrowed as mutablerustcClick for full compiler diagnostic main.rs(180, 13): consider changing this to be a mutable reference: &mut self

        
        let grid: Grid<GridMessage, MyTheme> = Grid::new(
            self.grid.rows_mut_iter().map(|row| RowData {
                cells: std::mem::take(&mut row.cells), // Move `cells` instead of cloning
            }),
            container::Style {
                background: Some(Background::Color(Color::WHITE)),
                ..Default::default()
            },
            |_offset: iced::widget::scrollable::AbsoluteOffset| GridMessage::Sync,
            400.0,
            400.0,
            Size::new(100.0, 100.0),
            MyTheme::Main
        );

         iced::Element::new(Wrapper {
             content: Box::new(&self.grid),
             target: Style,
             theme: self.grid.theme.clone(),
             style: self.grid.style,
         })
     }
    ```
snow matrix
#

example:
tic tac toe grid
every cell is a variant of a two variant enum
in your state, store a Vec<Vec<Cell>> where Cell is enum Cell { X, O }
then in your view, make a Grid from your cells

i doubt you can store custom elements in your grid (what would be a good enough usecase to need that? your calendar app is probably just storing text in the cells)

tardy garden
#

@snow matrix Here is the thing, I store three diffrent types of data, only one element, and that is the container

#

I dont think there is any workaround for container

#

and container lets you have ANY widget for it

#

I dont want people to be limited to my custom data types

pure marsh
#

are you still having the same issue?

snow matrix
#

but the point is that the element in the container has some meaning to it (maybe it is showing the time, or showing some text) so the iced state should store that time or that text

#

then the element should be created in view

tardy garden
#

what are you suggesting the container type should be

snow matrix
#

because view is for displaying your state, not getting elements out of your state to render them

tardy garden
#

i mean this is unrealted to my original issue, but what should i store for container

snow matrix
#

but you still need to store non-element data in the state

tardy garden
snow matrix
#

yes

#

correct

tardy garden
#

Ok, but its not nessesary for me to change the container type to element, as container has some specific feilds and such and it would mean i essentially re-impliment it, but i do get what you are saying

tardy garden
# snow matrix yes

But what would the code look like to position the elements? following how iced usually does things, (refer to draw and layout)

#

because whether they are created or not in the draw or layout function, in both cases, I cannot render them for some reason

snow matrix
snow matrix
#

it would be position based

tardy garden
#

so it should have shown the container with text

#

e.g:
row.push_container(container("New Cell").center(100));

snow matrix
#

what was the code in draw for containers

#

you could even have a column of rows for your grid and not impl widget in this case

tardy garden
tardy garden
# snow matrix what was the code in `draw` for containers
                for (row_index, row) in self.rows.iter().enumerate() {
                    for (col_index, cell) in row.cells.iter().enumerate() {
                        let child_index = row_index * cols + col_index;
                        //println!("B");
                    if let Some(bounds) = layout
                        .children()
                        .nth(child_index)
                        .map(|child| child.bounds())
                    {
                            match cell {
                                Cell::Container(container) => {
                                    // println!("{:#?}", layout);
                                    // println!("{:#?}", tree);
                                    container.draw(
                                        tree,
                                        renderer,
                                        &theme.resolve_theme(),
                                        style,
                                        layout,
                                        cursor,
                                        viewport,
                                    );
                                    print!("Matched")
                                }
                                _ => {
                                    //print!("Not matched")
                                }
                            }
                        }
                    }
                }```
#

this is the main peice of code

#

in the draw function

#

container is matched, iirc it printed matched

#

Weird thing is, the initial renderer is correct, because I ran a fill_quad function and it drew a quad, so idk whats the issue with the arguments I am passing it

#

maybe the issue is, i am not supposed to pass the same arguments for every single cell, as in, they would have their own like, unique layout or tree, but i tried that too

snow matrix
#

is the style making it invisible

#

or its drawing out of the screen

tardy garden
#

idk how to debug this issue, I mean, I am supposed to draw the widgets with or inside their nodes, nodes are what you use to position it from within a widget, when i print the location of a node, it is exactly as I expect it to be, however I dont think i can print the position of a widget

tardy garden
#

cannot borrow `self.grid` as mutable, as it is behind a `&` reference `self` is a `&` reference, so the data it refers to cannot be borrowed as mutablerustcClick for full compiler diagnostic main.rs(180, 13): consider changing this to be a mutable reference: `&mut self

impl MyApp {
    fn view(&self) -> iced::Element<'_, Message, MyTheme>{
        
        let grid: Grid<GridMessage, MyTheme> = Grid::new(
            self.grid.rows_mut_iter().map(|row| RowData {
                cells: std::mem::take(&mut row.cells), // Move `cells` instead of cloning
            }),
            container::Style {
                background: Some(Background::Color(Color::WHITE)),
                ..Default::default()
            },
            |_offset: iced::widget::scrollable::AbsoluteOffset| GridMessage::Sync,
            400.0,
            400.0,
            Size::new(100.0, 100.0),
            MyTheme::Main
        );

         iced::Element::new(Wrapper {
             content: Box::new(&self.grid),
             target: Style,
             theme: self.grid.theme.clone(),
             style: self.grid.style,
         })
     }

This was because you said I shouldnt store the widget, and instead construct it with my data

#

So i am trying to do that, but when i access self.grid, well it needs to be mutable

#

but i cant take in a mutable parameter

snow matrix
#

whats the type of self.grid?

tardy garden
#

Yeah it cant be mutable

tardy garden
# snow matrix whats the type of self.grid?

it was mutable, however when i remove the mut, i get alot of errors:

            rows,
            container::Style {
                background: Some(Background::Color(Color::WHITE)),
                ..Default::default()
            },
            |_offset: iced::widget::scrollable::AbsoluteOffset| UiMessage::Sync.into(),
            400.0,
            400.0,
            Size::new(100.0, 100.0),
            MyTheme::Main
            
        );```
```error[E0596]: cannot borrow `grid` as mutable, as it is not declared as mutable
  --> src/main.rs:60:13
   |
60 |         let grid: Grid<Message, MyTheme> = Grid::new(
   |             ^^^^ not mutable
...```
#

this is weird because I dont declare Grid mutable anywhere, I mean, I am changing the data, so I dont know if it can work as immutable and for me to construct it

snow matrix
snow matrix
tardy garden
# snow matrix <@609490386238308352>
pub struct Grid<Message, Theme>
where
    Theme: style::Catalog,
{
    rows: Vec<RowData>,
    pub style: <Theme as style::Catalog>::Style,
    pub theme: Theme,
    on_sync: fn(scrollable::AbsoluteOffset) -> Message,
    width: f32,
    height: f32,
    intrinsic_size: Size,
}
#

?

tardy garden
#

when i initially construct it

snow matrix
#

whats the definition of self.grid in MyApp

tardy garden
# snow matrix whats the definition of self.grid in MyApp

impl Default for MyApp {
    fn default() -> Self {
        let rows = vec![];

        
        let grid: Grid<Message, MyTheme> = Grid::new(
            rows,
            container::Style {
                background: Some(Background::Color(Color::WHITE)),
                ..Default::default()
            },
            |_offset: iced::widget::scrollable::AbsoluteOffset| UiMessage::Sync.into(),
            400.0,
            400.0,
            Size::new(100.0, 100.0),
            MyTheme::Main
            
        );

        
        let mut row = RowData::default();
        row.push_text("Row 1, Cell 1".into());
        row.push_button("Add Row".into(), CellMessage::Clicked);
        row.push_button("Add Cell".into(), CellMessage::Clicked);
        row.push_container(container("New Cell").center(100));
        grid.add_row(row);
        let mut row2 = RowData::default();
        grid.add_row(row2);
        
        grid.add_cells_to_all_rows(5);
        grid.style(
            container::Style {
                background: Some(Background::Color(Color::BLACK)),
                ..Default::default()
            }
        );
        
        


        MyApp { grid }```
#

is it what I said

#

MyApp is constructed with grid

snow matrix
#

self.grid needs to be a Vec<Vec<_>>

#

just data no widgets

tardy garden
#

which is not ideal

#

my code atm

snow matrix
#

and you are still creating a grid in default

tardy garden
# snow matrix but you have to do that

Thats probably inefficent code with some overhead, iirc elm arcitecture isnt about recreating everything whenever there is a update, its about, detecting a update, and changing the relevent part

snow matrix
#

but all iced widgets do that

tardy garden
#

Oh. In that case ill recreate it

snow matrix
#

everything in iced does that

tardy garden
# snow matrix and you are still creating a grid in default

But i am not storing it in the state, what goes into veiw is not a common widget, its a widget constructed with all the data previously made, i mean, I can do some stuff to make it a bit less jank, maybe move all grid data to veiw, but i am not storing it in state and it should be fine now

snow matrix
#

you should not have a Grid::new in default

#

you should have something like

[
  [Text("Row 1, Cell 1"), Button("Add Row"), Button("Add Cell"), Centred("New Cell", 100), None, None, None, None, None]
  [None, None, None, None, None]
]

in self.grid

#

the style call should be in view too

tardy garden
#
        let mut row = RowData::default();
        row.push_text("Row 1, Cell 1".into());
        row.push_button("Add Row".into(), CellMessage::Clicked);
        row.push_button("Add Cell".into(), CellMessage::Clicked);
        row.push_container(container("New Cell").center(100));
        let mut row2 = RowData::default();
        let resulting_rows = RefCell::new(vec![ row, row2 ]);

        MyApp { resulting_rows }```
#

Now, I do not store my widgets in state, now, I need help with fixing the widget so it renders

snow matrix
#

you still store widgets in state

snow matrix
#

you can name it GridData

#

and then in view, create a grid from this data

tardy garden
#
    fn default() -> Self {

        let mut row = RowData::default();
        row.push_text("Row 1, Cell 1".into());
        row.push_button("Add Row".into(), CellMessage::Clicked);
        row.push_button("Add Cell".into(), CellMessage::Clicked);
        row.push_container(container("New Cell").center(100));
        let mut row2 = RowData::default();
        let resulting_rows = RefCell::new(vec![ row, row2 ]);

        MyApp { resulting_rows }
    }
}
impl MyApp {

    fn view(&self) -> iced::Element<'_, Message, MyTheme> {
        let rows = std::mem::take(&mut *self.resulting_rows.borrow_mut());

        let grid: Grid<Message, MyTheme> = Grid::new(
            rows, // Consume the rows for the grid
            container::Style {
                background: Some(Background::Color(Color::WHITE)),
                ..Default::default()
            },
            |_offset: iced::widget::scrollable::AbsoluteOffset| Message::Grid(GridMessage::Sync),
            400.0,
            400.0,
            Size::new(100.0, 100.0),
            MyTheme::Main,
        );


        iced::Element::from(grid)
    }```
#

Wdym i store it in state

#

the only thing i am storing in the rows

#

when you were talking about state, i assumed you were talking about how i stored it in my app

snow matrix
tardy garden
#

Where?

snow matrix
#

self.resulting_rows[0]

#

has a container in it

tardy garden
#

@snow matrix What would GridData look like?

Does rust have something like extended, like, i assume GridData is just Grid but without a widget implimentation, this is grid:

pub struct Grid<Message, Theme>
where
    Theme: style::Catalog,
{
    rows: Vec<RowData>,
    pub style: <Theme as style::Catalog>::Style,
    pub theme: Theme,
    on_sync: fn(scrollable::AbsoluteOffset) -> Message,
    width: f32,
    height: f32,
    intrinsic_size: Size,
}
#

Also is there like, a point to GridData? it would like, essentially have the same feilds, i mean, ig i can have it, does rust have like, the abbility to extend feilds

snow matrix
#

there are only specific types of data which can be in the cells

#

and rust does not have the ability to extend fields outside macros

tardy garden
# snow matrix it does not have any widget information in it

How do i make a GridData that kinda looks like this:


struct ExtendedUser {
    base: BaseUser,
}

trait Protocol {
    fn f(&self);
}

impl Protocol for BaseUser {
    fn f(&self) {
        println!("<BaseUser as Protocol>::f called");
    }
}

impl Deref for ExtendedUser {
    type Target = BaseUser;

    fn deref(&self) -> &Self::Target {
        &self.base
    }
}```
#

Like

#

Grid contains GridData but re-uses its feilds

#

you can kinda do that with De-Ref but idk how to make that work

#

I dont want to brick my existing code

#

Ok fixed

#

@snow matrix
Done.

    fn default() -> Self {

        let mut row = RowData::default();
        row.push_text("Row 1, Cell 1".into());
        row.push_button("Add Row".into(), CellMessage::Clicked);
        row.push_button("Add Cell".into(), CellMessage::Clicked);
        row.push_container(container("New Cell").center(100));
        let mut row2 = RowData::default();
        let resulting_rows = RefCell::new(vec![ row, row2 ]);

        MyApp { resulting_rows }
    }
}
impl MyApp {
    fn view(&self) -> iced::Element<'_, Message, MyTheme> {
        let rows = std::mem::take(&mut *self.resulting_rows.borrow_mut());

        let grid: Grid<Message, MyTheme> = Grid { 
            data: GridData::new(
                rows, // Consume the rows for the grid
                container::Style {
                    background: Some(Background::Color(Color::WHITE)),
                    ..Default::default()
                },
                |_offset: iced::widget::scrollable::AbsoluteOffset| Message::Grid(GridMessage::Sync),
                400.0,
                400.0,
                Size::new(100.0, 100.0),
                MyTheme::Main,
            ),
         };

        // iced::Element::new(grid.into())
        iced::Element::from(grid)
    }```
#

Now what?

crimson plank
#

yes

tardy garden
#

How experinced are you with iced

crimson plank
#

not very

#

but I know that the whole point of iced is that view takes a &State and therefore doesn't modify the state

tardy garden
#

Ah ok, well idk if you can help me with this

#

Do you know why the container or any varient of Cell cant render?

snow matrix
tardy garden
snow matrix
#

create GridData in default

#

then in view, convert a GridData to a Grid

tardy garden
# snow matrix create GridData in default
impl Default for MyApp {
    fn default() -> Self {

        let mut row = RowData::default();
        row.push_text("Row 1, Cell 1".into());
        row.push_button("Add Row".into(), CellMessage::Clicked);
        row.push_button("Add Cell".into(), CellMessage::Clicked);
        row.push_container(container("New Cell").center(100));
        let mut row2 = RowData::default();
        //let resulting_rows = RefCell::new(vec![ row, row2 ]);
        //let fixed_rows = std::mem::take(&mut *resulting_rows.borrow_mut());

        let fixed_rows = vec![ row, row2 ];
        let grid_data: RefCell<GridData<Message, MyTheme>> = RefCell::new(GridData::new(
            fixed_rows, // Consume the rows for the grid
            container::Style {
                background: Some(Background::Color(Color::WHITE)),
                ..Default::default()
            },
            |_offset: iced::widget::scrollable::AbsoluteOffset| Message::Grid(GridMessage::Sync),
            400.0,
            400.0,
            Size::new(100.0, 100.0),
            MyTheme::Main,
        ));
        MyApp { grid_data }
    }
}
impl MyApp {
    fn view(&self) -> iced::Element<'_, Message, MyTheme> {
        let borrowed_grid_data = std::mem::take(&mut *self.grid_data.borrow_mut());
        let grid: Grid<Message, MyTheme> = Grid { 
            data: borrowed_grid_data
         };

        // iced::Element::new(grid.into())
        iced::Element::from(grid)
    }

    fn update(&mut self, message: Message) {
        let borrowed_grid_data = std::mem::take(&mut *self.grid_data.borrow_mut());
        let mut grid: Grid<Message, MyTheme> = Grid { 
            data: borrowed_grid_data
         };```
#

this?

snow matrix
#

and why std::mem::take

#

and why does grid need a mutable

tardy garden
#

it has to be owned and mutable

#

idk i could figure out some way to fix it but it already works

snow matrix
#

maybe make Grid's data field not a mutable ref

tardy garden
#

how do i debug a stack overflow issue

snow matrix
#

you are clearly calling a function in itself

tardy garden
#

Can gdb debug this?

snow matrix
#

show the code you added before it started

snow matrix
snow matrix
tardy garden
snow matrix
snow matrix
#

should i try writing an alternate version of your grid

tardy garden
snow matrix
#

your grid

tardy garden
#

You could use my testing or main branch as a starting point, I could apply all these changes to my other branches, because the code looks much better there

tardy garden
#

I do have a working grid that works FLAWLESSLY but containers dont really work

snow matrix
#

containers are tricky

#

you cant store a container and if you try to store a factory the captures of the factory make everything completely pinned

tardy garden
#

Is there a solution to this you can think of?

#

other than abandon containers, because I am quite intent on using it

tardy garden
# snow matrix you cant store a container and if you try to store a factory the captures of the...

I am about to go to sleep soon, you can write a alternative version of grid, that would be VERY much appreciated thank you, you dont have to re-write the whole thing, its the widget i am having a issue with mainly, if you can solve a basic widget, I can get it to work with the existing api for my library, or just do whatever, again, thank you very much for the help you given me and it would probably help if you attempted to write one (you can take a look at my code, primarily testing2 to try and use some of the existing code)

snow matrix
#

so for containers you would have to use factories

  • make the factories in default
  • in view, create the grid
    • if its a factory, call it and return an element
    • if its text or button, make an element based on that
tardy garden
# snow matrix for what?

There is alot of widgets out there, container just like, is like a abstraction for all of them, for example my calender will have things like, very unique and complicated styling, stuff you could not get from a basic button or text option

snow matrix
#

better solution is adding more variants to the enum

  • text
  • button
  • image
  • input
  • ...
#

for every case

snow matrix
tardy garden
# snow matrix better solution is adding more variants to the enum - text - button - image - in...

I mean, the issue is not using container itself, text and button does not use any of iced widgets, if i work on image, input, ill essentially have to re-impliment alot of iced-widgets, sometimes it will be basic like it is for buttons where the button varient of cell just stores a text and a function, then i reconstruct the button, but it gets much more complicated for things like input, and images.. not to mention all the other iced widgets, and what about unoffical ones

snow matrix
#

true

tardy garden
#

Someone made a grid widget but the API behind it is extremely ugly and cluttered and there isnt THAT many options i find, and NO documentation, but i did try and use some of its code for inspiration and failed

tardy garden
# snow matrix true

anyways if youd be willing, you can try and maybe write some code for a grid widget, and I can refer to you to the other grid and my own code

#

I am about to go to sleep so please let me know if your open

snow matrix
#

i am open

#

so you need to be able to put any element in each cell

tardy garden
#

yep

snow matrix
#

thanks

#

no other requirements

tardy garden
# snow matrix no other requirements

Uhh, each cell are bare minimum has to be a element (as in my thing should support elements) and I kind of like my api, so maybe its worth designing around it (where cells are varients, you can change the style, etc), and the changes we discussed. Also, I already have a working version of my grid thing, its on the main branch, you can try it out only with buttons and text, i mean maybe containers but those need to come in some factory refcells, it might help as a refrence.

#

I am heading to sleep

#

gn.

snow matrix
#

gn

tardy garden
#

Also the iced discord has been helpful and I had some discussions which helped improved my widget (link is on their github or website)

tardy garden
#

@snow matrix how's it going?

snow matrix
#

trying to do factories

#

if they didnt capture anything it would be easier

tardy garden
snow matrix
#

do you have an example app that i can demo it

#

like an actually practical one

#

i have factories working but they have to be 'static meaning the captured stuff has to be moved in

tardy garden
#

Uhh, wait, if I push a container, would I have to push a factory?

snow matrix
#

because rust needs to keep track of captures

#

so you need some sort of closure boundary

snow matrix
#

i can make it compatible with yours

tardy garden
#

with the changes you told me to make

snow matrix
#

my demo

#

use cargo run to run the demo

#

i much prefer this api

Grid::new()
    .with_row(["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"])
    .with_rows(
        ... // an iterator of iterators of things convertible to elements
    )
    .cell_height(50)
    .cell_width(50)
    .padding(5);
tardy garden
#

As cells

#

Like any widget

#

Oh wait you can

snow matrix
#

yes

tardy garden
# snow matrix yes

You didnt even need to impliment widget, WOW, I mean WOW, this totally works, I like your api, but idk if i should stick with mine, so ill probably try out both on different branches, and I will credit you because I will re-use a bit of code and add alot of features for styling and such, I mean the main issue is probably solved now, I dont think ill copy the whole thing, but I can use your thing as a refrence to fix my issues with shared element access and rendering

#

Thanks! Like seriously big thanks

snow matrix
#

i added some documentation

tardy garden