Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/onpush.yml
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ jobs:
run: |
sudo apt-get install -y wget libfuse-dev libgtk-3-dev
cargo install --force cargo-appimage
wget https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-$(uname -m).AppImage -O appimagetool
wget https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-$(uname -m).AppImage -O appimagetool
chmod a+x appimagetool

- name: Install Rust targets (macOS)
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
/target
.DS_Store
.vscode/
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 18 additions & 0 deletions data/BattleToads
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
0x000D = count of levels beaten
0x0010 = level ID

; enum level_names
intro: = 0
ragnarok_canyon: = 1
wookie_hole: = 2
TurboTunnel: = 3
arctic_caverns: = 4
revolution: = 5
volkmire_inferno: = 6
intruder_excluder: = 7
karnath_lair: = 8
rat_race: = 9
clinger_winger: = $A
terra_tubes: = $B
SurfCity: = $C
armageddon: = $D
4 changes: 2 additions & 2 deletions src/autosplitters/json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ where
.strip_prefix("0x")
.or_else(|| s.strip_prefix("0X"))
.unwrap_or(s);
u32::from_str_radix(s, 16).map_err(|e| de::Error::custom(format!("invalid hex: {}", e)))
u32::from_str_radix(s, 16).map_err(|e| de::Error::custom(format!("invalid hex: {e}")))
}

fn string_to_bool<'de, D>(deserializer: D) -> Result<bool, D::Error>
Expand All @@ -139,6 +139,6 @@ where
match s.trim() {
"1" => Ok(true),
"0" => Ok(false),
_ => Err(de::Error::custom(format!("invalid boolean string: {}", s))),
_ => Err(de::Error::custom(format!("invalid boolean string: {s}"))),
}
}
147 changes: 116 additions & 31 deletions src/config/app_config.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use clap::Parser;
use livesplit_hotkey::{Hotkey, KeyCode, Modifiers};
use serde_derive::{Deserialize, Serialize};

use crate::hotkey::*;
use crate::utils::*;
// use crate::hotkey::*;

#[derive(Deserialize, Serialize, Parser, Debug, Clone)]
#[clap(author, version, about, long_about = None)]
Expand All @@ -25,19 +27,21 @@ pub struct AppConfig {
#[clap(name = "global-hotkeys", long, short = 'g', value_parser)]
pub global_hotkeys: Option<YesOrNo>,
#[clap(skip)]
pub hot_key_start: Option<HotKey>,
pub hot_key_start: Option<Hotkey>,
#[clap(skip)]
pub hot_key_reset: Option<HotKey>,
pub hot_key_reset: Option<Hotkey>,
#[clap(skip)]
pub hot_key_undo: Option<HotKey>,
pub hot_key_undo: Option<Hotkey>,
#[clap(skip)]
pub hot_key_skip: Option<HotKey>,
pub hot_key_skip: Option<Hotkey>,
#[clap(skip)]
pub hot_key_pause: Option<HotKey>,
pub hot_key_pause: Option<Hotkey>,
#[clap(skip)]
pub hot_key_comparison_next: Option<HotKey>,
pub hot_key_comparison_next: Option<Hotkey>,
#[clap(skip)]
pub hot_key_comparison_prev: Option<HotKey>,
pub hot_key_comparison_prev: Option<Hotkey>,
#[clap(skip)]
pub hot_key_toggle_global_hotkeys: Option<Hotkey>,
}

#[derive(clap::ValueEnum, Clone, Copy, Debug, Serialize, Deserialize, Default, PartialEq, Eq)]
Expand All @@ -47,43 +51,64 @@ pub enum YesOrNo {
No,
}

impl From<bool> for YesOrNo {
fn from(b: bool) -> Self {
match b {
true => YesOrNo::Yes,
false => YesOrNo::No,
}
}
}

impl From<YesOrNo> for bool {
fn from(yes: YesOrNo) -> Self {
match yes {
YesOrNo::Yes => true,
YesOrNo::No => false,
}
}
}

pub const DEFAULT_FRAME_RATE: f32 = 30.0;
pub const DEFAULT_POLLING_RATE: f32 = 20.0;

impl AppConfig {
fn new() -> Self {
let modifiers = ::egui::Modifiers::default();
pub fn new() -> Self {
AppConfig {
recent_splits: None,
recent_layout: None,
recent_autosplitter: None,
hot_key_start: Some(HotKey {
key: egui::Key::Num1,
modifiers,
hot_key_start: Some(Hotkey {
key_code: KeyCode::Numpad1,
modifiers: Modifiers::empty(),
}),
hot_key_reset: Some(HotKey {
key: egui::Key::Num3,
modifiers,
hot_key_reset: Some(Hotkey {
key_code: KeyCode::Numpad3,
modifiers: Modifiers::empty(),
}),
hot_key_undo: Some(HotKey {
key: egui::Key::Num8,
modifiers,
hot_key_undo: Some(Hotkey {
key_code: KeyCode::Numpad8,
modifiers: Modifiers::empty(),
}),
hot_key_skip: Some(HotKey {
key: egui::Key::Num2,
modifiers,
hot_key_skip: Some(Hotkey {
key_code: KeyCode::Numpad2,
modifiers: Modifiers::empty(),
}),
hot_key_pause: Some(HotKey {
key: egui::Key::Num5,
modifiers,
hot_key_pause: Some(Hotkey {
key_code: KeyCode::Numpad5,
modifiers: Modifiers::empty(),
}),
hot_key_comparison_next: Some(HotKey {
key: egui::Key::Num6,
modifiers,
hot_key_comparison_next: Some(Hotkey {
key_code: KeyCode::Numpad6,
modifiers: Modifiers::empty(),
}),
hot_key_comparison_prev: Some(HotKey {
key: egui::Key::Num4,
modifiers,
hot_key_comparison_prev: Some(Hotkey {
key_code: KeyCode::Numpad4,
modifiers: Modifiers::empty(),
}),
hot_key_toggle_global_hotkeys: Some(Hotkey {
key_code: KeyCode::Numpad9,
modifiers: Modifiers::empty(),
}),
use_autosplitter: Some(YesOrNo::Yes),
frame_rate: Some(DEFAULT_FRAME_RATE),
Expand All @@ -93,6 +118,66 @@ impl AppConfig {
global_hotkeys: Some(YesOrNo::Yes),
}
}

pub fn save_app_config(&self) {
use std::io::Write;
let project_dirs = directories::ProjectDirs::from("", "", "annelid") // get directories
.ok_or("Unable to load computer configuration directory");
println!("project_dirs = {project_dirs:#?}");

let config_dir = project_dirs.unwrap(); // get preferences directory
println!("project_dirs = {:#?}", config_dir.preference_dir());

messagebox_on_error(|| {
std::fs::create_dir_all(config_dir.preference_dir()).expect("Created config dir"); // create preferences directory

let mut config_path = config_dir.preference_dir().to_path_buf();
config_path.push("settings.toml");

println!("Saving to {config_path:#?}");
let f = std::fs::OpenOptions::new()
.create(true)
.write(true)
.truncate(true)
.open(config_path)?;
let mut writer = std::io::BufWriter::new(f);
let toml = toml::to_string_pretty(&self)?;
writer.write_all(toml.as_bytes())?;
writer.flush()?;
Ok(())
});
}

pub fn load_app_config(mut self) -> Self {
let project_dirs = directories::ProjectDirs::from("", "", "annelid") // get directories
.ok_or("Unable to load computer configuration directory");
println!("project_dirs = {project_dirs:#?}");

let config_dir = project_dirs.unwrap(); // get preferences directory
println!("project_dirs = {:#?}", config_dir.preference_dir());

messagebox_on_error(|| {
use std::io::Read;
let mut config_path = config_dir.preference_dir().to_path_buf();
config_path.push("settings.toml");
println!("Loading from {config_path:#?}");
let saved_config: AppConfig = std::fs::File::open(config_path)
.and_then(|mut f| {
let mut buffer = String::new();
f.read_to_string(&mut buffer)?;
match toml::from_str(&buffer) {
Ok(app_config) => Ok(app_config),
Err(e) => Err(from_de_error(e)),
}

// }).unwrap;
})
.unwrap_or_default();
self = saved_config;
Ok(())
});
self
}
}

impl Default for AppConfig {
Expand Down
Loading
Loading