Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Support for Custom Storage Backends in eframe via a New NativeOptions Field #5689

Open
UnknownSuperficialNight opened this issue Feb 6, 2025 · 1 comment

Comments

@UnknownSuperficialNight
Copy link

Problem: Currently, eframe only supports saving app state using RON files. This limitation restricts developers who wish to integrate with different storage systems like SQLite or handle deserialization themselves for alternative data formats.

Solution: Introduce a customization option that allows users to provide a custom storage mechanism. This could be achieved by accepting a closure or function during initialization, enabling dynamic storage creation (e.g., SQLite, PostgreSQL).

fn init_run_state(
&mut self,
event_loop: &ActiveEventLoop,
) -> Result<&mut GlowWinitRunning<'app>> {
profiling::function_scope!();
let storage = if let Some(file) = &self.native_options.persistence_path {
epi_integration::create_storage_with_file(file)
} else {
epi_integration::create_storage(
self.native_options
.viewport
.app_id
.as_ref()
.unwrap_or(&self.app_name),
)
};

/// For loading/saving app state and/or egui memory to disk.
pub fn create_storage(_app_name: &str) -> Option<Box<dyn epi::Storage>> {
#[cfg(feature = "persistence")]
if let Some(storage) = super::file_storage::FileStorage::from_app_id(_app_name) {
return Some(Box::new(storage));
}
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
}

Proposed Implementation: Modify eframe to accept a Box<dyn Fn() -> Box<dyn crate::epi::Storage>> as an optional parameter in the initialization process. This closure would allow developers to return their own custom storage implementation instead of the default FileStorage.

Examples:

pub struct NativeOptions {
    // ... other fields ...
    pub persistence_path: Option<PathBuf>,
    /// Override the default storage creation with your own custom storage implementation
    pub storage_creator: Option<Box<dyn Fn() -> Option<Box<dyn crate::epi::Storage>>>>,
}
fn init_run_state(
    &mut self,
    event_loop: &ActiveEventLoop,
) -> Result<&mut GlowWinitRunning<'app>> {
    profiling::function_scope!();

    let storage = if let Some(storage_creator) = &self.native_options.storage_creator {
        storage_creator()
    } else if let Some(file) = &self.native_options.persistence_path {
        epi_integration::create_storage_with_file(file)
    } else {
        epi_integration::create_storage(
            self.native_options
                .viewport
                .app_id
                .as_ref()
                .unwrap_or(&self.app_name),
        )
    };

    // ... rest of function
}
@UnknownSuperficialNight UnknownSuperficialNight changed the title Support for Custom Storage Backends and Flexible Deserialization in eframe Add Support for Custom Storage Backends in eframe via a New NativeOptions Field Feb 6, 2025
@Evrey
Copy link

Evrey commented Feb 15, 2025

Same problem. Currently i’m just ignoring the provided Storage ref when saving state, pointing at my own, but i’d like to not have that RON file exist in the first place and install my own Storage properly. I have an SQLite-based settings DB and have in it a table for all the eframe stuff.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants