basic save load

This commit is contained in:
2025-09-27 01:13:01 -05:00
parent d11dc271af
commit ba7fda2b5c
9 changed files with 257 additions and 41 deletions
Generated
+186 -21
View File
@@ -241,6 +241,28 @@ dependencies = [
"libloading",
]
[[package]]
name = "ashpd"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6cbdf310d77fd3aaee6ea2093db7011dc2d35d2eb3481e5607f1f8d942ed99df"
dependencies = [
"async-fs",
"async-net",
"enumflags2",
"futures-channel",
"futures-util",
"rand",
"raw-window-handle",
"serde",
"serde_repr",
"url",
"wayland-backend",
"wayland-client",
"wayland-protocols",
"zbus",
]
[[package]]
name = "async-broadcast"
version = "0.7.2"
@@ -279,6 +301,17 @@ dependencies = [
"slab",
]
[[package]]
name = "async-fs"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8034a681df4aed8b8edbd7fbe472401ecf009251c8b40556b304567052e294c5"
dependencies = [
"async-lock",
"blocking",
"futures-lite",
]
[[package]]
name = "async-io"
version = "2.5.0"
@@ -308,6 +341,17 @@ dependencies = [
"pin-project-lite",
]
[[package]]
name = "async-net"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b948000fad4873c1c9339d60f2623323a0cfd3816e5181033c6a5cb68b2accf7"
dependencies = [
"async-io",
"blocking",
"futures-lite",
]
[[package]]
name = "async-process"
version = "2.4.0"
@@ -494,6 +538,15 @@ dependencies = [
"objc2 0.5.2",
]
[[package]]
name = "block2"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "340d2f0bdb2a43c1d3cd40513185b2bd7def0aa1052f956455114bc98f82dcf2"
dependencies = [
"objc2 0.6.2",
]
[[package]]
name = "blocking"
version = "1.6.2"
@@ -785,6 +838,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89a09f22a6c6069a18470eb92d2298acf25463f14256d24778e1230d789a2aec"
dependencies = [
"bitflags 2.9.4",
"block2 0.6.1",
"libc",
"objc2 0.6.2",
]
@@ -1162,6 +1217,15 @@ dependencies = [
"percent-encoding",
]
[[package]]
name = "futures-channel"
version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10"
dependencies = [
"futures-core",
]
[[package]]
name = "futures-core"
version = "0.3.31"
@@ -1211,8 +1275,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81"
dependencies = [
"futures-core",
"futures-io",
"futures-macro",
"futures-task",
"memchr",
"pin-project-lite",
"pin-utils",
"slab",
@@ -1553,9 +1619,9 @@ dependencies = [
[[package]]
name = "indexmap"
version = "2.11.1"
version = "2.11.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "206a8042aec68fa4a62e8d3f7aa4ceb508177d9324faf261e1959e495b7a1921"
checksum = "4b0f83760fb341a774ed326568e19f5a863af4a952def8c39f9ab92fd95b88e5"
dependencies = [
"equivalent",
"hashbrown",
@@ -1995,7 +2061,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e4e89ad9e3d7d297152b17d39ed92cd50ca8063a89a9fa569046d41568891eff"
dependencies = [
"bitflags 2.9.4",
"block2",
"block2 0.5.1",
"libc",
"objc2 0.5.2",
"objc2-core-data",
@@ -2011,6 +2077,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6f29f568bec459b0ddff777cec4fe3fd8666d82d5a40ebd0ff7e66134f89bcc"
dependencies = [
"bitflags 2.9.4",
"block2 0.6.1",
"objc2 0.6.2",
"objc2-core-foundation",
"objc2-core-graphics",
@@ -2039,7 +2106,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74dd3b56391c7a0596a295029734d3c1c5e7e510a4cb30245f8221ccea96b009"
dependencies = [
"bitflags 2.9.4",
"block2",
"block2 0.5.1",
"objc2 0.5.2",
"objc2-core-location",
"objc2-foundation 0.2.2",
@@ -2051,7 +2118,7 @@ version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a5ff520e9c33812fd374d8deecef01d4a840e7b41862d849513de77e44aa4889"
dependencies = [
"block2",
"block2 0.5.1",
"objc2 0.5.2",
"objc2-foundation 0.2.2",
]
@@ -2085,7 +2152,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef"
dependencies = [
"bitflags 2.9.4",
"block2",
"block2 0.5.1",
"objc2 0.5.2",
"objc2-foundation 0.2.2",
]
@@ -2120,7 +2187,7 @@ version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55260963a527c99f1819c4f8e3b47fe04f9650694ef348ffd2227e8196d34c80"
dependencies = [
"block2",
"block2 0.5.1",
"objc2 0.5.2",
"objc2-foundation 0.2.2",
"objc2-metal",
@@ -2132,7 +2199,7 @@ version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "000cfee34e683244f284252ee206a27953279d370e309649dc3ee317b37e5781"
dependencies = [
"block2",
"block2 0.5.1",
"objc2 0.5.2",
"objc2-contacts",
"objc2-foundation 0.2.2",
@@ -2151,7 +2218,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8"
dependencies = [
"bitflags 2.9.4",
"block2",
"block2 0.5.1",
"dispatch",
"libc",
"objc2 0.5.2",
@@ -2185,7 +2252,7 @@ version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1a1ae721c5e35be65f01a03b6d2ac13a54cb4fa70d8a5da293d7b0020261398"
dependencies = [
"block2",
"block2 0.5.1",
"objc2 0.5.2",
"objc2-app-kit 0.2.2",
"objc2-foundation 0.2.2",
@@ -2198,7 +2265,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6"
dependencies = [
"bitflags 2.9.4",
"block2",
"block2 0.5.1",
"objc2 0.5.2",
"objc2-foundation 0.2.2",
]
@@ -2210,7 +2277,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a"
dependencies = [
"bitflags 2.9.4",
"block2",
"block2 0.5.1",
"objc2 0.5.2",
"objc2-foundation 0.2.2",
"objc2-metal",
@@ -2233,7 +2300,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8bb46798b20cd6b91cbd113524c490f1686f4c4e8f49502431415f3512e2b6f"
dependencies = [
"bitflags 2.9.4",
"block2",
"block2 0.5.1",
"objc2 0.5.2",
"objc2-cloud-kit",
"objc2-core-data",
@@ -2253,7 +2320,7 @@ version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44fa5f9748dbfe1ca6c0b79ad20725a11eca7c2218bceb4b005cb1be26273bfe"
dependencies = [
"block2",
"block2 0.5.1",
"objc2 0.5.2",
"objc2-foundation 0.2.2",
]
@@ -2265,7 +2332,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "76cfcbf642358e8689af64cee815d139339f3ed8ad05103ed5eaf73db8d84cb3"
dependencies = [
"bitflags 2.9.4",
"block2",
"block2 0.5.1",
"objc2 0.5.2",
"objc2-core-location",
"objc2-foundation 0.2.2",
@@ -2440,6 +2507,12 @@ dependencies = [
"windows-sys 0.60.2",
]
[[package]]
name = "pollster"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2f3a9f18d041e6d0e102a0a46750538147e5e8992d3b4873aaafee2520b00ce3"
[[package]]
name = "portable-atomic"
version = "1.11.1"
@@ -2618,6 +2691,30 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832"
[[package]]
name = "rfd"
version = "0.15.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef2bee61e6cffa4635c72d7d81a84294e28f0930db0ddcb0f66d10244674ebed"
dependencies = [
"ashpd",
"block2 0.6.1",
"dispatch2",
"js-sys",
"log",
"objc2 0.6.2",
"objc2-app-kit 0.3.1",
"objc2-core-foundation",
"objc2-foundation 0.3.1",
"pollster",
"raw-window-handle",
"urlencoding",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
"windows-sys 0.59.0",
]
[[package]]
name = "rodio"
version = "0.21.1"
@@ -2718,18 +2815,28 @@ dependencies = [
[[package]]
name = "serde"
version = "1.0.219"
version = "1.0.227"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6"
checksum = "80ece43fc6fbed4eb5392ab50c07334d3e577cbf40997ee896fe7af40bba4245"
dependencies = [
"serde_core",
"serde_derive",
]
[[package]]
name = "serde_core"
version = "1.0.227"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a576275b607a2c86ea29e410193df32bc680303c82f31e275bbfcafe8b33be5"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.219"
version = "1.0.227"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
checksum = "51e694923b8824cf0e9b382adf0f60d4e05f348f357b38833a3fa5ed7c2ede04"
dependencies = [
"proc-macro2",
"quote",
@@ -2747,6 +2854,15 @@ dependencies = [
"syn",
]
[[package]]
name = "serde_spanned"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5417783452c2be558477e104686f7de5dae53dba813c28435e0e70f82d9b04ee"
dependencies = [
"serde_core",
]
[[package]]
name = "shlex"
version = "1.3.0"
@@ -3070,8 +3186,11 @@ name = "tenori-ish"
version = "0.1.0"
dependencies = [
"eframe",
"rfd",
"rodio",
"serde",
"tokio",
"toml",
]
[[package]]
@@ -3198,12 +3317,36 @@ dependencies = [
"syn",
]
[[package]]
name = "toml"
version = "0.9.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "00e5e5d9bf2475ac9d4f0d9edab68cc573dc2fd644b0dba36b0c30a92dd9eaa0"
dependencies = [
"indexmap",
"serde_core",
"serde_spanned",
"toml_datetime 0.7.2",
"toml_parser",
"toml_writer",
"winnow",
]
[[package]]
name = "toml_datetime"
version = "0.6.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c"
[[package]]
name = "toml_datetime"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32f1085dec27c2b6632b04c80b3bb1b4300d6495d1e129693bdda7d91e72eec1"
dependencies = [
"serde_core",
]
[[package]]
name = "toml_edit"
version = "0.22.27"
@@ -3211,10 +3354,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a"
dependencies = [
"indexmap",
"toml_datetime",
"toml_datetime 0.6.11",
"winnow",
]
[[package]]
name = "toml_parser"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4cf893c33be71572e0e9aa6dd15e6677937abd686b066eac3f8cd3531688a627"
dependencies = [
"winnow",
]
[[package]]
name = "toml_writer"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d163a63c116ce562a22cda521fcc4d79152e7aba014456fb5eb442f6d6a10109"
[[package]]
name = "tracing"
version = "0.1.41"
@@ -3302,6 +3460,12 @@ dependencies = [
"serde",
]
[[package]]
name = "urlencoding"
version = "2.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da"
[[package]]
name = "utf8_iter"
version = "1.0.4"
@@ -4200,7 +4364,7 @@ dependencies = [
"android-activity",
"atomic-waker",
"bitflags 2.9.4",
"block2",
"block2 0.5.1",
"bytemuck",
"calloop",
"cfg_aliases",
@@ -4545,6 +4709,7 @@ dependencies = [
"endi",
"enumflags2",
"serde",
"url",
"winnow",
"zvariant_derive",
"zvariant_utils",
+4 -1
View File
@@ -6,4 +6,7 @@ edition = "2024"
[dependencies]
eframe = "0.32.3"
tokio = { version = "1.47.1", features = ["rt", "rt-multi-thread", "macros"] }
rodio = { version = "0.21.1", features = ["noise"] }
rodio = { version = "0.21.1", features = ["noise"] }
toml = "0.9.7"
serde = { version = "1.0.227", features = ["derive"] }
rfd = "0.15.4"
+2
View File
@@ -1,6 +1,7 @@
use std::ops::RangeInclusive;
use eframe::egui;
use eframe::egui::{Color32, Context, Id, PointerButton, Pos2, Rangef, RichText, Sense, Ui, Vec2, Widget};
use serde::{Deserialize, Serialize};
use crate::noise::NoteType;
use crate::scale::Scale;
use crate::tenori::LOOP_LENGTH;
@@ -17,6 +18,7 @@ impl NoteType {
}
}
#[derive(Serialize, Deserialize, Clone)]
pub struct Grid {
pub note_type: NoteType,
pub volume: f32,
+40 -15
View File
@@ -1,28 +1,53 @@
use std::fs;
use std::ops::RangeInclusive;
use eframe::egui;
use eframe::egui::{Context, TopBottomPanel};
use crate::noise::NoteType;
use crate::saveload::PersistedTenori;
use crate::Tenori;
impl Tenori {
pub fn menu(&mut self, ctx: &Context) {
TopBottomPanel::top("menu_panel").show(ctx, |ui| {
egui::MenuBar::new().ui(ui, |ui| {
if ui.button("Square").clicked() {
self.add_window(NoteType::Square)
}
if ui.button("Sine").clicked() {
self.add_window(NoteType::Sine)
}
if ui.button("Triangle").clicked() {
self.add_window(NoteType::Triangle)
}
if ui.button("Sawtooth").clicked() {
self.add_window(NoteType::Sawtooth)
}
if ui.button("Noise").clicked() {
self.add_window(NoteType::Noise)
}
ui.menu_button("File", |ui| {
if ui.button("Save").clicked() &&
let Ok(serialized) = toml::to_string(&PersistedTenori::from(&*self)) &&
let Some(path) = rfd::FileDialog::new().add_filter("Tenori files", &["tenori"]).set_file_name("song.tenori").save_file() {
match fs::write(path, serialized) {
Ok(_) => {}
Err(e) => { dbg!(e); }
}
}
if ui.button("Load").clicked() &&
let Some(path) = rfd::FileDialog::new().add_filter("Tenori files", &["tenori"]).pick_file() &&
let Ok(serialized) = fs::read_to_string(path) &&
let Ok(persisted) = toml::from_str::<PersistedTenori>(serialized.as_str()) {
self.grids = persisted.grids;
self.tempo = persisted.tempo;
self.playing = false;
self.timer = 0.0;
}
});
ui.menu_button("Add track", |ui| {
if ui.button("Square").clicked() {
self.add_window(NoteType::Square)
}
if ui.button("Sine").clicked() {
self.add_window(NoteType::Sine)
}
if ui.button("Triangle").clicked() {
self.add_window(NoteType::Triangle)
}
if ui.button("Sawtooth").clicked() {
self.add_window(NoteType::Sawtooth)
}
if ui.button("Noise").clicked() {
self.add_window(NoteType::Noise)
}
});
ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| {
ui.add(egui::Slider::new(&mut self.tempo, RangeInclusive::new(20, 180)));
+2 -1
View File
@@ -3,6 +3,7 @@ mod tenori;
mod grid;
mod noise;
mod scale;
mod saveload;
use std::time::Duration;
use eframe::{App, Frame};
@@ -21,7 +22,7 @@ impl App for Tenori {
fn update(&mut self, ctx: &Context, frame: &mut Frame) {
let play = self.tick();
let cursor = self.ratio();
self.menu(&ctx);
self.menu(ctx);
for g in self.grids.iter_mut() {
g.show(ctx, cursor)
}
+2 -1
View File
@@ -1,8 +1,9 @@
use std::time::Duration;
use rodio::mixer::Mixer;
use rodio::Source;
use serde::{Deserialize, Serialize};
#[derive(Copy, Clone, Debug, PartialEq)]
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
pub enum NoteType {
Sine,
Triangle,
+18
View File
@@ -0,0 +1,18 @@
use serde::{Deserialize, Serialize};
use crate::grid::Grid;
use crate::tenori::Tenori;
#[derive(Serialize, Deserialize)]
pub struct PersistedTenori {
pub tempo: u32,
pub grids: Vec<Grid>
}
impl From<&Tenori> for PersistedTenori {
fn from(value: &Tenori) -> Self {
Self {
tempo: value.tempo,
grids: value.grids.iter().map(Grid::clone).collect()
}
}
}
+2 -1
View File
@@ -1,6 +1,7 @@
use eframe::egui::RichText;
use serde::{Deserialize, Serialize};
#[derive(Copy, Clone, Debug, PartialEq)]
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
pub enum Scale {
CMajor,
CMinor,
+1 -1
View File
@@ -10,7 +10,7 @@ pub struct Tenori {
pub tempo: u32,
// A count _in beats_ of where we are in the loop
timer: f32,
pub timer: f32,
/// Whether or not we're playing; false == paused
pub playing: bool,