Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Persist sketch parameters across app relaunch #94

Merged
merged 1 commit into from
Dec 31, 2023
Merged
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
8 changes: 4 additions & 4 deletions Cargo.lock

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

2 changes: 1 addition & 1 deletion crates/vsvg/src/color.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::fmt;

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub struct Color {
pub r: u8,
pub g: u8,
Expand Down
2 changes: 1 addition & 1 deletion crates/vsvg/src/path/point.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#[derive(Debug, Clone, Copy, PartialEq, Default)]
#[derive(Debug, Clone, Copy, PartialEq, Default, serde::Serialize, serde::Deserialize)]
pub struct Point {
data: [f64; 2],
}
Expand Down
40 changes: 40 additions & 0 deletions crates/whiskers-derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,46 @@ fn format_label(label: &str) -> String {
format!("{}:", label.to_case(Case::Lower))
}

/// Attribute macro to automatically derive some of the required traits for a sketch app.
///
/// This is equivalent to:
/// ```ignore
/// #[derive(Sketch, serde::Serialize, serde::Deserialize)]
/// #[serde(crate = "::whiskers::prelude::serde")]
/// ```
#[proc_macro_attribute]
pub fn sketch_app(_attr: TokenStream, item: TokenStream) -> TokenStream {
let ast = parse_macro_input!(item as DeriveInput);

let expanded = quote! {
#[derive(Sketch, serde::Serialize, serde::Deserialize)]
#[serde(crate = "::whiskers::prelude::serde")]
#ast
};

TokenStream::from(expanded)
}

/// Attribute macro to automatically derive some of the required traits for a sketch widget.
///
/// This is equivalent to:
/// ```ignore
/// #[derive(Widget, serde::Serialize, serde::Deserialize)]
/// #[serde(crate = "::whiskers::prelude::serde")]
/// ```
#[proc_macro_attribute]
pub fn sketch_widget(_attr: TokenStream, item: TokenStream) -> TokenStream {
let ast = parse_macro_input!(item as DeriveInput);

let expanded = quote! {
#[derive(Widget, serde::Serialize, serde::Deserialize)]
#[serde(crate = "::whiskers::prelude::serde")]
#ast
};

TokenStream::from(expanded)
}

#[proc_macro_derive(Sketch, attributes(param, skip))]
pub fn sketch_derive(input: TokenStream) -> TokenStream {
let input: DeriveInput = parse_macro_input!(input);
Expand Down
2 changes: 1 addition & 1 deletion crates/whiskers-web-demo/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
use itertools::iproduct;
use whiskers::prelude::*;

#[derive(Sketch)]
#[sketch_app]
pub struct WhiskersDemoSketch {
col_count: u32,
row_count: u32,
Expand Down
4 changes: 2 additions & 2 deletions crates/whiskers/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ Here is the code for a basic sketch:
```rust
use whiskers::prelude::*;

#[derive(Sketch)] // <- this is the magic to make the sketch interactive
#[sketch_app] // <- this is the magic to make the sketch interactive
struct HelloWorldSketch {
width: f64, // <- interactive UI is automagically built for these fields
height: f64,
Expand Down Expand Up @@ -82,7 +82,7 @@ This is the result:
- [x] Random Number Generator UI with seed control (see e.g. `asteroid` example).
- [x] Integrated profiler (based on [puffin](https://github.com/EmbarkStudios/puffin)).
- [x] `Grid` helper for grid-based sketches.
- [x] `HexGrid` helper for hexagonal-grid-based sketches
- [x] `HexGrid` helper for hexagonal-grid-based sketches
- [ ] Configuration handling (save/restore config, etc.).
- [ ] Compiled sketches are *also* a flexible CLI utility with the capability to batch generate sketch outputs with parameter ranges.
- [ ] Export to other format through templating (HPGL, g-code, etc. — for now, please use [*vpype*](https://github.com/abey79/vpype)).
Expand Down
2 changes: 1 addition & 1 deletion crates/whiskers/examples/animation_demo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
use std::f64::consts::TAU;
use whiskers::prelude::*;

#[derive(Sketch)]
#[sketch_app]
struct AnimationDemoSketch {
#[param(min = 3, max = 15)]
ngon_sides: usize,
Expand Down
2 changes: 1 addition & 1 deletion crates/whiskers/examples/app_demo.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use whiskers::prelude::*;

#[derive(Sketch)]
#[sketch_app]
struct MySketch {
#[param(slider, min = 0.0, max = 10.0, step = 2.0)]
rate: f64,
Expand Down
2 changes: 1 addition & 1 deletion crates/whiskers/examples/asteroid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use rand_distr::{Distribution, Normal};
use std::f64::consts::PI;
use whiskers::prelude::*;

#[derive(Sketch)]
#[sketch_app]
struct AsteroidSketch {
#[param(slider, min = 0.1, max = 1.5)]
irregularity: f64,
Expand Down
2 changes: 1 addition & 1 deletion crates/whiskers/examples/bezpath.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
use whiskers::prelude::*;

#[derive(Sketch)]
#[sketch_app]
struct BezpathSketch {
// path 1
move_to: Point,
Expand Down
2 changes: 1 addition & 1 deletion crates/whiskers/examples/catmull_rom.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use whiskers::prelude::*;

#[derive(Sketch)]
#[sketch_app]
struct CatmullRomSketch {
#[param(slider, min = 3, max = 1500)]
num_points: usize,
Expand Down
4 changes: 2 additions & 2 deletions crates/whiskers/examples/custom_ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use egui::Ui;
use whiskers::prelude::*;

/// Very custom data structure that is not supported by default
#[derive(Debug, Clone, Copy)]
#[derive(Debug, Clone, Copy, serde::Serialize, serde::Deserialize)]
struct GrayRed {
gray: f64,
red: f64,
Expand Down Expand Up @@ -85,7 +85,7 @@ register_widget_ui!(GrayRed, GrayRedWidget);
// =================================================================================
// from here on, we're back to super standard sketch code...

#[derive(Sketch)]
#[sketch_app]
struct CustomUISketch {
// these param key/value will call into the [`GrayRedWidget`]'s builder methods.
#[param(underline, label_color = egui::Color32::BLUE)]
Expand Down
2 changes: 1 addition & 1 deletion crates/whiskers/examples/grid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
use whiskers::prelude::*;

#[derive(Sketch)]
#[sketch_app]
struct GridSketch {
#[param(slider, min = 20.0, max = 400.0)]
width: f64,
Expand Down
2 changes: 1 addition & 1 deletion crates/whiskers/examples/hello_world.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use whiskers::prelude::*;

#[derive(Sketch)]
#[sketch_app]
struct HelloWorldSketch {
width: f64,
height: f64,
Expand Down
2 changes: 1 addition & 1 deletion crates/whiskers/examples/hex_grid.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! This example demonstrates the use of the [`HexGrid`] helper.
use whiskers::prelude::*;

#[derive(Sketch)]
#[sketch_app]
struct HexGridSketch {
is_pointy_orientation: bool,
#[param(slider, min = 2, max = 20)]
Expand Down
2 changes: 1 addition & 1 deletion crates/whiskers/examples/noise.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use noise::{Fbm, NoiseFn, Perlin};
use rayon::prelude::*;
use whiskers::prelude::*;

#[derive(Sketch)]
#[sketch_app]
struct NoiseSketch {
#[param(slider, min = 0.0, max = 500.0)]
margin: f64,
Expand Down
2 changes: 1 addition & 1 deletion crates/whiskers/examples/rng.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::ops::Range;
use vsvg::COLORS;
use whiskers::prelude::*;

#[derive(Sketch)]
#[sketch_app]
struct RngSketch {
width: f64,
height: f64,
Expand Down
9 changes: 6 additions & 3 deletions crates/whiskers/examples/ui_demo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@

use whiskers::prelude::*;

#[derive(Sketch, Default)]
#[sketch_app]
#[derive(Default)]
struct UiDemoSketch {
// all basic numerical types are supported
int_64: i64,
Expand Down Expand Up @@ -40,7 +41,8 @@ struct UiDemoSketch {
// the [`whiskers::widgets::WidgetMapper`] trait can be implemented manually, see the `custom_ui`
// example.
// Note: all types must implement [`Default`].
#[derive(Widget, Default)]
#[sketch_widget]
#[derive(Default)]
struct CustomStruct {
#[param(min = 0.0)]
some_float: f64,
Expand All @@ -53,7 +55,8 @@ struct CustomStruct {
}

// Tuple structs are supported too
#[derive(Widget, Default)]
#[sketch_widget]
#[derive(Default)]
struct CustomStructUnnamed(bool, String);

impl App for UiDemoSketch {
Expand Down
6 changes: 3 additions & 3 deletions crates/whiskers/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
//! ```no_run
//! use whiskers::prelude::*;
//!
//! #[derive(Sketch)]
//! #[sketch_app]
//! struct MySketch {
//! /* add sketch parameters here */
//! }
Expand Down Expand Up @@ -60,7 +60,7 @@
//! use whiskers::prelude::*;
//! use whiskers::wasm_main;
//!
//! #[derive(Sketch)]
//! #[sketch_app]
//! struct MySketch { }
//!
//! impl Default for MySketch {
Expand Down Expand Up @@ -135,7 +135,7 @@ pub trait App {

/// This trait is implemented by the [`whiskers_derive::Sketch`] derive macro and makes it possible
/// for the [`Runner`] to execute your sketch.s
pub trait SketchApp: App + Default {
pub trait SketchApp: App + Default + serde::Serialize + serde::de::DeserializeOwned {
/// Create a runner for this app.
fn runner<'a>() -> Runner<'a, Self> {
Runner::<Self>::new()
Expand Down
4 changes: 3 additions & 1 deletion crates/whiskers/src/prelude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ pub use crate::{
HexGridCell, InfoOptions, LayoutOptions, PageSizeOptions, Result, Runner, Sketch, SketchApp,
};
pub use vsvg::{Color, Draw, IntoBezPath, IntoBezPathTolerance, PageSize, Point, Transforms, Unit};
pub use whiskers_derive::{Sketch, Widget};
pub use whiskers_derive::{sketch_app, sketch_widget, Sketch, Widget};

#[cfg(not(target_arch = "wasm32"))]
pub use vsvg_viewer::show;

// re-exports
pub use ::serde;
pub use anyhow;
pub use egui;
pub use rand::prelude::*;
Expand Down
5 changes: 5 additions & 0 deletions crates/whiskers/src/runner/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,10 @@ impl<A: crate::SketchApp> vsvg_viewer::ViewerApp for Runner<'_, A> {
}

fn load(&mut self, storage: &dyn Storage) {
if let Some(app) = eframe::get_value(storage, "whiskers-app") {
self.app = app;
}

let save_ui: Option<SaveUI> = eframe::get_value(storage, "whiskers-runner-save-ui");
#[allow(unused_mut)]
if let Some(mut save_ui) = save_ui {
Expand All @@ -358,6 +362,7 @@ impl<A: crate::SketchApp> vsvg_viewer::ViewerApp for Runner<'_, A> {
}

fn save(&self, storage: &mut dyn Storage) {
eframe::set_value(storage, "whiskers-app", &self.app);
eframe::set_value(storage, "whiskers-runner-save-ui", &self.save_ui);
eframe::set_value(storage, "whiskers-layout-options", &self.layout_options);
eframe::set_value(storage, "whiskers-page-size", &self.page_size_options);
Expand Down
3 changes: 2 additions & 1 deletion crates/whiskers/src/widgets/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,8 @@
//! Now let's consider a hypothetical sketch:
//! ```rust
//! # use whiskers::prelude::*;
//! #[derive(Sketch, Default)]
//! #[sketch_app]
//! #[derive(Default)]
//! struct MySketch {
//! #[param(slider, step = 0.1)]
//! irregularity: f64,
Expand Down