viewer: fix a startup panic in the Save File browser (Bevy B0002)
draw_save_ui held both an EventReader<RequestSaveOpen> (to know when the View menu opened it) and an EventWriter<RequestSaveOpen> (so its own "Open savedata…" button could re-trigger the file dialog). Bevy rejects a system that accesses one event type both ways, and does so at schedule-validation time -- so the app panicked on startup, before any window content. The button now sets `SaveBrowser::request_open` and handle_save_open_request treats that flag as equivalent to the event, with no path (dialog). Audited every system in the viewer for the same shape; this was the only one. Verified by running the binary to steady state rather than by compiling alone, since a param conflict is invisible to the type checker. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -786,6 +786,11 @@ pub struct SaveBrowser {
|
||||
pub result: Option<Box<SaveResult>>,
|
||||
/// Show the fields that are still unidentified.
|
||||
pub show_unknown: bool,
|
||||
/// Set by the window's own "Open savedata…" button. It cannot send
|
||||
/// [`RequestSaveOpen`] itself: a system may not hold an `EventWriter` and an
|
||||
/// `EventReader` for the same event type, and `draw_save_ui` already reads
|
||||
/// this one (Bevy B0002).
|
||||
pub request_open: bool,
|
||||
}
|
||||
|
||||
/// Ask the loader to open + parse a `savedata` file. `None` = show a file
|
||||
@@ -4267,7 +4272,14 @@ fn handle_save_open_request(
|
||||
channels: Res<IsoChannels>,
|
||||
mut saves: ResMut<SaveBrowser>,
|
||||
) {
|
||||
let Some(req) = events.read().last() else {
|
||||
// Either the View-menu event, or the in-window button's flag.
|
||||
let want = match events.read().last() {
|
||||
Some(req) => Some(req.path.clone()),
|
||||
None if saves.request_open => Some(None),
|
||||
None => None,
|
||||
};
|
||||
saves.request_open = false;
|
||||
let Some(want) = want else {
|
||||
return;
|
||||
};
|
||||
if saves.loading {
|
||||
@@ -4275,7 +4287,6 @@ fn handle_save_open_request(
|
||||
}
|
||||
saves.loading = true;
|
||||
saves.open = true;
|
||||
let want = req.path.clone();
|
||||
let sender = channels.sender.clone();
|
||||
std::thread::spawn(move || {
|
||||
let path = match want {
|
||||
|
||||
@@ -2122,7 +2122,6 @@ fn draw_save_ui(
|
||||
mut contexts: EguiContexts,
|
||||
mut saves: ResMut<SaveBrowser>,
|
||||
mut requests: EventReader<RequestSaveOpen>,
|
||||
mut open_save: EventWriter<RequestSaveOpen>,
|
||||
) {
|
||||
if requests.read().next().is_some() {
|
||||
saves.open = true;
|
||||
@@ -2289,8 +2288,10 @@ fn draw_save_ui(
|
||||
});
|
||||
});
|
||||
|
||||
// A flag, not a self-send: holding both an EventReader and an EventWriter
|
||||
// for RequestSaveOpen in one system is a Bevy B0002 panic at startup.
|
||||
if reopen {
|
||||
open_save.send(RequestSaveOpen::default());
|
||||
saves.request_open = true;
|
||||
}
|
||||
saves.open &= open;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user