Skip to content

Commit e7774fa

Browse files
committed
fixes #129, handle tab loading errors
1 parent 8e0239e commit e7774fa

File tree

10 files changed

+122
-39
lines changed

10 files changed

+122
-39
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/notation_bevy/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ serde = { version = "1.0.133", features = ["derive"] }
4848
# https://github.com/serde-rs/serde/issues/1937
4949
serde_arrays = "0.1.0"
5050
anyhow = "1.0"
51+
thiserror = "1.0"
5152
ron = "0.7"
5253
float_eq = "0.7"
5354

crates/notation_bevy/src/dsl/get_tab_asset.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use bevy::utils::BoxedFuture;
33

44
use notation_dsl::prelude::parse_get_tab;
55

6-
use crate::tab::tab_asset::TabAsset;
6+
use crate::tab::tab_asset::{TabAsset, TabError};
77

88
#[derive(Default)]
99
pub struct GetTabAssetLoader;
@@ -16,8 +16,11 @@ impl AssetLoader for GetTabAssetLoader {
1616
) -> BoxedFuture<'a, Result<(), anyhow::Error>> {
1717
Box::pin(async move {
1818
let text = String::from_utf8(bytes.to_vec())?;
19-
let tab = parse_get_tab(&text)?;
20-
load_context.set_default_asset(LoadedAsset::new(TabAsset::from(tab)));
19+
let tab_asset = match parse_get_tab(&text) {
20+
Ok(tab) => TabAsset::from(tab),
21+
Err(err) => TabAsset::from(TabError::GetTabFailed(err.to_string())),
22+
};
23+
load_context.set_default_asset(LoadedAsset::new(tab_asset));
2124
Ok(())
2225
})
2326
}

crates/notation_bevy/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ pub mod prelude {
116116
#[doc(hidden)]
117117
pub use crate::strings::strings_plugin::StringsPlugin;
118118
#[doc(hidden)]
119-
pub use crate::tab::tab_asset::TabAsset;
119+
pub use crate::tab::tab_asset::{TabAsset, TabError};
120120
#[doc(hidden)]
121121
pub use crate::tab::tab_bars::TabBars;
122122
#[doc(hidden)]

crates/notation_bevy/src/notation/app.rs

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ impl NotationApp {
216216
}
217217
}
218218
}
219-
pub fn load_tab<F: Fn(String) -> Option<ProtoTab>>(
219+
pub fn load_tab<F: Fn(String) -> Option<TabAsset>>(
220220
commands: &mut Commands,
221221
time: &Time,
222222
windows: &mut Windows,
@@ -231,7 +231,7 @@ impl NotationApp {
231231
if state.window_width > 0.0
232232
&& state.window_height > 0.0
233233
&& state.tab.is_none()
234-
&& state.parse_error.is_none()
234+
&& state.tab_error.is_none()
235235
{
236236
let mut count = 0;
237237
for _ in entities_query.iter() {
@@ -274,20 +274,29 @@ impl NotationApp {
274274
return;
275275
}
276276
println!("\nload_tab(): Loading: {}", state.tab_path);
277-
if let Some(tab) = load_tab(state.tab_path.clone()) {
278-
match Tab::try_parse_arc(tab, settings.add_ready_section, state.bars_range) {
279-
Ok(tab) => {
280-
state.tab = Some(tab.clone());
281-
if let Some(window) = windows.get_primary_mut() {
282-
let title = format!("{} - {}", NotationApp::TITLE, state.tab_path);
283-
window.set_title(title);
284-
}
285-
theme._bypass_systems = false;
286-
evts.send(AddTabEvent(tab));
287-
}
288-
Err(err) => {
289-
println!("nload_tab(): Parse Tab Failed: {:?}", err);
290-
state.parse_error = Some(err);
277+
if state.tab_error.is_none() {
278+
if let Some(tab_asset) = load_tab(state.tab_path.clone()) {
279+
match tab_asset.tab {
280+
Ok(tab) => {
281+
match Tab::try_parse_arc(tab, settings.add_ready_section, state.bars_range) {
282+
Ok(tab) => {
283+
state.tab = Some(tab.clone());
284+
if let Some(window) = windows.get_primary_mut() {
285+
let title = format!("{} - {}", NotationApp::TITLE, state.tab_path);
286+
window.set_title(title);
287+
}
288+
theme._bypass_systems = false;
289+
evts.send(AddTabEvent(tab));
290+
}
291+
Err(err) => {
292+
println!("nload_tab(): Parse Tab Failed: {:?}", err);
293+
state.tab_error = Some(TabError::ParseFailed(err));
294+
}
295+
}
296+
},
297+
Err(err) => {
298+
state.tab_error = Some(err);
299+
},
291300
}
292301
}
293302
}
@@ -297,10 +306,10 @@ impl NotationApp {
297306
asset_server: &AssetServer,
298307
assets: &Assets<TabAsset>,
299308
tab_path: String,
300-
) -> Option<ProtoTab> {
309+
) -> Option<TabAsset> {
301310
let tab_asset: Handle<TabAsset> = asset_server.load(tab_path.as_str());
302311
if let Some(asset) = assets.get(&tab_asset) {
303-
Some(asset.tab.clone())
312+
Some(asset.clone())
304313
} else {
305314
None
306315
}

crates/notation_bevy/src/notation/control.rs

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,14 @@ use crate::settings::layout_settings::LayoutMode;
44

55
use crate::prelude::{NotationState, NotationSettings, NotationTheme};
66

7+
use super::events::WindowResizedEvent;
8+
79
pub struct Control();
810

911
impl Control {
12+
pub const PRESET_GUITAR_STRINGS: &'static str = "guitar_strings";
13+
1014
pub fn reload_tab(state: &mut NotationState, theme: &mut NotationTheme) {
11-
if state.tab.is_none() {
12-
return;
13-
}
1415
state.reload_tab();
1516
theme._bypass_systems = true;
1617
}
@@ -91,4 +92,22 @@ impl Control {
9192
}
9293
window.set_resolution(width as f32, height as f32);
9394
}
95+
pub fn set_preset(
96+
state: &mut NotationState,
97+
settings: &mut NotationSettings,
98+
theme: &mut NotationTheme,
99+
window_resized_evts: &mut EventWriter<WindowResizedEvent>,
100+
preset: &'static str,
101+
) {
102+
match preset {
103+
Self::PRESET_GUITAR_STRINGS => {
104+
state.preset = Some(preset.to_owned());
105+
settings.hide_shapes_lane = true;
106+
theme.sizes.strings.string_space = 20.0;
107+
theme.sizes.strings.note_height = 9.0;
108+
window_resized_evts.send(WindowResizedEvent::new(&state));
109+
},
110+
_ => {},
111+
}
112+
}
94113
}

crates/notation_bevy/src/notation/control_panel.rs

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -313,12 +313,18 @@ impl ControlPanel {
313313
ui: &mut Ui,
314314
pathes: &mut TabPathes,
315315
state: &mut NotationState,
316-
settings: &mut NotationSettings,
316+
_settings: &mut NotationSettings,
317317
theme: &mut NotationTheme,
318318
) {
319319
if theme._bypass_systems {
320-
ui.label("Loading Tab ...");
321-
return;
320+
if state.tab_error.is_some() {
321+
ui.label("Load Tab Failed");
322+
ui.separator();
323+
ui.label(format!("{:?}", state.tab_error.as_ref().unwrap()));
324+
} else {
325+
ui.label("Loading Tab ...");
326+
}
327+
ui.separator();
322328
}
323329
ui.horizontal(|ui| {
324330
if ui.button("Reload Tab").clicked() {
@@ -606,6 +612,26 @@ impl ControlPanel {
606612
ui.separator();
607613
}
608614
}
615+
pub fn presets_ui(
616+
ui: &mut Ui,
617+
state: &mut NotationState,
618+
settings: &mut NotationSettings,
619+
theme: &mut NotationTheme,
620+
window_resized_evts: &mut EventWriter<WindowResizedEvent>,
621+
) {
622+
CollapsingHeader::new(format!(
623+
"Preset: {}",
624+
state.preset.clone().unwrap_or("".to_string())
625+
))
626+
.default_open(true)
627+
.show(ui, |ui| {
628+
ui.horizontal(|ui| {
629+
if ui.button(Control::PRESET_GUITAR_STRINGS).clicked() {
630+
Control::set_preset(state, settings, theme, window_resized_evts, Control::PRESET_GUITAR_STRINGS);
631+
}
632+
});
633+
});
634+
}
609635
pub fn control_ui(
610636
egui_ctx: Res<EguiContext>,
611637
mut windows: ResMut<Windows>,
@@ -665,6 +691,8 @@ impl ControlPanel {
665691
);
666692
Self::display_ui(ui, &mut state, &mut settings, &mut theme);
667693
ui.separator();
694+
Self::presets_ui(ui, &mut state, &mut settings, &mut theme, &mut window_resized_evts);
695+
ui.separator();
668696
Self::layout_ui(ui, &mut state, &mut settings, &mut theme);
669697
Self::overrides_ui(
670698
ui,

crates/notation_bevy/src/notation/state.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::sync::Arc;
22

3-
use crate::prelude::*;
3+
use crate::{prelude::*, tab::tab_asset::TabError};
44
use bevy::prelude::*;
55
use notation_model::prelude::*;
66

@@ -16,7 +16,8 @@ pub struct NotationState {
1616
pub bars_range: Option<(usize, usize)>,
1717
pub show_control: bool,
1818
pub show_kb: bool,
19-
pub parse_error: Option<ParseError>,
19+
pub preset: Option<String>,
20+
pub tab_error: Option<TabError>,
2021
pub debug_str: Option<String>,
2122
pub _despawn_delay_seconds: f32,
2223
pub _load_tab_delay_seconds: f32,
@@ -40,7 +41,8 @@ impl NotationState {
4041
#[cfg(not(debug_assertions))]
4142
show_kb: true,
4243

43-
parse_error: None,
44+
preset: None,
45+
tab_error: None,
4446
debug_str: None,
4547
_despawn_delay_seconds: 0.0,
4648
_load_tab_delay_seconds: 0.0,
@@ -50,11 +52,11 @@ impl NotationState {
5052
theme._bypass_systems = true;
5153
self.tab_path = tab_path;
5254
self.bars_range = None;
53-
self.parse_error = None;
5455
self.reload_tab()
5556
}
5657
pub fn reload_tab(&mut self) {
5758
self.tab = None;
59+
self.tab_error = None;
5860
self._despawn_delay_seconds = 0.1;
5961
self._load_tab_delay_seconds = 0.2;
6062
}

crates/notation_bevy/src/tab/tab_asset.rs

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,36 @@
1+
use thiserror::Error;
2+
use notation_model::parse::ParseError;
13
use bevy::asset::{AssetLoader, LoadContext, LoadedAsset};
24
use bevy::reflect::TypeUuid;
35
use bevy::utils::BoxedFuture;
4-
use serde::Deserialize;
56

67
use notation_model::prelude::ProtoTab;
78

8-
#[derive(Debug, Deserialize, TypeUuid)]
9+
#[derive(Clone, Debug, TypeUuid)]
910
#[uuid = "52bcea66-eb44-4ad6-85bf-240b79494499"]
1011
pub struct TabAsset {
11-
pub tab: ProtoTab,
12+
pub tab: Result<ProtoTab, TabError>,
13+
}
14+
15+
#[derive(Clone, Error, Debug)]
16+
pub enum TabError {
17+
#[error("decode ron failed")]
18+
DecodeRonFailed(ron::Error),
19+
#[error("get tab failed")]
20+
GetTabFailed(String),
21+
#[error("parse tab failed")]
22+
ParseFailed(ParseError),
1223
}
1324

1425
impl From<ProtoTab> for TabAsset {
1526
fn from(v: ProtoTab) -> Self {
16-
Self { tab: v }
27+
Self { tab: Ok(v) }
28+
}
29+
}
30+
31+
impl From<TabError> for TabAsset {
32+
fn from(v: TabError) -> Self {
33+
Self { tab: Err(v) }
1734
}
1835
}
1936

@@ -34,8 +51,11 @@ impl AssetLoader for TabAssetLoader {
3451
load_context: &'a mut LoadContext,
3552
) -> BoxedFuture<'a, Result<(), anyhow::Error>> {
3653
Box::pin(async move {
37-
let tab = ron::de::from_bytes::<ProtoTab>(bytes)?;
38-
load_context.set_default_asset(LoadedAsset::new(TabAsset::from(tab)));
54+
let tab_asset = match ron::de::from_bytes::<ProtoTab>(bytes) {
55+
Ok(tab) => TabAsset::from(tab),
56+
Err(err) => TabAsset::from(TabError::DecodeRonFailed(err)),
57+
};
58+
load_context.set_default_asset(LoadedAsset::new(tab_asset));
3959
Ok(())
4060
})
4161
}

crates/notation_model/src/parse.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use thiserror::Error;
77
use crate::prelude::{BarLane, Form, LaneEntry, ModelEntry, Section, Tab, TabBar, TabMeta, Track};
88
use notation_proto::prelude::{Duration, Entry, ProtoEntry, Units};
99

10-
#[derive(Error, Debug)]
10+
#[derive(Error, Clone, Debug)]
1111
pub enum ParseError {
1212
#[error("track not found")]
1313
TrackNotFound(String),

0 commit comments

Comments
 (0)