Files
Oxide/docs/settings.md
T
Homer Simpson 9eead719b0 Import Oxide engine (Stages 0–10) under MIT license
Full project snapshot migrated to new Gitea remote without history:
engine, editor, physics, script, examples, tests, docs, and assets.
Relicensed from GPLv3 to MIT and updated repo URLs.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 20:41:02 +02:00

71 lines
2.8 KiB
Markdown

# Settings & Preferences Framework
`oxide_engine::settings` is the engine's unified, serialized configuration store.
The engine, the editor, and every module register typed **sections**; the
framework persists them all to RON and restores them — without any central code
knowing the sections' shapes. It is the backbone of the editor's Preferences
window and of per-module settings.
## Sections
A section is any plain `serde`-serializable struct with a `Default`. Register it
once under a name and the store owns a typed instance:
```rust
use oxide_engine::settings::Settings;
use serde::{Serialize, Deserialize};
#[derive(Serialize, Deserialize, Default)]
struct EditorPrefs { theme: String, grid: bool }
let mut settings = Settings::new();
settings.register::<EditorPrefs>("editor");
// Typed read/write.
settings.get_mut::<EditorPrefs>("editor").unwrap().theme = "dark".into();
assert_eq!(settings.get::<EditorPrefs>("editor").unwrap().theme, "dark");
```
`set` replaces a section's value (only if the registered type matches), and
`reset` returns it to `Default`. Accessing a section as the wrong type returns
`None` rather than panicking.
## Persisting
Every section serializes to a `name → RON` map via `export`, and `import` loads
matching sections back. This map is exactly the shape a
[`Project`](projects.md) stores, so per-project settings round-trip through the
project file:
```rust
# use oxide_engine::settings::Settings;
# use serde::{Serialize, Deserialize};
# #[derive(Serialize, Deserialize, Default)] struct EditorPrefs { theme: String }
# let mut settings = Settings::new();
# settings.register::<EditorPrefs>("editor");
let saved = settings.export(); // BTreeMap<String, String>
let mut restored = Settings::new();
restored.register::<EditorPrefs>("editor");
restored.import(&saved); // matching sections restored
```
`import` is deliberately lenient: an **unknown** section (e.g. one owned by a
disabled module) is ignored, and a **malformed** section is skipped, leaving its
current value. This means a project saved with a module enabled still opens
cleanly with that module disabled, and vice-versa.
## How the layers fit together
| Scope | Lives where | Persisted to |
|-------|-------------|--------------|
| Engine preferences (render/quality defaults) | a `Settings` section | global prefs file / project |
| Editor preferences (theme, layout, shortcuts) | a `Settings` section | global editor prefs file |
| Per-module settings | each module registers a section | the [project](projects.md) it's enabled in |
`Project` stores the per-project subset (`set_settings_section` /
`settings_section` hold the same RON blobs `export`/`import` produce). The editor
keeps its global preferences in a separate file using the same `Settings` API.
[`Settings`]: ../engine/src/settings.rs