eframe: Add `NativeOptions::persistence_path` (#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 #4098 (android users can now specify a path that works with android, by e.g. using app_dirs2, which supports android)
This commit is contained in:
parent
192a111272
commit
8553e738e0
|
|
@ -150,6 +150,7 @@ pub trait App {
|
||||||
/// On web the state is stored to "Local Storage".
|
/// On web the state is stored to "Local Storage".
|
||||||
///
|
///
|
||||||
/// On native the path is picked using [`crate::storage_dir`].
|
/// On native the path is picked using [`crate::storage_dir`].
|
||||||
|
/// The path can be customized via [`NativeOptions::persistence_path`].
|
||||||
fn save(&mut self, _storage: &mut dyn Storage) {}
|
fn save(&mut self, _storage: &mut dyn Storage) {}
|
||||||
|
|
||||||
/// Called once on shutdown, after [`Self::save`].
|
/// Called once on shutdown, after [`Self::save`].
|
||||||
|
|
@ -362,6 +363,10 @@ pub struct NativeOptions {
|
||||||
/// Controls whether or not the native window position and size will be
|
/// Controls whether or not the native window position and size will be
|
||||||
/// persisted (only if the "persistence" feature is enabled).
|
/// persisted (only if the "persistence" feature is enabled).
|
||||||
pub persist_window: bool,
|
pub persist_window: bool,
|
||||||
|
|
||||||
|
/// The folder where `eframe` will store the app state. If not set, eframe will get the paths
|
||||||
|
/// from [directories_next].
|
||||||
|
pub persistence_path: Option<std::path::PathBuf>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
|
|
@ -379,6 +384,8 @@ impl Clone for NativeOptions {
|
||||||
#[cfg(feature = "wgpu")]
|
#[cfg(feature = "wgpu")]
|
||||||
wgpu_options: self.wgpu_options.clone(),
|
wgpu_options: self.wgpu_options.clone(),
|
||||||
|
|
||||||
|
persistence_path: self.persistence_path.clone(),
|
||||||
|
|
||||||
..*self
|
..*self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -418,6 +425,8 @@ impl Default for NativeOptions {
|
||||||
wgpu_options: egui_wgpu::WgpuConfiguration::default(),
|
wgpu_options: egui_wgpu::WgpuConfiguration::default(),
|
||||||
|
|
||||||
persist_window: true,
|
persist_window: true,
|
||||||
|
|
||||||
|
persistence_path: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
//! Common tools used by [`super::glow_integration`] and [`super::wgpu_integration`].
|
//! Common tools used by [`super::glow_integration`] and [`super::wgpu_integration`].
|
||||||
|
|
||||||
use web_time::Instant;
|
use web_time::Instant;
|
||||||
|
|
||||||
|
use std::path::PathBuf;
|
||||||
use winit::event_loop::EventLoopWindowTarget;
|
use winit::event_loop::EventLoopWindowTarget;
|
||||||
|
|
||||||
use raw_window_handle::{HasDisplayHandle as _, HasWindowHandle as _};
|
use raw_window_handle::{HasDisplayHandle as _, HasWindowHandle as _};
|
||||||
|
|
@ -132,6 +134,16 @@ pub fn create_storage(_app_name: &str) -> Option<Box<dyn epi::Storage>> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::unnecessary_wraps)]
|
||||||
|
pub fn create_storage_with_file(_file: impl Into<PathBuf>) -> Option<Box<dyn epi::Storage>> {
|
||||||
|
#[cfg(feature = "persistence")]
|
||||||
|
return Some(Box::new(
|
||||||
|
super::file_storage::FileStorage::from_ron_filepath(_file),
|
||||||
|
));
|
||||||
|
#[cfg(not(feature = "persistence"))]
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
/// Everything needed to make a winit-based integration for [`epi`].
|
/// Everything needed to make a winit-based integration for [`epi`].
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ impl Drop for FileStorage {
|
||||||
|
|
||||||
impl FileStorage {
|
impl FileStorage {
|
||||||
/// Store the state in this .ron file.
|
/// Store the state in this .ron file.
|
||||||
fn from_ron_filepath(ron_filepath: impl Into<PathBuf>) -> Self {
|
pub(crate) fn from_ron_filepath(ron_filepath: impl Into<PathBuf>) -> Self {
|
||||||
crate::profile_function!();
|
crate::profile_function!();
|
||||||
let ron_filepath: PathBuf = ron_filepath.into();
|
let ron_filepath: PathBuf = ron_filepath.into();
|
||||||
log::debug!("Loading app state from {:?}…", ron_filepath);
|
log::debug!("Loading app state from {:?}…", ron_filepath);
|
||||||
|
|
|
||||||
|
|
@ -195,13 +195,17 @@ impl GlowWinitApp {
|
||||||
) -> Result<&mut GlowWinitRunning> {
|
) -> Result<&mut GlowWinitRunning> {
|
||||||
crate::profile_function!();
|
crate::profile_function!();
|
||||||
|
|
||||||
let storage = epi_integration::create_storage(
|
let storage = if let Some(file) = &self.native_options.persistence_path {
|
||||||
self.native_options
|
epi_integration::create_storage_with_file(file)
|
||||||
.viewport
|
} else {
|
||||||
.app_id
|
epi_integration::create_storage(
|
||||||
.as_ref()
|
self.native_options
|
||||||
.unwrap_or(&self.app_name),
|
.viewport
|
||||||
);
|
.app_id
|
||||||
|
.as_ref()
|
||||||
|
.unwrap_or(&self.app_name),
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
let egui_ctx = create_egui_context(storage.as_deref());
|
let egui_ctx = create_egui_context(storage.as_deref());
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -406,13 +406,17 @@ impl WinitApp for WgpuWinitApp {
|
||||||
self.recreate_window(event_loop, running);
|
self.recreate_window(event_loop, running);
|
||||||
running
|
running
|
||||||
} else {
|
} else {
|
||||||
let storage = epi_integration::create_storage(
|
let storage = if let Some(file) = &self.native_options.persistence_path {
|
||||||
self.native_options
|
epi_integration::create_storage_with_file(file)
|
||||||
.viewport
|
} else {
|
||||||
.app_id
|
epi_integration::create_storage(
|
||||||
.as_ref()
|
self.native_options
|
||||||
.unwrap_or(&self.app_name),
|
.viewport
|
||||||
);
|
.app_id
|
||||||
|
.as_ref()
|
||||||
|
.unwrap_or(&self.app_name),
|
||||||
|
)
|
||||||
|
};
|
||||||
let egui_ctx = winit_integration::create_egui_context(storage.as_deref());
|
let egui_ctx = winit_integration::create_egui_context(storage.as_deref());
|
||||||
let (window, builder) = create_window(
|
let (window, builder) = create_window(
|
||||||
&egui_ctx,
|
&egui_ctx,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue