Skip to content

Commit a001893

Browse files
committed
fixes #120, support reload tab from disk
1 parent 325fbef commit a001893

File tree

4 files changed

+42
-18
lines changed

4 files changed

+42
-18
lines changed

crates/notation_bevy/src/app/app.rs

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ impl NotationApp {
104104
app.init_resource::<NotationAppState>();
105105

106106
app.add_startup_system(setup_camera.system());
107+
//app.add_startup_system(setup_hot_reloading.system());
107108

108109
app.add_system_set(
109110
SystemSet::on_enter(NotationAssetsStates::Loaded)
@@ -116,6 +117,7 @@ impl NotationApp {
116117
.with_system(handle_mouse_inputs.system())
117118
.with_system(handle_touch_inputs.system())
118119
.with_system(load_tab.system())
120+
.with_system(on_tab_asset.system())
119121
);
120122

121123
extra(&mut app);
@@ -136,9 +138,34 @@ fn setup_camera(mut commands: Commands) {
136138
commands.spawn_bundle(OrthographicCameraBundle::new_2d());
137139
}
138140

141+
/*
142+
* The open tab logic is using some trick in the asset server, which can load from absolute path
143+
* (outside assets folder), but the hot reloading is not working this way.
144+
* Ideally can use hot-reloading to update tabs automatically, but that means need to patch bevy
145+
* to bypass the assumption with asset path under assets folder in reloading.
146+
* Leave the codes here in case that want to revisit this feature in the future.
147+
*
148+
* The crash error is:
149+
*
150+
* thread 'Compute Task Pool (2)' panicked at 'called `Result::unwrap()` on an `Err` value: StripPrefixError(())', C:\Users\yjpark\scoop\persist\rustup-msvc\.cargo\registry\src\github.com-1ecc6299db9ec823\bevy_asset-0.5.1\src\io\file_asset_io.rs:135:84
151+
*
152+
fn setup_hot_reloading(asset_server: Res<AssetServer>) {
153+
asset_server.watch_for_changes().unwrap();
154+
}
155+
*/
156+
157+
fn on_tab_asset(
158+
mut evts: EventReader<AssetEvent<TabAsset>>,
159+
) {
160+
for evt in evts.iter() {
161+
println!("AssetEvent<TabAsset> {:?}", evt);
162+
}
163+
}
164+
139165
fn load_tab(
140166
mut commands: Commands,
141167
time: Res<Time>,
168+
asset_server: Res<AssetServer>,
142169
mut windows: ResMut<Windows>,
143170
mut state: ResMut<NotationAppState>,
144171
mut theme: ResMut<NotationTheme>,
@@ -171,13 +198,15 @@ fn load_tab(
171198
}
172199
return;
173200
}
201+
asset_server.free_unused_assets();
174202
if state._load_tab_delay_seconds > 0.0 {
175203
state._load_tab_delay_seconds -= time.delta_seconds();
176204
println!("load_tab(): Waiting to Load tab: -> {}", state._load_tab_delay_seconds);
177205
return;
178206
}
179207
println!("\nload_tab(): Loading: {}", state.tab_path);
180-
if let Some(asset) = assets.get(&state.tab_asset) {
208+
let tab_asset: Handle<TabAsset> = asset_server.load(state.tab_path.as_str());
209+
if let Some(asset) = assets.get(&tab_asset) {
181210
match Tab::try_parse_arc(asset.tab.clone()) {
182211
Ok(tab) => {
183212
state.tab = Some(tab.clone());
@@ -216,6 +245,8 @@ fn handle_keyboard_inputs(
216245
if !ControlView::HUD_MODE {
217246
window_resized_evts.send(WindowResizedEvent());
218247
}
248+
} else if keyboard_input.just_released(KeyCode::F5) {
249+
Control::reload_tab(&mut app_state, &mut theme);
219250
} else if keyboard_input.just_released(KeyCode::Space) {
220251
Control::play_or_pause(&mut midi_state, &mut play_control_evts);
221252
} else if keyboard_input.just_released(KeyCode::Return) {

crates/notation_bevy/src/app/app_state.rs

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ pub struct NotationAppState {
1111
pub window_height: f32,
1212
pub scale_factor_override: Option<f64>,
1313
pub tab_path: String,
14-
pub tab_asset: Handle<TabAsset>,
1514
pub tab: Option<Arc<Tab>>,
1615
pub hide_control: bool,
1716
pub parse_error: Option<ParseError>,
@@ -21,14 +20,12 @@ pub struct NotationAppState {
2120
}
2221

2322
impl NotationAppState {
24-
pub fn new(asset_server: &AssetServer, tab_path: String) -> Self {
25-
let tab_asset = asset_server.load(tab_path.as_str());
23+
pub fn new(tab_path: String) -> Self {
2624
Self {
2725
window_width: 0.0,
2826
window_height: 0.0,
2927
scale_factor_override: None,
3028
tab_path,
31-
tab_asset,
3229
tab: None,
3330
hide_control: true,
3431
parse_error: None,
@@ -39,17 +36,15 @@ impl NotationAppState {
3936
}
4037
pub fn change_tab(
4138
&mut self,
42-
asset_server: &AssetServer,
4339
theme: &mut NotationTheme,
4440
tab_path: String
4541
) {
4642
theme._bypass_systems = true;
4743
self.tab_path = tab_path;
48-
self.tab_asset = asset_server.load(self.tab_path.as_str());
4944
self.parse_error = None;
50-
self.reset_tab()
45+
self.reload_tab()
5146
}
52-
pub fn reset_tab(&mut self) {
47+
pub fn reload_tab(&mut self) {
5348
self.tab = None;
5449
self._despawn_delay_seconds = 0.1;
5550
self._load_tab_delay_seconds = 0.2;
@@ -64,8 +59,7 @@ impl NotationAppState {
6459

6560
impl FromWorld for NotationAppState {
6661
fn from_world(world: &mut World) -> Self {
67-
let server = world.get_resource::<AssetServer>().unwrap();
6862
let tab_pathes = world.get_resource::<TabPathes>().unwrap();
69-
Self::new(server, tab_pathes.0[0].clone())
63+
Self::new(tab_pathes.0[0].clone())
7064
}
7165
}

crates/notation_bevy/src/viewer/control.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ impl Control {
2323
if state.tab.is_none() {
2424
return;
2525
}
26-
state.reset_tab();
26+
state.reload_tab();
2727
theme._bypass_systems = true;
2828
}
2929
pub fn sync_speed_factor(

crates/notation_bevy/src/viewer/control_view.rs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -426,7 +426,6 @@ impl ControlView {
426426
}
427427
pub fn tab_ui(
428428
ui: &mut Ui,
429-
asset_server: &AssetServer,
430429
pathes: &mut TabPathes,
431430
state: &mut NotationAppState,
432431
_settings: &mut NotationSettings,
@@ -437,9 +436,10 @@ impl ControlView {
437436
return;
438437
}
439438
ui.horizontal(|ui| {
440-
if ui.button("Reset Tab").clicked() {
439+
if ui.button("Reload Tab").clicked() {
441440
Control::reload_tab(state, theme);
442441
}
442+
ui.separator();
443443
#[cfg(not(target_arch = "wasm32"))]
444444
if ui.button("Open Tab").clicked() {
445445
if let Some(path) = rfd::FileDialog::new()
@@ -448,7 +448,7 @@ impl ControlView {
448448
let path_str = path.clone().into_os_string().into_string();
449449
if let Ok(path_str) = path_str {
450450
pathes.0.insert(0, path_str.clone());
451-
state.change_tab(asset_server, theme, path_str.clone());
451+
state.change_tab(theme, path_str.clone());
452452
} else {
453453
println!("Failed to convert path to string: {:?} -> {:?}", path, path_str);
454454
}
@@ -464,7 +464,7 @@ impl ControlView {
464464
for path in pathes.0.iter() {
465465
if ui.selectable_label(*path == state.tab_path, path).clicked()
466466
{
467-
state.change_tab(asset_server, theme, path.clone());
467+
state.change_tab(theme, path.clone());
468468
}
469469
}
470470
});
@@ -640,7 +640,6 @@ impl ControlView {
640640
pub fn control_ui(
641641
egui_ctx: Res<EguiContext>,
642642
mut windows: ResMut<Windows>,
643-
asset_server: Res<AssetServer>,
644643
mut pathes: ResMut<TabPathes>,
645644
mut state: ResMut<NotationAppState>,
646645
mut settings: ResMut<NotationSettings>,
@@ -668,7 +667,7 @@ impl ControlView {
668667
}
669668
ui.separator();
670669
*/
671-
Self::tab_ui(ui, &asset_server, &mut pathes, &mut state, &mut settings, &mut theme);
670+
Self::tab_ui(ui, &mut pathes, &mut state, &mut settings, &mut theme);
672671
ui.separator();
673672
Self::play_control_ui(ui, &mut settings, &mut midi_state, &mut play_control_evts);
674673
ui.separator();

0 commit comments

Comments
 (0)