Skip to content

Commit

Permalink
Persist sketch parameters across app relaunch (#94)
Browse files Browse the repository at this point in the history
  • Loading branch information
abey79 authored Dec 31, 2023
1 parent f56ca54 commit 6cc5cac
Show file tree
Hide file tree
Showing 22 changed files with 80 additions and 29 deletions.
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

0 comments on commit 6cc5cac

Please sign in to comment.