Skip to content

Commit

Permalink
desktop: Document preferences a little
Browse files Browse the repository at this point in the history
  • Loading branch information
Dinnerbone committed Mar 4, 2024
1 parent c713f56 commit 571f60a
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 11 deletions.
35 changes: 32 additions & 3 deletions desktop/src/preferences.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,26 @@ use sys_locale::get_locale;
use toml_edit::Document;
use unic_langid::LanguageIdentifier;

/// The preferences that relate to the application itself.
///
/// This structure is safe to clone, internally it holds an Arc to any mutable properties.
///
/// The general priority order for preferences should look as follows, where top is "highest priority":
/// - User-selected movie-specific setting (if applicable, such as through Open Advanced)
/// - Movie-specific settings (if applicable and we implement this, stored on disk)
/// - CLI (if applicable)
/// - Persisted preferences (if applicable, saved to toml)
/// - Ruffle defaults
#[derive(Clone)]
pub struct GlobalPreferences {
/// As the CLI holds properties ranging from initial movie settings (ie url),
/// to application itself (ie render backend),
/// this field is available for checking where needed.
// TODO: This should really not be public and we should split up CLI somehow,
// or make it all getters in here?
pub cli: Opt,

/// The actual, mutable user preferences that are persisted to disk.
preferences: Arc<Mutex<PreferencesAndDocument>>,
}

Expand All @@ -31,7 +48,7 @@ impl GlobalPreferences {
tracing::warn!("{warning}");
}
PreferencesAndDocument {
document,
toml_document: document,
values: result.result,
}
} else {
Expand Down Expand Up @@ -91,15 +108,27 @@ impl GlobalPreferences {
let mut writer = PreferencesWriter::new(&mut preferences);
fun(&mut writer);

let serialized = preferences.document.to_string();
let serialized = preferences.toml_document.to_string();
std::fs::write(self.cli.config.join("preferences.toml"), serialized)
.context("Could not write preferences to disk")
}
}

/// The actual preferences that are persisted to disk, and mutable at runtime.
/// Care should be taken to only modify what's actually changed, using `GlobalPreferences::write_preferences`.
///
/// Two versions of Ruffle may have different preferences, or different values available for each preference.
/// For this reason, we store both the original toml document *and* the parsed values as we understand them.
/// Whenever we persist values back to the toml, we only edit the values we changed and leave the remaining
/// values as they originally were.
/// This way, switching between different versions will *not* wipe your settings or get Ruffle into an
/// invalid state.
#[derive(Default)]
struct PreferencesAndDocument {
document: Document,
/// The original toml document
toml_document: Document,

/// The actual preferences stored within the toml document, as this version of Ruffle understands them.
values: SavedGlobalPreferences,
}

Expand Down
16 changes: 8 additions & 8 deletions desktop/src/preferences/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,25 +11,25 @@ impl<'a> PreferencesWriter<'a> {
}

pub fn set_graphics_backend(&mut self, backend: GraphicsBackend) {
self.0.document["graphics_backend"] = value(backend.as_str());
self.0.toml_document["graphics_backend"] = value(backend.as_str());
self.0.values.graphics_backend = backend;
}

pub fn set_graphics_power_preference(&mut self, preference: PowerPreference) {
self.0.document["graphics_power_preference"] = value(preference.as_str());
self.0.toml_document["graphics_power_preference"] = value(preference.as_str());
self.0.values.graphics_power_preference = preference;
}

pub fn set_language(&mut self, language: LanguageIdentifier) {
self.0.document["language"] = value(language.to_string());
self.0.toml_document["language"] = value(language.to_string());
self.0.values.language = language;
}

pub fn set_output_device(&mut self, name: Option<String>) {
if let Some(name) = &name {
self.0.document["output_device"] = value(name);
self.0.toml_document["output_device"] = value(name);
} else {
self.0.document.remove("output_device");
self.0.toml_document.remove("output_device");
}
self.0.values.output_device = name;
}
Expand All @@ -44,13 +44,13 @@ mod tests {
fn parse(input: &str) -> PreferencesAndDocument {
let (result, document) = read_preferences(input);
PreferencesAndDocument {
document,
toml_document: document,
values: result.result,
}
}

fn check_roundtrip(preferences: &mut PreferencesAndDocument) {
let read_result = read_preferences(&preferences.document.to_string());
let read_result = read_preferences(&preferences.toml_document.to_string());
assert_eq!(
preferences.values, read_result.0.result,
"roundtrip failed: expected != actual"
Expand All @@ -62,7 +62,7 @@ mod tests {
let mut writer = PreferencesWriter::new(&mut preferences);
fun(&mut writer);
check_roundtrip(&mut preferences);
assert_eq!(expected, preferences.document.to_string());
assert_eq!(expected, preferences.toml_document.to_string());
}

#[test]
Expand Down

0 comments on commit 571f60a

Please sign in to comment.