#Egui

14 messages · Page 1 of 1 (latest)

hardy zenith
#

Is this like expected behaviour, as in you wrote the gui drawing code in a way that it enters an infinite loop or just a heavy task in general, or is it happening for seemingly no reason?

#

ok, probably the easier (and best) way is to use some multithreading

#

probably using a channel, but Arc<Mutex<Option<T>>> kind of stuff works as well

#

so, you can have the main thread just continue working, and when you press the button, it starts up a second thread that does work in the background.
your app state should have a field like task_reciever: Option<Reciever<ResultType>> that you can check on each time the gui is drawn, to monitor if the task is finished, and the thread that does the work has the corresponding sender

hardy zenith
#

would need a little more information than that, like the full error from running cargo check and maybe some of the code

hardy zenith
#

you wont be able to make the second thread access any of the regular references. you need to have it be completely independent, and send the result in a channel

#

lets say, what would happen if the thread modified self at the same time as the main update loop? data races, garbage output. Obscure bug that breaks your program. What would happen if the thread tries to access self after the whole main event loop has already ended and self no longer exists? either more garbage output or the program would crash in a very uncontrolled way

#

these are the kinds of things its trying to protect you from

#

so instead of this part (im gonna ignore the weird naming) rs self.Player_Name = read::Read("C:\\Name.mmap".to_string()); self.Player_Race = read::Read("C:\\Race.mmap".to_string()); self.Player_Empire = read::Read("C:\\Empire.mmap".to_string());you should make some sort of struct rs struct Player { name: String, race: String, empire: String, }and then use a channel to send this struct from the worker thread to the main event loop.

#

by doing this immediately after spawning the thread handle1.join().unwrap();, youre running into the original problem again. If the operation that the thread is doing takes a full second to execute, the GUI is still going to be stuck on the same frame for the whole time. the work has to be done independently so it doesnt stop the GUI from redrawing itself freely

#

so your program state would have the field like task_reciever: Option<Reciever<Player>>, which would be None by default.
When you click the button that starts the heavy work, you would do like this (in this example its giving a path to read a file from, and the worker thread reads the file and constructs the player struct from it) ```rs
let path = path.clone();
let (tx, rx): (Sender<Player>, Receiver<Player>) = mpsc::channel();
std::thread::spawn(move || {
let file_contents = std::fs::read_to_string(path);

// parse a Player out of the file contents
let player = ...;

tx.send(player).expect("Failed to send player");

});
self.task_reciever = Some(rx);now youve started the task to be ran in the background, without blocking the UI. and the fact that `self.task_receiver` is now `Some` with a receiver instead of `None` indicates that the work is currently being done in the background. You can use this to run some code like this in another part of the regular update loop, every time instead of just on a button press. rs
if let Some(rx) = &self.task_reciever { // checks whether the computation is in progress, and puts the receiver into rx if yes.
if let Ok(player) = rx.try_recv() { // if this returns Ok, that means the computation is finished. else, the gui can continue running as normal and check for progress again on the next time that the update function gets run.
// Here you can do whatever you wanted to do with the result
self.Player_Name = player.name;
self.Player_Race = player.race;
self.Player_Empire = player.empire;

    self.task_reciever = None; // the computation is done, and the reciever can now be set to None to indicate that
}

}```

hardy zenith
#

so do you understand why the UI is freezing? the update function is necessary for drawing the UI to the screen. So if update takes long, there's nothing else drawing the UI for you, you blocked the thing that's supposed to be doing that.

hardy zenith
#

I have no idea about stuff like that. But maybe you can ask in #dark-arts or something, or make a new post here with a more appropriate name