Skip to content

Commit 5f45cf9

Browse files
lucasmerlinhacknus
authored andcommitted
eframe: Add NativeOptions::persistence_path (emilk#4423)
This allows customizing the persistence path in NativeOptions. Previously, persistence wouldn't work with android because directories-next doesn't support android so eframe would just fail to find a place where it could store its config. * Closes emilk#4098 (android users can now specify a path that works with android, by e.g. using app_dirs2, which supports android)
1 parent 94e8e51 commit 5f45cf9

File tree

5 files changed

+44
-15
lines changed

5 files changed

+44
-15
lines changed

crates/eframe/src/epi.rs

+9
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ pub trait App {
150150
/// On web the state is stored to "Local Storage".
151151
///
152152
/// On native the path is picked using [`crate::storage_dir`].
153+
/// The path can be customized via [`NativeOptions::persistence_path`].
153154
fn save(&mut self, _storage: &mut dyn Storage) {}
154155

155156
/// Called once on shutdown, after [`Self::save`].
@@ -362,6 +363,10 @@ pub struct NativeOptions {
362363
/// Controls whether or not the native window position and size will be
363364
/// persisted (only if the "persistence" feature is enabled).
364365
pub persist_window: bool,
366+
367+
/// The folder where `eframe` will store the app state. If not set, eframe will get the paths
368+
/// from [directories_next].
369+
pub persistence_path: Option<std::path::PathBuf>,
365370
}
366371

367372
#[cfg(not(target_arch = "wasm32"))]
@@ -379,6 +384,8 @@ impl Clone for NativeOptions {
379384
#[cfg(feature = "wgpu")]
380385
wgpu_options: self.wgpu_options.clone(),
381386

387+
persistence_path: self.persistence_path.clone(),
388+
382389
..*self
383390
}
384391
}
@@ -418,6 +425,8 @@ impl Default for NativeOptions {
418425
wgpu_options: egui_wgpu::WgpuConfiguration::default(),
419426

420427
persist_window: true,
428+
429+
persistence_path: None,
421430
}
422431
}
423432
}

crates/eframe/src/native/epi_integration.rs

+12
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
//! Common tools used by [`super::glow_integration`] and [`super::wgpu_integration`].
22
33
use web_time::Instant;
4+
5+
use std::path::PathBuf;
46
use winit::event_loop::EventLoopWindowTarget;
57

68
use raw_window_handle::{HasDisplayHandle as _, HasWindowHandle as _};
@@ -132,6 +134,16 @@ pub fn create_storage(_app_name: &str) -> Option<Box<dyn epi::Storage>> {
132134
None
133135
}
134136

137+
#[allow(clippy::unnecessary_wraps)]
138+
pub fn create_storage_with_file(_file: impl Into<PathBuf>) -> Option<Box<dyn epi::Storage>> {
139+
#[cfg(feature = "persistence")]
140+
return Some(Box::new(
141+
super::file_storage::FileStorage::from_ron_filepath(_file),
142+
));
143+
#[cfg(not(feature = "persistence"))]
144+
None
145+
}
146+
135147
// ----------------------------------------------------------------------------
136148

137149
/// Everything needed to make a winit-based integration for [`epi`].

crates/eframe/src/native/file_storage.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ impl Drop for FileStorage {
4141

4242
impl FileStorage {
4343
/// Store the state in this .ron file.
44-
fn from_ron_filepath(ron_filepath: impl Into<PathBuf>) -> Self {
44+
pub(crate) fn from_ron_filepath(ron_filepath: impl Into<PathBuf>) -> Self {
4545
crate::profile_function!();
4646
let ron_filepath: PathBuf = ron_filepath.into();
4747
log::debug!("Loading app state from {:?}…", ron_filepath);

crates/eframe/src/native/glow_integration.rs

+11-7
Original file line numberDiff line numberDiff line change
@@ -195,13 +195,17 @@ impl GlowWinitApp {
195195
) -> Result<&mut GlowWinitRunning> {
196196
crate::profile_function!();
197197

198-
let storage = epi_integration::create_storage(
199-
self.native_options
200-
.viewport
201-
.app_id
202-
.as_ref()
203-
.unwrap_or(&self.app_name),
204-
);
198+
let storage = if let Some(file) = &self.native_options.persistence_path {
199+
epi_integration::create_storage_with_file(file)
200+
} else {
201+
epi_integration::create_storage(
202+
self.native_options
203+
.viewport
204+
.app_id
205+
.as_ref()
206+
.unwrap_or(&self.app_name),
207+
)
208+
};
205209

206210
let egui_ctx = create_egui_context(storage.as_deref());
207211

crates/eframe/src/native/wgpu_integration.rs

+11-7
Original file line numberDiff line numberDiff line change
@@ -406,13 +406,17 @@ impl WinitApp for WgpuWinitApp {
406406
self.recreate_window(event_loop, running);
407407
running
408408
} else {
409-
let storage = epi_integration::create_storage(
410-
self.native_options
411-
.viewport
412-
.app_id
413-
.as_ref()
414-
.unwrap_or(&self.app_name),
415-
);
409+
let storage = if let Some(file) = &self.native_options.persistence_path {
410+
epi_integration::create_storage_with_file(file)
411+
} else {
412+
epi_integration::create_storage(
413+
self.native_options
414+
.viewport
415+
.app_id
416+
.as_ref()
417+
.unwrap_or(&self.app_name),
418+
)
419+
};
416420
let egui_ctx = winit_integration::create_egui_context(storage.as_deref());
417421
let (window, builder) = create_window(
418422
&egui_ctx,

0 commit comments

Comments
 (0)