Use global state

This commit is contained in:
Dane Johnson 2022-05-03 15:41:42 -05:00
parent 679fd3e275
commit 74ad76f504
4 changed files with 238 additions and 27 deletions

212
Cargo.lock generated
View File

@ -26,6 +26,15 @@ dependencies = [
"opaque-debug", "opaque-debug",
] ]
[[package]]
name = "ansi_term"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2"
dependencies = [
"winapi",
]
[[package]] [[package]]
name = "autocfg" name = "autocfg"
version = "1.1.0" version = "1.1.0"
@ -67,6 +76,7 @@ dependencies = [
"image", "image",
"serde", "serde",
"serde_json", "serde_json",
"state",
"zip", "zip",
] ]
@ -328,6 +338,19 @@ version = "0.3.21"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868" checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868"
[[package]]
name = "generator"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c1d9279ca822891c1a4dae06d185612cf8fc6acfe5dff37781b41297811b12ee"
dependencies = [
"cc",
"libc",
"log",
"rustversion",
"winapi",
]
[[package]] [[package]]
name = "generic-array" name = "generic-array"
version = "0.14.5" version = "0.14.5"
@ -484,6 +507,30 @@ dependencies = [
"cfg-if", "cfg-if",
] ]
[[package]]
name = "loom"
version = "0.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "edc5c7d328e32cc4954e8e01193d7f0ef5ab257b5090b70a964e099a36034309"
dependencies = [
"cfg-if",
"generator",
"scoped-tls",
"serde",
"serde_json",
"tracing",
"tracing-subscriber",
]
[[package]]
name = "matchers"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558"
dependencies = [
"regex-automata",
]
[[package]] [[package]]
name = "memoffset" name = "memoffset"
version = "0.6.5" version = "0.6.5"
@ -571,6 +618,12 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "once_cell"
version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9"
[[package]] [[package]]
name = "opaque-debug" name = "opaque-debug"
version = "0.3.0" version = "0.3.0"
@ -626,6 +679,12 @@ dependencies = [
"syn", "syn",
] ]
[[package]]
name = "pin-project-lite"
version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116"
[[package]] [[package]]
name = "pkg-config" name = "pkg-config"
version = "0.3.25" version = "0.3.25"
@ -692,12 +751,48 @@ dependencies = [
"num_cpus", "num_cpus",
] ]
[[package]]
name = "regex"
version = "1.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a11647b6b25ff05a515cb92c365cec08801e83423a235b51e231e1808747286"
dependencies = [
"regex-syntax",
]
[[package]]
name = "regex-automata"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132"
dependencies = [
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.6.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
[[package]]
name = "rustversion"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2cc38e8fa666e2de3c4aba7edeb5ffc5246c1c2ed0e3d17e560aeeba736b23f"
[[package]] [[package]]
name = "ryu" name = "ryu"
version = "1.0.9" version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f"
[[package]]
name = "scoped-tls"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2"
[[package]] [[package]]
name = "scoped_threadpool" name = "scoped_threadpool"
version = "0.1.9" version = "0.1.9"
@ -763,6 +858,15 @@ dependencies = [
"digest", "digest",
] ]
[[package]]
name = "sharded-slab"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31"
dependencies = [
"lazy_static",
]
[[package]] [[package]]
name = "smallvec" name = "smallvec"
version = "1.8.0" version = "1.8.0"
@ -778,6 +882,15 @@ dependencies = [
"lock_api", "lock_api",
] ]
[[package]]
name = "state"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dbe866e1e51e8260c9eed836a042a5e7f6726bb2b411dffeaa712e19c388f23b"
dependencies = [
"loom",
]
[[package]] [[package]]
name = "subtle" name = "subtle"
version = "2.4.1" version = "2.4.1"
@ -795,6 +908,15 @@ dependencies = [
"unicode-xid", "unicode-xid",
] ]
[[package]]
name = "thread_local"
version = "1.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5516c27b78311c50bf42c071425c560ac799b11c30b31f87e3081965fe5e0180"
dependencies = [
"once_cell",
]
[[package]] [[package]]
name = "threadpool" name = "threadpool"
version = "1.8.1" version = "1.8.1"
@ -833,6 +955,68 @@ version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42657b1a6f4d817cda8e7a0ace261fe0cc946cf3a80314390b22cc61ae080792" checksum = "42657b1a6f4d817cda8e7a0ace261fe0cc946cf3a80314390b22cc61ae080792"
[[package]]
name = "tracing"
version = "0.1.34"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5d0ecdcb44a79f0fe9844f0c4f33a342cbcbb5117de8001e6ba0dc2351327d09"
dependencies = [
"cfg-if",
"pin-project-lite",
"tracing-attributes",
"tracing-core",
]
[[package]]
name = "tracing-attributes"
version = "0.1.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cc6b8ad3567499f98a1db7a752b07a7c8c7c7c34c332ec00effb2b0027974b7c"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "tracing-core"
version = "0.1.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f54c8ca710e81886d498c2fd3331b56c93aa248d49de2222ad2742247c60072f"
dependencies = [
"lazy_static",
"valuable",
]
[[package]]
name = "tracing-log"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922"
dependencies = [
"lazy_static",
"log",
"tracing-core",
]
[[package]]
name = "tracing-subscriber"
version = "0.3.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4bc28f93baff38037f64e6f43d34cfa1605f27a49c34e8a04c5e78b0babf2596"
dependencies = [
"ansi_term",
"lazy_static",
"matchers",
"regex",
"sharded-slab",
"smallvec",
"thread_local",
"tracing",
"tracing-core",
"tracing-log",
]
[[package]] [[package]]
name = "ttf-parser" name = "ttf-parser"
version = "0.15.0" version = "0.15.0"
@ -851,6 +1035,12 @@ version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
[[package]]
name = "valuable"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
[[package]] [[package]]
name = "version_check" name = "version_check"
version = "0.9.4" version = "0.9.4"
@ -923,6 +1113,28 @@ version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c97e489d8f836838d497091de568cf16b117486d529ec5579233521065bd5e4" checksum = "9c97e489d8f836838d497091de568cf16b117486d529ec5579233521065bd5e4"
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]] [[package]]
name = "zip" name = "zip"
version = "0.6.2" version = "0.6.2"

View File

@ -6,6 +6,7 @@ edition = "2021"
[dependencies] [dependencies]
fltk = "1.3.6" fltk = "1.3.6"
state = "0.5.3"
serde = { version = "1.0.136", features = ["derive"] } serde = { version = "1.0.136", features = ["derive"] }
serde_json = "1.0.79" serde_json = "1.0.79"
zip = "0.6.2" zip = "0.6.2"

BIN
board.zip

Binary file not shown.

View File

@ -9,14 +9,18 @@ extern crate image;
use image::io::Reader as ImageReader; use image::io::Reader as ImageReader;
use image::{ DynamicImage }; use image::{ DynamicImage };
use state::Storage;
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
use std::cell::RefCell; use std::sync::Mutex;
use std::rc::Rc;
use std::io::{ Write, Read, Cursor }; use std::io::{ Write, Read, Cursor };
use std::fs::File; use std::fs::File;
//////////////////// Global State ////////////////////
// Don't @ me...
static STATE: Storage<Mutex<AppState>> = Storage::new();
//////////////////// Data Layout //////////////////// //////////////////// Data Layout ////////////////////
@ -131,14 +135,16 @@ fn node_create_dialog(state: &mut AppState, pos_x: f32, pos_y: f32) {
mod dispatch { mod dispatch {
use super::*; use super::*;
type Coords = (f32, f32); type Coords = (f32, f32);
pub(super) fn node_press(state: &mut AppState, coords: Coords) { pub(super) fn node_press(coords: Coords) {
let (pos_x, pos_y) = coords; let (pos_x, pos_y) = coords;
if app::event_button() == 1 { if app::event_button() == 1 {
let name = dialog::input_default("Node", ""); let name = dialog::input_default("Node", "");
if let Some(name) = name { if let Some(name) = name {
let mut state = STATE.get().lock().unwrap();
state.board.add_node(pos_x, pos_y, name); state.board.add_node(pos_x, pos_y, name);
} }
} else if app::event_button() == 3 { } else if app::event_button() == 3 {
let mut state = STATE.get().lock().unwrap();
let id = state.board.nearest_node(pos_x, pos_y); let id = state.board.nearest_node(pos_x, pos_y);
if let Some(id) = id { if let Some(id) = id {
state.board.remove_node(id); state.board.remove_node(id);
@ -146,8 +152,9 @@ mod dispatch {
} }
app::redraw(); app::redraw();
} }
pub(super) fn edge_press(state: &mut AppState, coords: Coords) { pub(super) fn edge_press(coords: Coords) {
let (pos_x, pos_y) = coords; let (pos_x, pos_y) = coords;
let mut state = STATE.get().lock().unwrap();
if app::event_button() == 1 { if app::event_button() == 1 {
match (state.selected_node, state.board.nearest_node(pos_x, pos_y)) { match (state.selected_node, state.board.nearest_node(pos_x, pos_y)) {
(Some(selected), Some(nearest)) => { (Some(selected), Some(nearest)) => {
@ -218,7 +225,7 @@ impl CoordTransformer for frame::Frame {
} }
//////////////////// App State //////////////////// //////////////////// App State ////////////////////
#[derive(Clone, Copy)]
enum EditMode { enum EditMode {
Node, Node,
Edge, Edge,
@ -245,6 +252,8 @@ impl AppState {
//////////////////// Procedural App Creation //////////////////// //////////////////// Procedural App Creation ////////////////////
fn main() { fn main() {
// State
STATE.set(Mutex::new(AppState::new()));
// App setup // App setup
let app = app::App::default() let app = app::App::default()
.with_scheme(app::Scheme::Gtk); .with_scheme(app::Scheme::Gtk);
@ -255,17 +264,12 @@ fn main() {
.size_of_parent(); .size_of_parent();
flex.set_type(group::FlexType::Column); flex.set_type(group::FlexType::Column);
// State
let state = Rc::new(RefCell::new(AppState::new()));
// Menu // Menu
let mut menubar = menu::MenuBar::default(); let mut menubar = menu::MenuBar::default();
let state_clone = Rc::clone(&state);
menubar.add("File/New", Shortcut::None, menu::MenuFlag::Normal, move |_| { menubar.add("File/New", Shortcut::None, menu::MenuFlag::Normal, move |_| {
state_clone.replace(AppState::new()); *STATE.get().lock().unwrap() = AppState::new();
app::redraw(); app::redraw();
}); });
let state_clone = Rc::clone(&state);
menubar.add("File/Open...", Shortcut::None, menu::MenuFlag::Normal, move |_| { menubar.add("File/Open...", Shortcut::None, menu::MenuFlag::Normal, move |_| {
let mut fc = dialog::NativeFileChooser::new(dialog::NativeFileChooserType::BrowseFile); let mut fc = dialog::NativeFileChooser::new(dialog::NativeFileChooserType::BrowseFile);
fc.show(); fc.show();
@ -285,9 +289,8 @@ fn main() {
state.image_raw = Some(image); state.image_raw = Some(image);
app::redraw(); app::redraw();
} }
state_clone.replace(state); *STATE.get().lock().unwrap() = state;
}); });
let state_clone = Rc::clone(&state);
menubar.add("File/Open Image...", Shortcut::None, menu::MenuFlag::Normal, move |_| { menubar.add("File/Open Image...", Shortcut::None, menu::MenuFlag::Normal, move |_| {
let mut fc = dialog::NativeFileChooser::new(dialog::NativeFileChooserType::BrowseFile); let mut fc = dialog::NativeFileChooser::new(dialog::NativeFileChooserType::BrowseFile);
fc.show(); fc.show();
@ -295,7 +298,7 @@ fn main() {
match ImageReader::open(filename).map(|i| i.decode()) { match ImageReader::open(filename).map(|i| i.decode()) {
Ok(Ok(image)) => { Ok(Ok(image)) => {
let mut state = state_clone.borrow_mut(); let mut state = STATE.get().lock().unwrap();
let data = encode_png(&image); let data = encode_png(&image);
state.image = Some(PngImage::from_data(&data).unwrap()); state.image = Some(PngImage::from_data(&data).unwrap());
state.image_raw = Some(image); state.image_raw = Some(image);
@ -304,7 +307,6 @@ fn main() {
_ => dialog::alert_default("Error opening file"), _ => dialog::alert_default("Error opening file"),
} }
}); });
let state_clone = Rc::clone(&state);
menubar.add("File/Save As ...", Shortcut::None, menu::MenuFlag::Normal, move |_| { menubar.add("File/Save As ...", Shortcut::None, menu::MenuFlag::Normal, move |_| {
let mut fc = dialog::NativeFileChooser::new(dialog::NativeFileChooserType::BrowseSaveFile); let mut fc = dialog::NativeFileChooser::new(dialog::NativeFileChooserType::BrowseSaveFile);
fc.show(); fc.show();
@ -312,7 +314,7 @@ fn main() {
let file = File::create(fc.filename()).unwrap(); let file = File::create(fc.filename()).unwrap();
let mut ar = zip::ZipWriter::new(file); let mut ar = zip::ZipWriter::new(file);
let options = zip::write::FileOptions::default(); let options = zip::write::FileOptions::default();
let state = state_clone.borrow(); let mut state = STATE.get().lock().unwrap();
ar.start_file("graph.json", options).ok(); ar.start_file("graph.json", options).ok();
ar.write(&serde_json::to_vec(&state.board).unwrap()).ok(); ar.write(&serde_json::to_vec(&state.board).unwrap()).ok();
@ -324,14 +326,12 @@ fn main() {
} }
ar.finish().ok(); ar.finish().ok();
}); });
let state_clone = Rc::clone(&state);
menubar.add("Edit/Edit Nodes", Shortcut::None, menu::MenuFlag::Normal, move |_| { menubar.add("Edit/Edit Nodes", Shortcut::None, menu::MenuFlag::Normal, move |_| {
let mut state = state_clone.borrow_mut(); let mut state = STATE.get().lock().unwrap();
state.edit_mode = EditMode::Node; state.edit_mode = EditMode::Node;
}); });
let state_clone = Rc::clone(&state);
menubar.add("Edit/Edit Edges", Shortcut::None, menu::MenuFlag::Normal, move |_| { menubar.add("Edit/Edit Edges", Shortcut::None, menu::MenuFlag::Normal, move |_| {
let mut state = state_clone.borrow_mut(); let mut state = STATE.get().lock().unwrap();
state.edit_mode = EditMode::Edge; state.edit_mode = EditMode::Edge;
}); });
@ -339,10 +339,9 @@ fn main() {
// Canvas // Canvas
let mut frame = frame::Frame::default(); let mut frame = frame::Frame::default();
let state_clone = Rc::clone(&state);
frame.draw(move |f| { frame.draw(move |f| {
use draw::*; use draw::*;
let mut state = state_clone.borrow_mut(); let mut state = STATE.get().lock().unwrap();
// Background // Background
let image = &mut state.image; let image = &mut state.image;
if let Some(image) = image.as_mut() { if let Some(image) = image.as_mut() {
@ -369,16 +368,15 @@ fn main() {
} }
} }
}); });
let state_clone = Rc::clone(&state);
frame.handle(move |f, e| { frame.handle(move |f, e| {
match e { match e {
Event::Push => { Event::Push => {
let mut state = state_clone.borrow_mut(); let edit_mode = STATE.get().lock().unwrap().edit_mode;
let coords = f.to_coords(app::event_x(), app::event_y()); let coords = f.to_coords(app::event_x(), app::event_y());
match state.edit_mode { match edit_mode {
EditMode::Node => dispatch::node_press(&mut state, coords), EditMode::Node => dispatch::node_press(coords),
EditMode::Edge => dispatch::edge_press(&mut state, coords), EditMode::Edge => dispatch::edge_press(coords),
} }
true true
} }