Skip to content

Commit d11d9d8

Browse files
committed
refactor: cleanup wasm code
1 parent 13950d2 commit d11d9d8

File tree

5 files changed

+148
-62
lines changed

5 files changed

+148
-62
lines changed

Sources/Code/TypeScript/Components/NavigraphLogin.tsx

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
import { ComponentProps, DisplayComponent, EventBus, FSComponent, VNode } from "@microsoft/msfs-sdk"
2-
import { getDefaultAppDomain } from "@navigraph/app"
3-
import { CancelToken, navigraphRequest } from "navigraph/auth"
4-
import { AuthService } from "../Services/AuthService"
5-
import "./NavigraphLogin.css"
1+
import { ComponentProps, DisplayComponent, EventBus, FSComponent, VNode } from "@microsoft/msfs-sdk";
2+
import { getDefaultAppDomain } from "@navigraph/app";
3+
import { CancelToken, navigraphRequest } from "navigraph/auth";
4+
import { AuthService } from "../Services/AuthService";
5+
import "./NavigraphLogin.css";
6+
67

78
interface NavigraphLoginProps extends ComponentProps {
89
bus: EventBus
@@ -25,12 +26,12 @@ export class NavigraphLogin extends DisplayComponent<NavigraphLoginProps> {
2526
console.info("JS_LISTENER_COMM_BUS registered")
2627
})
2728

28-
this.commBusListener.on("NavdataDownloaded", () => {
29+
this.commBusListener.on("NAVIGRAPH_NavdataDownloaded", () => {
2930
console.info("WASM downloaded navdata")
3031
this.navdataTextRef.instance.textContent = "Navdata downloaded!"
3132
})
3233

33-
this.commBusListener.on("UnzippedFilesRemaining", (jsonArgs: string) => {
34+
this.commBusListener.on("NAVIGRAPH_UnzippedFilesRemaining", (jsonArgs: string) => {
3435
const args = JSON.parse(jsonArgs)
3536
console.info("WASM unzipping files", args)
3637
const percent = Math.round((args.unzipped / args.total) * 100)
@@ -97,8 +98,8 @@ export class NavigraphLogin extends DisplayComponent<NavigraphLoginProps> {
9798
.catch(e => console.error(e))
9899
const signedUrl = result.data[0].files[0].signed_url
99100
console.log("signed url", signedUrl)
100-
await this.commBusListener.call("COMM_BUS_WASM_CALLBACK", "DownloadNavdata", JSON.stringify({
101+
await this.commBusListener.call("COMM_BUS_WASM_CALLBACK", "NAVIGRAPH_DownloadNavdata", JSON.stringify({
101102
url: signedUrl
102103
}))
103104
}
104-
}
105+
}
Lines changed: 36 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
use std::collections::HashMap;
2-
use std::mem;
32
use std::rc::Rc;
43

5-
use crate::download::downloader::NavdataDownloader;
4+
use crate::download::downloader::{DownloadStatus, NavdataDownloader};
65
use msfs::{commbus::*, MSFSEvent};
76

87
pub struct Dispatcher<'a> {
@@ -23,21 +22,22 @@ impl<'a> Dispatcher<'a> {
2322
MSFSEvent::PostInitialize => {
2423
self.handle_initialized();
2524
}
26-
MSFSEvent::PostUpdate => {
25+
MSFSEvent::PreUpdate => {
2726
self.handle_update();
2827
}
2928
MSFSEvent::PreKill => {
30-
// handle pre kill TODO wait for the unregister functions to be ported
29+
// Drop commbus so that we in turn unregister the events. TODO wait for the unregister functions to be ported into the msfs-rs library
30+
self.commbus = None;
3131
}
3232

3333
_ => {}
3434
}
3535
}
3636

3737
fn handle_initialized(&mut self) {
38-
println!("[WASM] Initialized");
38+
CommBus::call("NAVIGRAPH_Initialized", "", CommBusBroadcastFlags::All);
3939
let captured_downloader = self.downloader.clone();
40-
self.commbus = CommBus::register("DownloadNavdata", move |args| {
40+
self.commbus = CommBus::register("NAVIGRAPH_DownloadNavdata", move |args| {
4141
captured_downloader.download(args)
4242
});
4343
}
@@ -46,32 +46,43 @@ impl<'a> Dispatcher<'a> {
4646
// update unzip
4747
// todo: maybe another way to check instead of cloning? i mean we drop the value anyway but not sure on performance
4848
let captured_downloader = self.downloader.clone();
49-
if captured_downloader.get_files_to_unzip() > 0 {
50-
let total_files = captured_downloader.get_total_files();
51-
let files_unzipped = captured_downloader.get_files_unzipped();
49+
let status = captured_downloader.update_and_get_status();
50+
if captured_downloader.update_and_get_status() == DownloadStatus::Extracting {
51+
let statistics = captured_downloader.get_download_statistics().unwrap(); // will always be Some because we are extracting
5252
let mut map = HashMap::new();
53-
map.insert("total", total_files);
54-
map.insert("unzipped", files_unzipped);
53+
map.insert("total", statistics.total_files);
54+
map.insert("unzipped", statistics.files_unzipped);
5555
let data = serde_json::to_string(&map).unwrap();
56-
// this is temporary until msfs-rs handles this unsafe stuff (soon TM)
57-
let i8_slice: &[i8] = unsafe { mem::transmute(data.as_bytes()) };
58-
println!(
59-
"[WASM] total: {}, unzipped: {}",
60-
total_files, files_unzipped
56+
CommBus::call(
57+
"NAVIGRAPH_UnzippedFilesRemaining",
58+
&data,
59+
CommBusBroadcastFlags::All,
6160
);
62-
// only send the call if unzipped is divisible by 100 (kinda hacky but otherwise we flood the commbus (not good!))
63-
if files_unzipped % 100 == 0 {
64-
CommBus::call(
65-
"UnzippedFilesRemaining",
66-
i8_slice,
67-
CommBusBroadcastFlags::JS,
68-
);
69-
}
7061
let has_more_files = captured_downloader.unzip_batch(10);
7162
if !has_more_files {
7263
println!("[WASM] finished unzip");
73-
CommBus::call("NavdataDownloaded", &[], CommBusBroadcastFlags::JS);
64+
CommBus::call(
65+
"NAVIGRAPH_NavdataDownloaded",
66+
"",
67+
CommBusBroadcastFlags::All,
68+
);
69+
captured_downloader.clear_zip_handler();
7470
}
71+
} else if let DownloadStatus::Failed(_) = status {
72+
let error_message = match status {
73+
DownloadStatus::Failed(message) => message,
74+
_ => "Unknown error".to_owned(),
75+
};
76+
let mut map = HashMap::new();
77+
map.insert("error", &error_message);
78+
let data = serde_json::to_string(&map).unwrap();
79+
CommBus::call(
80+
"NAVIGRAPH_DownloadFailed",
81+
&data,
82+
CommBusBroadcastFlags::All,
83+
);
84+
// clear the zip handler
85+
captured_downloader.clear_zip_handler();
7586
}
7687
}
7788
}

Sources/Code/WASM/navdata_updater/src/download/downloader.rs

Lines changed: 97 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -9,22 +9,48 @@ use msfs::network::*;
99
use crate::download::zip_handler::ZipFileHandler;
1010
use crate::util::JsonParser;
1111

12+
pub struct DownloadStatistics {
13+
pub total_files: usize,
14+
pub files_unzipped: usize,
15+
pub files_to_unzip: usize,
16+
}
17+
18+
#[derive(PartialEq, Eq, Clone)]
19+
pub enum DownloadStatus {
20+
NoDownload,
21+
Downloading,
22+
Extracting,
23+
Done,
24+
Failed(String),
25+
}
26+
1227
pub struct NavdataDownloader {
1328
zip_handler: RefCell<Option<ZipFileHandler<Cursor<Vec<u8>>>>>,
29+
status: RefCell<DownloadStatus>,
1430
}
1531

1632
impl NavdataDownloader {
1733
pub fn new() -> Self {
1834
NavdataDownloader {
1935
zip_handler: RefCell::new(None),
36+
status: RefCell::new(DownloadStatus::NoDownload),
2037
}
2138
}
2239

2340
pub fn download(self: &Rc<Self>, args: &[u8]) {
24-
println!("[WASM] call received");
41+
// Set our status to downloading (needs to be done in its own scope so that the borrow_mut is dropped)
42+
{
43+
let mut status = self.status.borrow_mut();
44+
*status = DownloadStatus::Downloading;
45+
println!("[WASM] Downloading");
46+
}
47+
2548
let json_result = JsonParser::parse(args);
2649
if json_result.is_err() {
27-
println!("[WASM] json error: {}", json_result.err().unwrap());
50+
let mut status = self.status.borrow_mut();
51+
let error = json_result.err().unwrap();
52+
*status = DownloadStatus::Failed(format!("JSON Parsing error from JS: {}", error));
53+
println!("[WASM] Failed: {}", error);
2854
return;
2955
}
3056
let json = json_result.unwrap();
@@ -42,49 +68,84 @@ impl NavdataDownloader {
4268

4369
fn request_finished_callback(&self, request: NetworkRequest, status_code: i32) {
4470
if status_code != 200 {
45-
println!("[WASM] request failed");
71+
let mut status = self.status.borrow_mut();
72+
*status = DownloadStatus::Failed(format!(
73+
"Request failed with code {} and status {}",
74+
request.error_code(),
75+
status_code
76+
));
4677
return;
4778
}
4879
let path = PathBuf::from("\\work/navdata");
4980
if let Err(e) = fs::create_dir_all(&path) {
50-
println!("[WASM] directory error: {}", e);
81+
let mut status = self.status.borrow_mut();
82+
*status = DownloadStatus::Failed(format!("Failed to create directory: {}", e));
5183
return;
5284
}
5385

54-
let data = request.data().unwrap();
86+
let data = request.data();
87+
if data.is_none() {
88+
let mut status = self.status.borrow_mut();
89+
*status = DownloadStatus::Failed("No data received".to_string());
90+
return;
91+
}
92+
let data = data.unwrap();
5593
let cursor = Cursor::new(data);
5694
let zip = zip::ZipArchive::new(cursor).unwrap();
5795

5896
let handler = ZipFileHandler::new(zip, path);
97+
5998
let mut zip_handler = self.zip_handler.borrow_mut();
6099
*zip_handler = Some(handler);
61-
}
62100

63-
/// Returns the number of files left to unzip
64-
pub fn get_files_to_unzip(&self) -> usize {
65-
let zip_handler = self.zip_handler.borrow();
66-
match zip_handler.as_ref() {
67-
Some(handler) => handler.zip_file_count - handler.current_file_index,
68-
None => 0,
101+
// Set our status to extracting (needs to be done in its own scope so that the borrow_mut is dropped)
102+
{
103+
let mut status = self.status.borrow_mut();
104+
*status = DownloadStatus::Extracting;
105+
println!("[WASM] Extracting");
69106
}
70107
}
71108

72-
/// Returns the total number of files in the zip
73-
pub fn get_total_files(&self) -> usize {
74-
let zip_handler = self.zip_handler.borrow();
75-
match zip_handler.as_ref() {
76-
Some(handler) => handler.zip_file_count,
77-
None => 0,
78-
}
109+
pub fn get_download_statistics(
110+
&self,
111+
) -> Result<DownloadStatistics, Box<dyn std::error::Error>> {
112+
let zip_handler_ref = self.zip_handler.borrow(); // Borrow and hold onto the reference
113+
let zip_handler = zip_handler_ref.as_ref().ok_or("No zip handler")?;
114+
115+
let total_files = zip_handler.zip_file_count;
116+
let files_unzipped = zip_handler.current_file_index;
117+
let files_to_unzip = total_files - files_unzipped;
118+
119+
Ok(DownloadStatistics {
120+
total_files,
121+
files_unzipped,
122+
files_to_unzip,
123+
})
79124
}
80125

81-
/// Returns the number of files that have been unzipped
82-
pub fn get_files_unzipped(&self) -> usize {
83-
let zip_handler = self.zip_handler.borrow();
84-
match zip_handler.as_ref() {
85-
Some(handler) => handler.current_file_index,
86-
None => 0,
87-
}
126+
/// This basically either sets the status to no download, extracting, or done
127+
pub fn update_and_get_status(&self) -> DownloadStatus {
128+
let mut status = self.status.borrow_mut();
129+
let zip_handler_option = self.zip_handler.borrow();
130+
131+
// If there is no zip handler, we are not downloading
132+
*status = match zip_handler_option.as_ref() {
133+
None => DownloadStatus::NoDownload,
134+
Some(zip_handler) => {
135+
// Downloaded all files
136+
match zip_handler
137+
.zip_file_count
138+
.cmp(&zip_handler.current_file_index)
139+
{
140+
std::cmp::Ordering::Equal => DownloadStatus::Done,
141+
std::cmp::Ordering::Greater => DownloadStatus::Extracting,
142+
_ => return status.clone(),
143+
}
144+
}
145+
};
146+
147+
// Clone here to return the updated status
148+
status.clone()
88149
}
89150

90151
/// Unzips a batch of files
@@ -97,4 +158,14 @@ impl NavdataDownloader {
97158
None => false,
98159
}
99160
}
161+
162+
pub fn clear_zip_handler(&self) {
163+
// Borrow mutably and set the zip handler to None. We need to do this in its own scope so that the borrow_mut is dropped
164+
// I really don't like this since update_and_get_status also borrows mutably but I don't know how else to do it/what the best way is
165+
{
166+
let mut zip_handler = self.zip_handler.borrow_mut();
167+
*zip_handler = None;
168+
}
169+
self.update_and_get_status();
170+
}
100171
}

Sources/Code/WASM/navdata_updater/src/download/zip_handler.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,8 @@ impl<R: io::Read + io::Seek> ZipFileHandler<R> {
2626
return false;
2727
}
2828
let unwrapped_zip_archive = self.zip_archive.as_mut().unwrap();
29-
let total_files = unwrapped_zip_archive.len();
3029
for _ in 0..batch_size {
31-
if self.current_file_index >= total_files {
30+
if self.current_file_index >= self.zip_file_count {
3231
// lets clear our zip
3332
self.zip_archive = None;
3433
return false; // no more files to unzip
@@ -51,6 +50,10 @@ impl<R: io::Read + io::Seek> ZipFileHandler<R> {
5150
fs::create_dir_all(p).unwrap();
5251
}
5352
}
53+
// If file already exists, delete it so we can overwrite it
54+
if outpath.exists() {
55+
fs::remove_file(&outpath).unwrap();
56+
}
5457
let mut outfile = fs::File::create(outpath).unwrap();
5558
io::copy(&mut file, &mut outfile).unwrap();
5659
}

0 commit comments

Comments
 (0)