run VRU dialog in main thread (#774)

* run VRU dialog in main thread

* more
This commit is contained in:
Logan McNaughton 2026-04-19 09:00:50 -06:00 committed by GitHub
parent 66abd14c3b
commit 805bcba249
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 60 additions and 108 deletions

View File

@ -77,16 +77,7 @@ pub fn cheats_window(app: &AppWindow) {
options,
));
}
#[allow(clippy::type_complexity)]
let cheats_model: std::rc::Rc<
slint::VecModel<(
slint::SharedString,
bool,
slint::SharedString,
slint::ModelRc<(bool, slint::SharedString)>,
)>,
> = std::rc::Rc::new(cheats_vec);
handle.set_cheats(slint::ModelRc::from(cheats_model));
handle.set_cheats(slint::ModelRc::from(std::rc::Rc::new(cheats_vec)));
})
.unwrap();
} else {
@ -137,17 +128,9 @@ pub fn cheats_window(app: &AppWindow) {
fn clear_cheats(weak: &slint::Weak<AppWindow>, clear_name: bool) {
weak.upgrade_in_event_loop(move |handle| {
let cheats_vec = slint::VecModel::default();
#[allow(clippy::type_complexity)]
let cheats_model: std::rc::Rc<
slint::VecModel<(
slint::SharedString,
bool,
slint::SharedString,
slint::ModelRc<(bool, slint::SharedString)>,
)>,
> = std::rc::Rc::new(cheats_vec);
handle.set_cheats(slint::ModelRc::from(cheats_model));
handle.set_cheats(slint::ModelRc::from(std::rc::Rc::new(
slint::VecModel::default(),
)));
if clear_name {
handle.set_cheat_game_name(String::new().into());
}

View File

@ -132,13 +132,10 @@ fn update_input_profiles(weak: &slint::Weak<AppWindow>, config: &ui::config::Con
for profile in profiles {
input_profiles.push(profile.into());
}
let input_profiles_model: std::rc::Rc<slint::VecModel<slint::SharedString>> =
std::rc::Rc::new(input_profiles);
handle.set_input_profiles(slint::ModelRc::from(input_profiles_model));
handle.set_input_profiles(slint::ModelRc::from(std::rc::Rc::new(input_profiles)));
let input_profile_binding_model: std::rc::Rc<slint::VecModel<i32>> =
std::rc::Rc::new(profile_bindings);
handle.set_selected_profile_binding(slint::ModelRc::from(input_profile_binding_model));
handle
.set_selected_profile_binding(slint::ModelRc::from(std::rc::Rc::new(profile_bindings)));
// this is a workaround to make the input profile combobox update
handle.set_blank_profiles(true);
@ -159,32 +156,27 @@ fn controller_window(
controller_names: &Vec<String>,
controller_paths: &[Option<String>],
) {
let controller_enabled_model: std::rc::Rc<slint::VecModel<bool>> = std::rc::Rc::new(
slint::VecModel::from(config.input.controller_enabled.to_vec()),
);
app.set_emulate_vru(config.input.emulate_vru);
app.set_controller_enabled(slint::ModelRc::from(controller_enabled_model));
app.set_controller_enabled(slint::ModelRc::from(std::rc::Rc::new(
slint::VecModel::from(config.input.controller_enabled.to_vec()),
)));
let transferpak_enabled_model: std::rc::Rc<slint::VecModel<bool>> =
std::rc::Rc::new(slint::VecModel::from(config.input.transfer_pak.to_vec()));
app.set_transferpak(slint::ModelRc::from(transferpak_enabled_model));
app.set_transferpak(slint::ModelRc::from(std::rc::Rc::new(
slint::VecModel::from(config.input.transfer_pak.to_vec()),
)));
let gb_rom_paths = slint::VecModel::default();
for gb_rom_path in config.input.gb_rom_path.iter() {
gb_rom_paths.push(gb_rom_path.into());
}
let gb_rom_path_model: std::rc::Rc<slint::VecModel<slint::SharedString>> =
std::rc::Rc::new(gb_rom_paths);
app.set_gb_rom_paths(slint::ModelRc::from(gb_rom_path_model));
app.set_gb_rom_paths(slint::ModelRc::from(std::rc::Rc::new(gb_rom_paths)));
let gb_ram_paths = slint::VecModel::default();
for gb_ram_path in config.input.gb_ram_path.iter() {
gb_ram_paths.push(gb_ram_path.into());
}
let gb_ram_path_model: std::rc::Rc<slint::VecModel<slint::SharedString>> =
std::rc::Rc::new(gb_ram_paths);
app.set_gb_ram_paths(slint::ModelRc::from(gb_ram_path_model));
app.set_gb_ram_paths(slint::ModelRc::from(std::rc::Rc::new(gb_ram_paths)));
update_input_profiles(&app.as_weak(), config);
@ -192,9 +184,7 @@ fn controller_window(
for controller in controller_names {
controllers.push(controller.into());
}
let controller_names_model: std::rc::Rc<slint::VecModel<slint::SharedString>> =
std::rc::Rc::new(controllers);
app.set_controller_names(slint::ModelRc::from(controller_names_model));
app.set_controller_names(slint::ModelRc::from(std::rc::Rc::new(controllers)));
let controller_changed = slint::VecModel::default();
let selected_controllers = slint::VecModel::default();
@ -212,13 +202,9 @@ fn controller_window(
}
controller_changed.push(false);
}
let selected_controllers_model: std::rc::Rc<slint::VecModel<i32>> =
std::rc::Rc::new(selected_controllers);
app.set_selected_controller(slint::ModelRc::from(selected_controllers_model));
app.set_selected_controller(slint::ModelRc::from(std::rc::Rc::new(selected_controllers)));
let controller_changed_model: std::rc::Rc<slint::VecModel<bool>> =
std::rc::Rc::new(controller_changed);
app.set_controller_changed(slint::ModelRc::from(controller_changed_model));
app.set_controller_changed(slint::ModelRc::from(std::rc::Rc::new(controller_changed)));
let weak_app = app.as_weak();
app.on_input_profile_button_clicked(move || {

View File

@ -159,12 +159,8 @@ fn populate_server_names<T: ComponentHandle + NetplayPages + 'static>(weak: slin
}
server_names.push("Custom".into());
handle.refresh_sessions();
let server_names_model: std::rc::Rc<slint::VecModel<slint::SharedString>> =
std::rc::Rc::new(server_names);
let server_urls_model: std::rc::Rc<slint::VecModel<slint::SharedString>> =
std::rc::Rc::new(server_urls);
handle.set_server_names(slint::ModelRc::from(server_names_model));
handle.set_server_urls(slint::ModelRc::from(server_urls_model));
handle.set_server_names(slint::ModelRc::from(std::rc::Rc::new(server_names)));
handle.set_server_urls(slint::ModelRc::from(std::rc::Rc::new(server_urls)));
})
.unwrap();
});
@ -583,26 +579,19 @@ fn update_sessions(weak: slint::Weak<NetplayJoin>) {
.upgrade_in_event_loop(move |handle| {
let sessions_vec = slint::VecModel::default();
for session in sessions.iter() {
let session_vec = slint::VecModel::from(session.to_vec());
let session_model: std::rc::Rc<
slint::VecModel<slint::StandardListViewItem>,
> = std::rc::Rc::new(session_vec);
sessions_vec.push(slint::ModelRc::from(session_model));
sessions_vec.push(slint::ModelRc::from(std::rc::Rc::new(
slint::VecModel::from(session.to_vec()),
)));
}
let rooms_model: std::rc::Rc<
slint::VecModel<slint::ModelRc<slint::StandardListViewItem>>,
> = std::rc::Rc::new(sessions_vec);
handle.set_sessions(slint::ModelRc::from(rooms_model));
handle.set_sessions(slint::ModelRc::from(std::rc::Rc::new(sessions_vec)));
let room_urls_vec = slint::VecModel::from(room_urls.to_vec());
let room_urls_model: std::rc::Rc<slint::VecModel<slint::SharedString>> =
std::rc::Rc::new(room_urls_vec);
handle.set_room_urls(slint::ModelRc::from(room_urls_model));
handle.set_room_urls(slint::ModelRc::from(std::rc::Rc::new(
slint::VecModel::from(room_urls.to_vec()),
)));
let room_ports_vec = slint::VecModel::from(room_ports.to_vec());
let room_ports_model: std::rc::Rc<slint::VecModel<i32>> =
std::rc::Rc::new(room_ports_vec);
handle.set_room_ports(slint::ModelRc::from(room_ports_model));
handle.set_room_ports(slint::ModelRc::from(std::rc::Rc::new(
slint::VecModel::from(room_ports.to_vec()),
)));
handle.set_current_session(-1);
handle.set_pending_refresh(false);
@ -1067,10 +1056,9 @@ fn setup_wait_window(
for player in player_names {
players_vec.push(player.into());
}
let players_model: std::rc::Rc<
slint::VecModel<slint::SharedString>,
> = std::rc::Rc::new(players_vec);
handle.set_players(slint::ModelRc::from(players_model));
handle.set_players(slint::ModelRc::from(std::rc::Rc::new(
players_vec,
)));
}
})
.unwrap();

View File

@ -8,43 +8,38 @@ pub fn prompt_for_match(words: &[String], frame_time: f64) -> u16 {
dedup_words.dedup();
let (tx, mut rx) = tokio::sync::mpsc::channel(1);
tokio::spawn(async move {
let vru_dialog = gui::VruDialog::new().unwrap();
let vru_dialog_weak = vru_dialog.as_weak();
let tx_clicked = tx.clone();
let vru_dialog = gui::VruDialog::new().unwrap();
let vru_dialog_weak = vru_dialog.as_weak();
vru_dialog.on_vru_button_clicked(move |chosen_word| {
tx_clicked.try_send(chosen_word.to_string()).unwrap();
vru_dialog_weak.unwrap().window().hide().unwrap();
});
vru_dialog.window().on_close_requested(move || {
tx.try_send(String::new()).unwrap();
slint::CloseRequestResponse::HideWindow
});
let words_vec = slint::VecModel::default();
for word in dedup_words {
words_vec.push(word.into());
}
let words_model: std::rc::Rc<slint::VecModel<slint::SharedString>> =
std::rc::Rc::new(words_vec);
vru_dialog.set_words(slint::ModelRc::from(words_model));
vru_dialog.run().unwrap();
vru_dialog.on_vru_button_clicked(move |chosen_word| {
tx.try_send(chosen_word.to_string()).unwrap();
vru_dialog_weak.unwrap().window().hide().unwrap();
});
let mut result = rx.try_recv();
while result.is_err() {
result = rx.try_recv();
std::thread::sleep(std::time::Duration::from_secs_f64(frame_time));
unsafe { sdl3_sys::events::SDL_PumpEvents() }; // so the OS doesn't complain about the game window being frozen
retroachievements::do_idle();
let words_vec = slint::VecModel::default();
for word in dedup_words {
words_vec.push(word.into());
}
for (i, v) in words.iter().enumerate() {
if *v == *result.as_ref().unwrap() {
return i as u16;
vru_dialog.set_words(slint::ModelRc::from(std::rc::Rc::new(words_vec)));
let timer = slint::Timer::default();
timer.start(
slint::TimerMode::Repeated,
std::time::Duration::from_secs_f64(frame_time),
move || {
unsafe { sdl3_sys::events::SDL_PumpEvents() }; // so the OS doesn't complain about the game window being frozen
retroachievements::do_idle();
},
);
vru_dialog.run().unwrap();
if let Ok(result) = rx.try_recv() {
for (i, v) in words.iter().enumerate() {
if *v == result {
return i as u16;
}
}
}
0x7FFF