[egui_glium] Add option not to persist app to file

This commit is contained in:
Emil Ernerfeldt 2020-10-19 20:25:05 +02:00
parent 43813a71eb
commit 8ccc36937f
5 changed files with 40 additions and 25 deletions

View file

@ -1,11 +1,15 @@
#![deny(warnings)] #![deny(warnings)]
#![warn(clippy::all)] #![warn(clippy::all)]
use egui_glium::storage::FileStorage;
fn main() { fn main() {
let title = "Egui glium demo"; let title = "Egui glium demo";
let storage = FileStorage::from_path(".egui_demo_glium.json".into());
// Persist app state to file:
let storage = egui_glium::storage::FileStorage::from_path(".egui_demo_glium.json".into());
// Alternative: store nowhere
// let storage = egui::app::DummyStorage::default();
let app: egui::DemoApp = egui::app::get_value(&storage, egui::app::APP_KEY).unwrap_or_default(); let app: egui::DemoApp = egui::app::get_value(&storage, egui::app::APP_KEY).unwrap_or_default();
egui_glium::run(title, storage, app); egui_glium::run(title, Box::new(storage), app);
} }

View file

@ -75,6 +75,9 @@ pub trait TextureAllocator {
pub trait Storage { pub trait Storage {
fn get_string(&self, key: &str) -> Option<&str>; fn get_string(&self, key: &str) -> Option<&str>;
fn set_string(&mut self, key: &str, value: String); fn set_string(&mut self, key: &str, value: String);
/// write-to-disk or similar
fn flush(&mut self);
} }
/// Stores nothing. /// Stores nothing.
@ -86,6 +89,7 @@ impl Storage for DummyStorage {
None None
} }
fn set_string(&mut self, _key: &str, _value: String) {} fn set_string(&mut self, _key: &str, _value: String) {}
fn flush(&mut self) {}
} }
#[cfg(feature = "serde_json")] #[cfg(feature = "serde_json")]

View file

@ -1,9 +1,6 @@
use std::time::Instant; use std::time::Instant;
use crate::{ use crate::{storage::WindowSettings, *};
storage::{FileStorage, WindowSettings},
*,
};
pub use egui::{ pub use egui::{
app::{self, App, Storage}, app::{self, App, Storage},
@ -24,7 +21,11 @@ impl egui::app::TextureAllocator for Painter {
} }
/// Run an egui app /// Run an egui app
pub fn run(title: &str, mut storage: FileStorage, mut app: impl App + 'static) -> ! { pub fn run(
title: &str,
mut storage: Box<dyn egui::app::Storage>,
mut app: impl App + 'static,
) -> ! {
let event_loop = glutin::event_loop::EventLoop::new(); let event_loop = glutin::event_loop::EventLoop::new();
let mut window = glutin::window::WindowBuilder::new() let mut window = glutin::window::WindowBuilder::new()
.with_decorations(true) .with_decorations(true)
@ -32,7 +33,8 @@ pub fn run(title: &str, mut storage: FileStorage, mut app: impl App + 'static) -
.with_title(title) .with_title(title)
.with_transparent(false); .with_transparent(false);
let window_settings: Option<WindowSettings> = egui::app::get_value(&storage, WINDOW_KEY); let window_settings: Option<WindowSettings> =
egui::app::get_value(storage.as_ref(), WINDOW_KEY);
if let Some(window_settings) = &window_settings { if let Some(window_settings) = &window_settings {
window = window_settings.initialize_size(window); window = window_settings.initialize_size(window);
} }
@ -49,7 +51,7 @@ pub fn run(title: &str, mut storage: FileStorage, mut app: impl App + 'static) -
} }
let mut ctx = egui::Context::new(); let mut ctx = egui::Context::new();
*ctx.memory() = egui::app::get_value(&storage, EGUI_MEMORY_KEY).unwrap_or_default(); *ctx.memory() = egui::app::get_value(storage.as_ref(), EGUI_MEMORY_KEY).unwrap_or_default();
let mut raw_input = egui::RawInput { let mut raw_input = egui::RawInput {
pixels_per_point: Some(native_pixels_per_point(&display)), pixels_per_point: Some(native_pixels_per_point(&display)),
@ -119,13 +121,13 @@ pub fn run(title: &str, mut storage: FileStorage, mut app: impl App + 'static) -
} }
glutin::event::Event::LoopDestroyed => { glutin::event::Event::LoopDestroyed => {
egui::app::set_value( egui::app::set_value(
&mut storage, storage.as_mut(),
WINDOW_KEY, WINDOW_KEY,
&WindowSettings::from_display(&display), &WindowSettings::from_display(&display),
); );
egui::app::set_value(&mut storage, EGUI_MEMORY_KEY, &*ctx.memory()); egui::app::set_value(storage.as_mut(), EGUI_MEMORY_KEY, &*ctx.memory());
app.on_exit(&mut storage); app.on_exit(storage.as_mut());
storage.save(); storage.flush();
} }
_ => (), _ => (),
} }

View file

@ -18,13 +18,6 @@ impl FileStorage {
dirty: false, dirty: false,
} }
} }
pub fn save(&mut self) {
if self.dirty {
serde_json::to_writer(std::fs::File::create(&self.path).unwrap(), &self.kv).unwrap();
self.dirty = false;
}
}
} }
impl egui::app::Storage for FileStorage { impl egui::app::Storage for FileStorage {
@ -38,6 +31,13 @@ impl egui::app::Storage for FileStorage {
self.dirty = true; self.dirty = true;
} }
} }
fn flush(&mut self) {
if self.dirty {
serde_json::to_writer(std::fs::File::create(&self.path).unwrap(), &self.kv).unwrap();
self.dirty = false;
}
}
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

View file

@ -4,7 +4,6 @@
#![warn(clippy::all)] #![warn(clippy::all)]
use egui::{Slider, Window}; use egui::{Slider, Window};
use egui_glium::storage::FileStorage;
/// We derive Deserialize/Serialize so we can persist app state on shutdown. /// We derive Deserialize/Serialize so we can persist app state on shutdown.
#[derive(Default, serde::Deserialize, serde::Serialize)] #[derive(Default, serde::Deserialize, serde::Serialize)]
@ -44,9 +43,15 @@ impl egui::app::App for MyApp {
fn main() { fn main() {
let title = "My Egui Window"; let title = "My Egui Window";
let storage = FileStorage::from_path(".egui_example_glium.json".into()); // Where to persist app state
// Persist app state to file:
let storage = egui_glium::storage::FileStorage::from_path(".egui_example_glium.json".into());
// Alternative: store nowhere
// let storage = egui::app::DummyStorage::default();
let app: MyApp = egui::app::get_value(&storage, egui::app::APP_KEY).unwrap_or_default(); // Restore `MyApp` from file, or create new `MyApp`. let app: MyApp = egui::app::get_value(&storage, egui::app::APP_KEY).unwrap_or_default(); // Restore `MyApp` from file, or create new `MyApp`.
egui_glium::run(title, storage, app); egui_glium::run(title, Box::new(storage), app);
} }
fn my_save_function() { fn my_save_function() {