Saving is multi threaded now
This commit is contained in:
parent
60182e4d82
commit
c7761b9787
3 changed files with 85 additions and 52 deletions
|
@ -115,10 +115,10 @@ Kirigami.ApplicationWindow {
|
||||||
anchors.left: footerFilePathLabel.left
|
anchors.left: footerFilePathLabel.left
|
||||||
anchors.right: footerFilePathLabel.right
|
anchors.right: footerFilePathLabel.right
|
||||||
anchors.rightMargin: footerFilePathLabel.rightMargin
|
anchors.rightMargin: footerFilePathLabel.rightMargin
|
||||||
from: 0
|
from: 0.0
|
||||||
to: 100
|
to: 100.0
|
||||||
value: mainPage.progress
|
value: Math.min(ServiceItemModel.saveProgess, 100.0)
|
||||||
visible: mainPage.progress > 0
|
/* visible: mainPage.progress > 0 */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Item { */
|
/* Item { */
|
||||||
|
@ -208,7 +208,7 @@ Kirigami.ApplicationWindow {
|
||||||
defaultSuffix: ".pres"
|
defaultSuffix: ".pres"
|
||||||
selectExisting: false
|
selectExisting: false
|
||||||
onAccepted: {
|
onAccepted: {
|
||||||
finalSave(saveFileDialog.fileUrl);
|
ServiceItemModel.save(saveFileDialog.fileUrl);
|
||||||
console.log(saveFileDialog.fileUrl);
|
console.log(saveFileDialog.fileUrl);
|
||||||
}
|
}
|
||||||
onRejected: {
|
onRejected: {
|
||||||
|
@ -274,29 +274,32 @@ Kirigami.ApplicationWindow {
|
||||||
let file = "";
|
let file = "";
|
||||||
if (saveFile.length === 0) {
|
if (saveFile.length === 0) {
|
||||||
file = fileHelper.saveFile();
|
file = fileHelper.saveFile();
|
||||||
finalSave(file);
|
ServiceItemModel.save(file);
|
||||||
} else {
|
} else {
|
||||||
finalSave(saveFile);
|
ServiceItemModel.save(saveFile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function saveAs() {
|
function saveAs() {
|
||||||
let file = fileHelper.saveFile();
|
let file = fileHelper.saveFile();
|
||||||
finalSave(file);
|
ServiceItemModel.save(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
function finalSave(file) {
|
Connections {
|
||||||
const saved = mainPage.serviceItems.save(file);
|
target: ServiceItemModel
|
||||||
if (saved) {
|
function onSavedToFile(saved, file) {
|
||||||
RSettings.setSaveFile(file);
|
if (saved) {
|
||||||
showPassiveNotification("SAVED! " + file);
|
Utils.dbg(file);
|
||||||
mainPage.progress = 0;
|
console.log(file);
|
||||||
} else {
|
showPassiveNotification("Saved to ", + Qt.resolvedUrl(file));
|
||||||
console.log("File: " + file + " wasn't saved");
|
}
|
||||||
showPassiveNotification("Didn't save file");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* function finalSave(file) { */
|
||||||
|
/* const saved = mainPage.serviceItems.save(file); */
|
||||||
|
/* } */
|
||||||
|
|
||||||
function load() {
|
function load() {
|
||||||
const file = fileHelper.loadFile("Load Presentation");
|
const file = fileHelper.loadFile("Load Presentation");
|
||||||
const loaded = mainPage.serviceItems.load(file);
|
const loaded = mainPage.serviceItems.load(file);
|
||||||
|
|
|
@ -184,8 +184,8 @@ Controls.Page {
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: ServiceItemModel
|
target: ServiceItemModel
|
||||||
function saveProgressUpdate(progress) {
|
function onSaveProgressChanged() {
|
||||||
mainPage.progress = progress;
|
Utils.dbg(ServiceItemModel.saveProgress);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -48,6 +48,8 @@ mod service_item_model {
|
||||||
#[base = "QAbstractListModel"]
|
#[base = "QAbstractListModel"]
|
||||||
#[qml_element]
|
#[qml_element]
|
||||||
#[qproperty(i32, count)]
|
#[qproperty(i32, count)]
|
||||||
|
#[qproperty(f32, save_progress)]
|
||||||
|
#[qproperty(bool, saved)]
|
||||||
type ServiceItemModel = super::ServiceItemModelRust;
|
type ServiceItemModel = super::ServiceItemModelRust;
|
||||||
|
|
||||||
#[inherit]
|
#[inherit]
|
||||||
|
@ -100,6 +102,13 @@ mod service_item_model {
|
||||||
progress: i32,
|
progress: i32,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
#[qsignal]
|
||||||
|
fn saved_to_file(
|
||||||
|
self: Pin<&mut ServiceItemModel>,
|
||||||
|
saved: bool,
|
||||||
|
file: &QUrl,
|
||||||
|
);
|
||||||
|
|
||||||
#[qinvokable]
|
#[qinvokable]
|
||||||
fn clear(self: Pin<&mut ServiceItemModel>);
|
fn clear(self: Pin<&mut ServiceItemModel>);
|
||||||
|
|
||||||
|
@ -283,7 +292,7 @@ mod service_item_model {
|
||||||
|
|
||||||
use crate::obs::Obs;
|
use crate::obs::Obs;
|
||||||
use crate::service_item_model::service_item_model::QList_QString;
|
use crate::service_item_model::service_item_model::QList_QString;
|
||||||
use cxx_qt::CxxQtType;
|
use cxx_qt::{CxxQtType, Threading};
|
||||||
use cxx_qt_lib::{
|
use cxx_qt_lib::{
|
||||||
QByteArray, QModelIndex, QString, QStringList, QUrl, QVariant,
|
QByteArray, QModelIndex, QString, QStringList, QUrl, QVariant,
|
||||||
};
|
};
|
||||||
|
@ -293,6 +302,7 @@ use std::io::{Read, Write};
|
||||||
use std::iter;
|
use std::iter;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
|
use std::time::Instant;
|
||||||
use std::{fs, println};
|
use std::{fs, println};
|
||||||
use tar::{Archive, Builder};
|
use tar::{Archive, Builder};
|
||||||
use tracing::{debug, error};
|
use tracing::{debug, error};
|
||||||
|
@ -359,6 +369,8 @@ pub struct ServiceItemModelRust {
|
||||||
service_items: Vec<ServiceItem>,
|
service_items: Vec<ServiceItem>,
|
||||||
obs: Option<Obs>,
|
obs: Option<Obs>,
|
||||||
count: i32,
|
count: i32,
|
||||||
|
save_progress: f32,
|
||||||
|
saved: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for ServiceItemModelRust {
|
impl Default for ServiceItemModelRust {
|
||||||
|
@ -378,6 +390,8 @@ impl Default for ServiceItemModelRust {
|
||||||
service_items: Vec::new(),
|
service_items: Vec::new(),
|
||||||
obs,
|
obs,
|
||||||
count: 0,
|
count: 0,
|
||||||
|
save_progress: 0.0,
|
||||||
|
saved: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -875,16 +889,19 @@ impl service_item_model::ServiceItemModel {
|
||||||
|
|
||||||
pub fn save(mut self: Pin<&mut Self>, file: QUrl) -> bool {
|
pub fn save(mut self: Pin<&mut Self>, file: QUrl) -> bool {
|
||||||
println!("rust-save-file: {file}");
|
println!("rust-save-file: {file}");
|
||||||
let path =
|
let save_path =
|
||||||
file.to_local_file().unwrap_or_default().to_string();
|
file.to_local_file().unwrap_or_default().to_string();
|
||||||
println!("path: {:?}", path);
|
println!("path: {:?}", save_path);
|
||||||
let lfr = fs::File::create(&path);
|
|
||||||
|
let save_file = fs::File::create(&save_path);
|
||||||
let runtime = tokio::runtime::Runtime::new().unwrap();
|
let runtime = tokio::runtime::Runtime::new().unwrap();
|
||||||
let mut handles = vec![];
|
let mut handles = vec![];
|
||||||
if let Ok(lf) = &lfr {
|
|
||||||
println!("archive: {:?}", lf);
|
if let Ok(save_file) = save_file {
|
||||||
|
println!("archive: {:?}", save_file);
|
||||||
self.as_mut().save_progress_updated(5);
|
self.as_mut().save_progress_updated(5);
|
||||||
let encoder = Encoder::new(lf, 3).unwrap();
|
// let save_file = save_file.clone();
|
||||||
|
let encoder = Encoder::new(save_file, 3).unwrap();
|
||||||
let mut tar = Builder::new(encoder);
|
let mut tar = Builder::new(encoder);
|
||||||
let items = self.rust().service_items.clone();
|
let items = self.rust().service_items.clone();
|
||||||
let mut temp_dir = dirs::data_dir().unwrap();
|
let mut temp_dir = dirs::data_dir().unwrap();
|
||||||
|
@ -905,7 +922,7 @@ impl service_item_model::ServiceItemModel {
|
||||||
temp_service_file.push("serviceitems.json");
|
temp_service_file.push("serviceitems.json");
|
||||||
self.as_mut().save_progress_updated(10);
|
self.as_mut().save_progress_updated(10);
|
||||||
let mut service_json: Vec<Value> = vec![];
|
let mut service_json: Vec<Value> = vec![];
|
||||||
let progress_fraction = items.len() as i32 / 80 as i32;
|
let progress_fraction = items.len() as f32 / 100 as f32;
|
||||||
for (id, item) in items.iter().enumerate() {
|
for (id, item) in items.iter().enumerate() {
|
||||||
let text_list = QList_QString::from(&item.text);
|
let text_list = QList_QString::from(&item.text);
|
||||||
let mut text_vec = Vec::<String>::default();
|
let mut text_vec = Vec::<String>::default();
|
||||||
|
@ -1004,9 +1021,6 @@ impl service_item_model::ServiceItemModel {
|
||||||
handles.push(handle);
|
handles.push(handle);
|
||||||
|
|
||||||
service_json.push(item_json);
|
service_json.push(item_json);
|
||||||
self.as_mut().save_progress_updated(
|
|
||||||
progress_fraction * (id as i32 + 1),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for handle in handles {
|
for handle in handles {
|
||||||
|
@ -1023,6 +1037,8 @@ impl service_item_model::ServiceItemModel {
|
||||||
println!("error-creating-service-file: {:?}", e)
|
println!("error-creating-service-file: {:?}", e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
let now = Instant::now();
|
||||||
|
let thread = self.qt_thread();
|
||||||
match fs::File::options()
|
match fs::File::options()
|
||||||
.write(true)
|
.write(true)
|
||||||
.read(true)
|
.read(true)
|
||||||
|
@ -1034,41 +1050,55 @@ impl service_item_model::ServiceItemModel {
|
||||||
&service_json,
|
&service_json,
|
||||||
) {
|
) {
|
||||||
Ok(e) => {
|
Ok(e) => {
|
||||||
println!("json: file written");
|
debug!(time = ?now.elapsed(), "file written");
|
||||||
match tar.append_dir_all("./", &temp_dir)
|
std::thread::spawn(move || {
|
||||||
{
|
debug!(time = ?now.elapsed(), "idk");
|
||||||
Ok(i) => match tar.finish() {
|
let dir = fs::read_dir(&temp_dir).expect("idk");
|
||||||
Ok(i) => {
|
for (index, file) in dir.enumerate() {
|
||||||
debug!(
|
if let Ok(file) = file {
|
||||||
file = ?&lf,
|
let file_name = file.file_name();
|
||||||
"Tar archive written"
|
debug!(?file, ?file_name);
|
||||||
);
|
let mut file = std::fs::File::open(file.path()).expect("missing file");
|
||||||
self.as_mut()
|
tar.append_file(file_name, &mut file).expect("Error in moving file to tar");
|
||||||
.save_progress_updated(
|
thread.queue(move |mut service| {
|
||||||
100,
|
service
|
||||||
);
|
.as_mut()
|
||||||
|
.set_save_progress(
|
||||||
|
progress_fraction *
|
||||||
|
(index as f32 + 1.0) * 100.0
|
||||||
|
)
|
||||||
|
}).expect("Problem queuing on cxx thread");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if let Ok(encoder) = tar.into_inner() {
|
||||||
|
if let Ok(done) = encoder.finish() {
|
||||||
|
debug!(time = ?now.elapsed(), ?done, "tar finished");
|
||||||
|
thread.queue(move |mut service| {
|
||||||
|
service.as_mut().set_save_progress(100.0);
|
||||||
|
service.as_mut().saved_to_file(true, &file);
|
||||||
|
}).expect("Problem queuing on cxx thread");
|
||||||
fs::remove_dir_all(&temp_dir)
|
fs::remove_dir_all(&temp_dir)
|
||||||
.expect(
|
.expect(
|
||||||
"error in removal",
|
"error in removal",
|
||||||
);
|
);
|
||||||
true
|
true
|
||||||
}
|
} else {
|
||||||
Err(error) => {
|
|
||||||
error!(?error);
|
|
||||||
fs::remove_dir_all(&temp_dir)
|
fs::remove_dir_all(&temp_dir)
|
||||||
.expect(
|
.expect(
|
||||||
"error in removal",
|
"error in removal",
|
||||||
);
|
);
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
},
|
} else {
|
||||||
Err(error) => {
|
|
||||||
error!(?error);
|
|
||||||
fs::remove_dir_all(&temp_dir)
|
fs::remove_dir_all(&temp_dir)
|
||||||
.expect("error in removal");
|
.expect(
|
||||||
|
"error in removal",
|
||||||
|
);
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
true
|
||||||
}
|
}
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
error!(?error, "json error");
|
error!(?error, "json error");
|
||||||
|
@ -1086,7 +1116,7 @@ impl service_item_model::ServiceItemModel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
println!("rust-save-file-failed: {:?}", lfr);
|
error!(?save_file, "failed to save");
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue