2022-10-01 16:58:22 +00:00
|
|
|
// Gupax - GUI Uniting P2Pool And XMRig
|
|
|
|
//
|
|
|
|
// Copyright (c) 2022 hinto-janaiyo
|
|
|
|
//
|
|
|
|
// This program is free software: you can redistribute it and/or modify
|
|
|
|
// it under the terms of the GNU General Public License as published by
|
|
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
|
|
// (at your option) any later version.
|
|
|
|
//
|
|
|
|
// This program is distributed in the hope that it will be useful,
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
// GNU General Public License for more details.
|
|
|
|
//
|
|
|
|
// You should have received a copy of the GNU General Public License
|
|
|
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
use std::path::Path;
|
update: save [Version] to state, use runtime [og: State]
[og: State] is now completely wrapped in an [Arc<Mutex>] so that
when the update is done, it can [.lock()] the CURRENT runtime
settings of the user and save to [gupax.toml] instead of using an
old copy that was given to it at the beginning of the thread.
In practice, this means users can change settings around during
an update and the update finishing and saving to disk won't be
using their old settings, but the current ones. Wrapping all of
[og: State] within in [Arc<Mutex>] might be overkill compared to
message channels but [State] really is just a few [bool]'s, [u*],
and small [String]'s, so it's not much data.
To bypass a deadlock when comparing [og == state] every frame,
[og]'s struct fields get cloned every frame into separate
variables, then it gets compared. This is also pretty stupid, but
again, the data being cloned is so tiny that it doesn't seem to
slow anything down.
2022-11-02 17:58:44 +00:00
|
|
|
use crate::{App,State};
|
2022-11-11 02:20:31 +00:00
|
|
|
use egui::TextStyle::Monospace;
|
|
|
|
use egui::RichText;
|
2022-10-01 16:58:22 +00:00
|
|
|
use crate::constants::*;
|
2022-10-27 03:15:56 +00:00
|
|
|
use crate::state::{Gupax,Version};
|
2022-10-25 02:58:42 +00:00
|
|
|
use crate::update::*;
|
2022-10-27 03:15:56 +00:00
|
|
|
use std::thread;
|
|
|
|
use std::sync::{Arc,Mutex};
|
|
|
|
use log::*;
|
2022-10-01 16:58:22 +00:00
|
|
|
|
|
|
|
impl Gupax {
|
update: save [Version] to state, use runtime [og: State]
[og: State] is now completely wrapped in an [Arc<Mutex>] so that
when the update is done, it can [.lock()] the CURRENT runtime
settings of the user and save to [gupax.toml] instead of using an
old copy that was given to it at the beginning of the thread.
In practice, this means users can change settings around during
an update and the update finishing and saving to disk won't be
using their old settings, but the current ones. Wrapping all of
[og: State] within in [Arc<Mutex>] might be overkill compared to
message channels but [State] really is just a few [bool]'s, [u*],
and small [String]'s, so it's not much data.
To bypass a deadlock when comparing [og == state] every frame,
[og]'s struct fields get cloned every frame into separate
variables, then it gets compared. This is also pretty stupid, but
again, the data being cloned is so tiny that it doesn't seem to
slow anything down.
2022-11-02 17:58:44 +00:00
|
|
|
pub fn show(state: &mut Gupax, og: &Arc<Mutex<State>>, state_ver: &Arc<Mutex<Version>>, update: &Arc<Mutex<Update>>, width: f32, height: f32, ctx: &egui::Context, ui: &mut egui::Ui) {
|
2022-10-27 03:15:56 +00:00
|
|
|
// Update button + Progress bar
|
|
|
|
ui.group(|ui| {
|
|
|
|
// These are in unnecessary [ui.vertical()]'s
|
|
|
|
// because I need to use [ui.set_enabled]s, but I can't
|
|
|
|
// find a way to use a [ui.xxx()] with [ui.add_sized()].
|
|
|
|
// I have to pick one. This one seperates them though.
|
|
|
|
let height = height/6.0;
|
|
|
|
let width = width - SPACE;
|
update: save [Version] to state, use runtime [og: State]
[og: State] is now completely wrapped in an [Arc<Mutex>] so that
when the update is done, it can [.lock()] the CURRENT runtime
settings of the user and save to [gupax.toml] instead of using an
old copy that was given to it at the beginning of the thread.
In practice, this means users can change settings around during
an update and the update finishing and saving to disk won't be
using their old settings, but the current ones. Wrapping all of
[og: State] within in [Arc<Mutex>] might be overkill compared to
message channels but [State] really is just a few [bool]'s, [u*],
and small [String]'s, so it's not much data.
To bypass a deadlock when comparing [og == state] every frame,
[og]'s struct fields get cloned every frame into separate
variables, then it gets compared. This is also pretty stupid, but
again, the data being cloned is so tiny that it doesn't seem to
slow anything down.
2022-11-02 17:58:44 +00:00
|
|
|
let updating = *update.lock().unwrap().updating.lock().unwrap();
|
2022-10-27 03:15:56 +00:00
|
|
|
ui.vertical(|ui| {
|
2022-10-27 15:52:18 +00:00
|
|
|
ui.set_enabled(!updating);
|
2022-10-27 03:15:56 +00:00
|
|
|
if ui.add_sized([width, height], egui::Button::new("Check for updates")).on_hover_text(GUPAX_UPDATE).clicked() {
|
update: save [Version] to state, use runtime [og: State]
[og: State] is now completely wrapped in an [Arc<Mutex>] so that
when the update is done, it can [.lock()] the CURRENT runtime
settings of the user and save to [gupax.toml] instead of using an
old copy that was given to it at the beginning of the thread.
In practice, this means users can change settings around during
an update and the update finishing and saving to disk won't be
using their old settings, but the current ones. Wrapping all of
[og: State] within in [Arc<Mutex>] might be overkill compared to
message channels but [State] really is just a few [bool]'s, [u*],
and small [String]'s, so it's not much data.
To bypass a deadlock when comparing [og == state] every frame,
[og]'s struct fields get cloned every frame into separate
variables, then it gets compared. This is also pretty stupid, but
again, the data being cloned is so tiny that it doesn't seem to
slow anything down.
2022-11-02 17:58:44 +00:00
|
|
|
update.lock().unwrap().path_p2pool = og.lock().unwrap().gupax.absolute_p2pool_path.display().to_string();
|
|
|
|
update.lock().unwrap().path_xmrig = og.lock().unwrap().gupax.absolute_xmrig_path.display().to_string();
|
|
|
|
update.lock().unwrap().tor = og.lock().unwrap().gupax.update_via_tor;
|
|
|
|
let og = Arc::clone(&og);
|
|
|
|
let og_ver = Arc::clone(&og.lock().unwrap().version);
|
|
|
|
let state_ver = Arc::clone(&state_ver);
|
|
|
|
let update = Arc::clone(&update);
|
|
|
|
let update_thread = Arc::clone(&update);
|
2022-10-27 03:15:56 +00:00
|
|
|
thread::spawn(move|| {
|
|
|
|
info!("Spawning update thread...");
|
update: save [Version] to state, use runtime [og: State]
[og: State] is now completely wrapped in an [Arc<Mutex>] so that
when the update is done, it can [.lock()] the CURRENT runtime
settings of the user and save to [gupax.toml] instead of using an
old copy that was given to it at the beginning of the thread.
In practice, this means users can change settings around during
an update and the update finishing and saving to disk won't be
using their old settings, but the current ones. Wrapping all of
[og: State] within in [Arc<Mutex>] might be overkill compared to
message channels but [State] really is just a few [bool]'s, [u*],
and small [String]'s, so it's not much data.
To bypass a deadlock when comparing [og == state] every frame,
[og]'s struct fields get cloned every frame into separate
variables, then it gets compared. This is also pretty stupid, but
again, the data being cloned is so tiny that it doesn't seem to
slow anything down.
2022-11-02 17:58:44 +00:00
|
|
|
match Update::start(update_thread, og_ver.clone(), state_ver.clone()) {
|
2022-10-27 15:52:18 +00:00
|
|
|
Err(e) => {
|
2022-11-02 22:18:41 +00:00
|
|
|
info!("Update ... FAIL ... {}", e);
|
2022-10-28 20:14:43 +00:00
|
|
|
*update.lock().unwrap().msg.lock().unwrap() = format!("{} | {}", MSG_FAILED, e);
|
2022-10-27 15:52:18 +00:00
|
|
|
},
|
update: save [Version] to state, use runtime [og: State]
[og: State] is now completely wrapped in an [Arc<Mutex>] so that
when the update is done, it can [.lock()] the CURRENT runtime
settings of the user and save to [gupax.toml] instead of using an
old copy that was given to it at the beginning of the thread.
In practice, this means users can change settings around during
an update and the update finishing and saving to disk won't be
using their old settings, but the current ones. Wrapping all of
[og: State] within in [Arc<Mutex>] might be overkill compared to
message channels but [State] really is just a few [bool]'s, [u*],
and small [String]'s, so it's not much data.
To bypass a deadlock when comparing [og == state] every frame,
[og]'s struct fields get cloned every frame into separate
variables, then it gets compared. This is also pretty stupid, but
again, the data being cloned is so tiny that it doesn't seem to
slow anything down.
2022-11-02 17:58:44 +00:00
|
|
|
_ => {
|
|
|
|
info!("Update | Saving state...");
|
|
|
|
match State::save(&mut og.lock().unwrap()) {
|
|
|
|
Ok(_) => info!("Update ... OK"),
|
|
|
|
Err(e) => {
|
|
|
|
warn!("Update | Saving state ... FAIL ... {}", e);
|
|
|
|
*update.lock().unwrap().msg.lock().unwrap() = format!("Saving new versions into state failed");
|
|
|
|
},
|
|
|
|
};
|
|
|
|
}
|
|
|
|
};
|
|
|
|
*update.lock().unwrap().updating.lock().unwrap() = false;
|
2022-10-27 03:15:56 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
ui.vertical(|ui| {
|
2022-10-27 15:52:18 +00:00
|
|
|
ui.set_enabled(updating);
|
update: save [Version] to state, use runtime [og: State]
[og: State] is now completely wrapped in an [Arc<Mutex>] so that
when the update is done, it can [.lock()] the CURRENT runtime
settings of the user and save to [gupax.toml] instead of using an
old copy that was given to it at the beginning of the thread.
In practice, this means users can change settings around during
an update and the update finishing and saving to disk won't be
using their old settings, but the current ones. Wrapping all of
[og: State] within in [Arc<Mutex>] might be overkill compared to
message channels but [State] really is just a few [bool]'s, [u*],
and small [String]'s, so it's not much data.
To bypass a deadlock when comparing [og == state] every frame,
[og]'s struct fields get cloned every frame into separate
variables, then it gets compared. This is also pretty stupid, but
again, the data being cloned is so tiny that it doesn't seem to
slow anything down.
2022-11-02 17:58:44 +00:00
|
|
|
let prog = *update.lock().unwrap().prog.lock().unwrap();
|
|
|
|
let msg = format!("{}\n{}{}", *update.lock().unwrap().msg.lock().unwrap(), prog, "%");
|
2022-11-11 02:20:31 +00:00
|
|
|
ui.add_sized([width, height*1.4], egui::Label::new(RichText::text_style(RichText::new(msg), Monospace)));
|
2022-10-27 03:15:56 +00:00
|
|
|
let height = height/2.0;
|
2022-10-28 19:45:13 +00:00
|
|
|
if updating {
|
|
|
|
ui.add_sized([width, height], egui::Spinner::new().size(height));
|
|
|
|
} else {
|
|
|
|
ui.add_sized([width, height], egui::Label::new("..."));
|
|
|
|
}
|
update: save [Version] to state, use runtime [og: State]
[og: State] is now completely wrapped in an [Arc<Mutex>] so that
when the update is done, it can [.lock()] the CURRENT runtime
settings of the user and save to [gupax.toml] instead of using an
old copy that was given to it at the beginning of the thread.
In practice, this means users can change settings around during
an update and the update finishing and saving to disk won't be
using their old settings, but the current ones. Wrapping all of
[og: State] within in [Arc<Mutex>] might be overkill compared to
message channels but [State] really is just a few [bool]'s, [u*],
and small [String]'s, so it's not much data.
To bypass a deadlock when comparing [og == state] every frame,
[og]'s struct fields get cloned every frame into separate
variables, then it gets compared. This is also pretty stupid, but
again, the data being cloned is so tiny that it doesn't seem to
slow anything down.
2022-11-02 17:58:44 +00:00
|
|
|
ui.add_sized([width, height], egui::ProgressBar::new((update.lock().unwrap().prog.lock().unwrap().round() / 100.0)));
|
2022-10-27 03:15:56 +00:00
|
|
|
});
|
|
|
|
});
|
2022-10-01 16:58:22 +00:00
|
|
|
|
|
|
|
ui.horizontal(|ui| {
|
|
|
|
ui.group(|ui| {
|
2022-10-28 19:45:13 +00:00
|
|
|
let width = (width - SPACE*9.8)/5.0;
|
2022-11-02 22:18:41 +00:00
|
|
|
let height = height/2.5;
|
2022-10-17 00:36:58 +00:00
|
|
|
let mut style = (*ctx.style()).clone();
|
2022-10-28 19:45:13 +00:00
|
|
|
style.spacing.icon_width_inner = width / 6.0;
|
|
|
|
style.spacing.icon_width = width / 4.0;
|
|
|
|
style.spacing.icon_spacing = 20.0;
|
2022-10-17 00:36:58 +00:00
|
|
|
ctx.set_style(style);
|
2022-11-02 22:18:41 +00:00
|
|
|
let height = height/2.5;
|
2022-10-27 03:15:56 +00:00
|
|
|
ui.add_sized([width, height], egui::Checkbox::new(&mut state.auto_update, "Auto-update")).on_hover_text(GUPAX_AUTO_UPDATE);
|
|
|
|
ui.separator();
|
|
|
|
ui.add_sized([width, height], egui::Checkbox::new(&mut state.auto_node, "Auto-node")).on_hover_text(GUPAX_AUTO_NODE);
|
|
|
|
ui.separator();
|
|
|
|
ui.add_sized([width, height], egui::Checkbox::new(&mut state.update_via_tor, "Update via Tor")).on_hover_text(GUPAX_UPDATE_VIA_TOR);
|
|
|
|
ui.separator();
|
|
|
|
ui.add_sized([width, height], egui::Checkbox::new(&mut state.ask_before_quit, "Ask before quit")).on_hover_text(GUPAX_ASK_BEFORE_QUIT);
|
|
|
|
ui.separator();
|
|
|
|
ui.add_sized([width, height], egui::Checkbox::new(&mut state.save_before_quit, "Save before quit")).on_hover_text(GUPAX_SAVE_BEFORE_QUIT);
|
2022-10-01 16:58:22 +00:00
|
|
|
});
|
|
|
|
});
|
2022-10-27 03:15:56 +00:00
|
|
|
ui.add_space(SPACE);
|
2022-10-01 16:58:22 +00:00
|
|
|
|
|
|
|
ui.horizontal(|ui| {
|
|
|
|
ui.label("P2Pool binary path:");
|
2022-10-28 19:45:13 +00:00
|
|
|
ui.spacing_mut().text_edit_width = ui.available_width() - SPACE;
|
2022-10-17 00:36:58 +00:00
|
|
|
ui.text_edit_singleline(&mut state.p2pool_path).on_hover_text(GUPAX_PATH_P2POOL);
|
2022-10-01 16:58:22 +00:00
|
|
|
});
|
|
|
|
ui.horizontal(|ui| {
|
|
|
|
ui.label("XMRig binary path: ");
|
2022-10-28 19:45:13 +00:00
|
|
|
ui.spacing_mut().text_edit_width = ui.available_width() - SPACE;
|
2022-10-17 00:36:58 +00:00
|
|
|
ui.text_edit_singleline(&mut state.xmrig_path).on_hover_text(GUPAX_PATH_XMRIG);
|
2022-10-01 16:58:22 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|