Newbie question on lifetimes and &self in impl for Struct

Hi,

I have been so far fooling around in cli programming only and decided to come up with a project to try gui programming for a change. Now I find myself for the first time in a lifetime limbo and would appreciate some tutoring and nudging to right direction from more seasoned rustaceans.

tl;dr version is that I try to reference &self in implementation for a struct after move || and I am stuck on how I should setup my lifetimes to get around the compiler error.

Please see the repository and issue on Github: https://github.com/braincow/fmitestbed/issues/1

Also if you see me doing something really stupid elsewhere in my code feel free to give input.

-Antti-

What do you plan to do with datapoints inside self? As it stands, you don’t make use of it (from a cursory glance) so it can be a local inside the closure itself, rather than a field of TestBedGui.

If you do need access to it from TestBedGui then you can put the datapoints inside an Rc<RefCell<...>> and then move a clone of that into the closure.

You are correct, as it stands the values would not do anything inside the closure or TestBedGui. But after refactoring the code a bit further end result would be something like this:

  1. download the pictures and metadata from the website (working)
  2. show gtk window with several image elements on it (working)
  3. periodically refresh the source images and metadata every five minutes, store them in to the struct (current lifetime problem)
  4. rotate which image is visible on one of the gtk image elements every second (or something similar) also update relevant metadata like date and time somewhere in the gtk window (I was planning on using gtktreeview for this) (not yet implemented).

@vitalyd, I have now tried several different things with Rc and RefCell, but I am unable to make this work. Could you perhaps point me towards an example code for using these together with the gtk::timeout_add_seconds that takes the closure as an argument?

Whatever I do I always end up moving the variable inside the closure. Most likely I dont get a grasp on how to do the .clone() properly(?)

Something like this:

pub struct TestbedGui {
    application: Application,
    datapoints: Rc<RefCell<HashMap<String, Datapoint>>>,
}

pub fn run(&self) {
        // we are using a closure to capture the data
        let datapoints_clone = self.datapoints.clone();
        let tick = move || {
            // download fmi data
            *datapoints_clone.borrow_mut() = parse_testbed();
            // test pixbuf conversion
            let map = &*datapoints_clone.borrow();
            for (key, val) in map {
                println!("get pixbuf for {}", key);
                let _pixbuf = val.image_as_pixbuf();
            }

            // we could return gtk::Continue(false) to stop our refreshing data
            gtk::Continue(true)
        };

        // executes the closure once every five minutes
        gtk::timeout_add_seconds(5 * 60, tick);

        // run Gtk main loop
        self.application.run(&args().collect::<Vec<_>>());
    }