mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Merge branch 'imbris/voxygen-settings-improvements' into 'master'
Cleanup things in voxygen settings, making the directory externally specified, removing unused and planned to be removed things Closes #853 See merge request veloren/veloren!2645
This commit is contained in:
commit
b8b27cb5f7
@ -3436,12 +3436,16 @@ impl Hud {
|
||||
.clamped(1.25, max_zoom / 64.0);
|
||||
|
||||
global_state.settings.interface.map_zoom = new_zoom_lvl;
|
||||
global_state.settings.save_to_file_warn();
|
||||
global_state
|
||||
.settings
|
||||
.save_to_file_warn(&global_state.config_dir);
|
||||
} else if global_state.settings.interface.minimap_show {
|
||||
let new_zoom_lvl = global_state.settings.interface.minimap_zoom * factor;
|
||||
|
||||
global_state.settings.interface.minimap_zoom = new_zoom_lvl;
|
||||
global_state.settings.save_to_file_warn();
|
||||
global_state
|
||||
.settings
|
||||
.save_to_file_warn(&global_state.config_dir);
|
||||
}
|
||||
|
||||
show.map && global_state.settings.interface.minimap_show
|
||||
|
@ -50,9 +50,12 @@ use crate::{
|
||||
use common::clock::Clock;
|
||||
use common_base::span;
|
||||
use i18n::LocalizationHandle;
|
||||
use std::path::PathBuf;
|
||||
|
||||
/// A type used to store state that is shared between all play states.
|
||||
pub struct GlobalState {
|
||||
pub userdata_dir: PathBuf,
|
||||
pub config_dir: PathBuf,
|
||||
pub settings: Settings,
|
||||
pub profile: Profile,
|
||||
pub window: Window,
|
||||
|
@ -17,33 +17,54 @@ use veloren_voxygen::{
|
||||
#[cfg(feature = "hot-reloading")]
|
||||
use common::assets;
|
||||
use common::clock::Clock;
|
||||
use std::panic;
|
||||
use std::{panic, path::PathBuf};
|
||||
use tracing::{error, info, warn};
|
||||
#[cfg(feature = "egui-ui")]
|
||||
use veloren_voxygen::ui::egui::EguiState;
|
||||
|
||||
#[allow(clippy::manual_unwrap_or)]
|
||||
fn main() {
|
||||
let userdata_dir = common_base::userdata_dir_workspace!();
|
||||
|
||||
// Determine where Voxygen's logs should go
|
||||
// Choose a path to store the logs by the following order:
|
||||
// - The VOXYGEN_LOGS environment variable
|
||||
// - The <userdata>/voxygen/logs
|
||||
let logs_dir = std::env::var_os("VOXYGEN_LOGS")
|
||||
.map(PathBuf::from)
|
||||
.unwrap_or_else(|| userdata_dir.join("voxygen").join("logs"));
|
||||
|
||||
// Init logging and hold the guards.
|
||||
const LOG_FILENAME: &str = "voxygen.log";
|
||||
let _guards = common_frontend::init_stdout(Some((&logs_dir, LOG_FILENAME)));
|
||||
|
||||
info!("Using userdata dir at: {}", userdata_dir.display());
|
||||
|
||||
// Determine Voxygen's config directory either by env var or placed in veloren's
|
||||
// userdata folder
|
||||
let config_dir = std::env::var_os("VOXYGEN_CONFIG")
|
||||
.map(PathBuf::from)
|
||||
.and_then(|path| {
|
||||
if path.exists() {
|
||||
Some(path)
|
||||
} else {
|
||||
warn!(?path, "VOXYGEN_CONFIG points to invalid path.");
|
||||
None
|
||||
}
|
||||
})
|
||||
.unwrap_or_else(|| userdata_dir.join("voxygen"));
|
||||
info!("Using config dir at: {}", config_dir.display());
|
||||
|
||||
// Load the settings
|
||||
// Note: This won't log anything due to it being called before
|
||||
// `logging::init`. The issue is we need to read a setting to decide
|
||||
// whether we create a log file or not.
|
||||
let mut settings = Settings::load();
|
||||
let mut settings = Settings::load(&config_dir);
|
||||
// Save settings to add new fields or create the file if it is not already there
|
||||
if let Err(err) = settings.save_to_file() {
|
||||
if let Err(err) = settings.save_to_file(&config_dir) {
|
||||
panic!("Failed to save settings: {:?}", err);
|
||||
}
|
||||
|
||||
// Init logging and hold the guards.
|
||||
const LOG_FILENAME: &str = "voxygen.log";
|
||||
let _guards = common_frontend::init_stdout(Some((&settings.log.logs_path, LOG_FILENAME)));
|
||||
|
||||
if let Some(path) = veloren_voxygen::settings::voxygen_data_dir().parent() {
|
||||
info!("Using userdata dir at: {}", path.display());
|
||||
} else {
|
||||
error!("Can't log userdata dir, voxygen data dir has no parent!");
|
||||
}
|
||||
|
||||
// Set up panic handler to relay swish panic messages to the user
|
||||
let default_hook = panic::take_hook();
|
||||
panic::set_hook(Box::new(move |panic_info| {
|
||||
@ -92,9 +113,7 @@ fn main() {
|
||||
Panic Payload: {:?}\n\
|
||||
PanicInfo: {}\n\
|
||||
Game version: {} [{}]",
|
||||
Settings::load()
|
||||
.log
|
||||
.logs_path
|
||||
logs_dir
|
||||
.join("voxygen-<date>.log")
|
||||
.display(),
|
||||
reason,
|
||||
@ -171,7 +190,7 @@ fn main() {
|
||||
audio.set_sfx_volume(settings.audio.sfx_volume);
|
||||
|
||||
// Load the profile.
|
||||
let profile = Profile::load();
|
||||
let profile = Profile::load(&config_dir);
|
||||
|
||||
let mut i18n =
|
||||
LocalizationHandle::load(&settings.language.selected_language).unwrap_or_else(|error| {
|
||||
@ -198,6 +217,8 @@ fn main() {
|
||||
let egui_state = EguiState::new(&window);
|
||||
|
||||
let global_state = GlobalState {
|
||||
userdata_dir,
|
||||
config_dir,
|
||||
audio,
|
||||
profile,
|
||||
window,
|
||||
|
@ -139,7 +139,9 @@ impl PlayState for CharSelectionState {
|
||||
global_state
|
||||
.profile
|
||||
.set_selected_character(server_name, selected);
|
||||
global_state.profile.save_to_file_warn();
|
||||
global_state
|
||||
.profile
|
||||
.save_to_file_warn(&global_state.config_dir);
|
||||
},
|
||||
}
|
||||
}
|
||||
@ -185,7 +187,9 @@ impl PlayState for CharSelectionState {
|
||||
match event {
|
||||
client::Event::SetViewDistance(vd) => {
|
||||
global_state.settings.graphics.view_distance = vd;
|
||||
global_state.settings.save_to_file_warn();
|
||||
global_state
|
||||
.settings
|
||||
.save_to_file_warn(&global_state.config_dir);
|
||||
},
|
||||
client::Event::Disconnect => {
|
||||
global_state.info_message = Some(
|
||||
|
@ -175,7 +175,9 @@ impl PlayState for MainMenuState {
|
||||
match event {
|
||||
client::Event::SetViewDistance(vd) => {
|
||||
global_state.settings.graphics.view_distance = vd;
|
||||
global_state.settings.save_to_file_warn();
|
||||
global_state
|
||||
.settings
|
||||
.save_to_file_warn(&global_state.config_dir);
|
||||
},
|
||||
client::Event::Disconnect => {
|
||||
global_state.info_message = Some(
|
||||
@ -238,7 +240,9 @@ impl PlayState for MainMenuState {
|
||||
if !net_settings.servers.contains(&server_address) {
|
||||
net_settings.servers.push(server_address.clone());
|
||||
}
|
||||
global_state.settings.save_to_file_warn();
|
||||
global_state
|
||||
.settings
|
||||
.save_to_file_warn(&global_state.config_dir);
|
||||
|
||||
let connection_args = if use_quic {
|
||||
ConnectionArgs::Quic {
|
||||
@ -302,7 +306,9 @@ impl PlayState for MainMenuState {
|
||||
.networking
|
||||
.trusted_auth_servers
|
||||
.insert(auth_server.clone());
|
||||
global_state.settings.save_to_file_warn();
|
||||
global_state
|
||||
.settings
|
||||
.save_to_file_warn(&global_state.config_dir);
|
||||
}
|
||||
self.init
|
||||
.client()
|
||||
|
@ -1,100 +0,0 @@
|
||||
use common::comp;
|
||||
use directories::ProjectDirs;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{fs, io::Write, path::PathBuf};
|
||||
use tracing::warn;
|
||||
|
||||
const VALID_VERSION: u32 = 0; // Change this if you broke charsaves
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
#[repr(C)]
|
||||
pub struct CharacterData {
|
||||
pub name: String,
|
||||
pub body: comp::Body,
|
||||
pub tool: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
|
||||
//#[serde(default)]
|
||||
#[repr(C)]
|
||||
pub struct Meta {
|
||||
pub characters: Vec<CharacterData>,
|
||||
pub selected_character: usize,
|
||||
pub version: u32,
|
||||
}
|
||||
|
||||
impl Meta {
|
||||
pub fn delete_character(&mut self, index: usize) {
|
||||
self.characters.remove(index);
|
||||
if index < self.selected_character {
|
||||
self.selected_character -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_character(&mut self, data: CharacterData) -> usize {
|
||||
self.characters.push(data);
|
||||
// return new character's index
|
||||
self.characters.len() - 1
|
||||
}
|
||||
|
||||
pub fn load() -> Self {
|
||||
let path = Self::get_meta_path();
|
||||
|
||||
if let Ok(file) = fs::File::open(&path) {
|
||||
match ron::de::from_reader::<_, Meta>(file) {
|
||||
Ok(s) => {
|
||||
if s.version == VALID_VERSION {
|
||||
return s;
|
||||
}
|
||||
},
|
||||
Err(e) => {
|
||||
warn!(?e, ?file, "Failed to parse meta file! Fallback to default");
|
||||
// Rename the corrupted settings file
|
||||
let mut new_path = path.to_owned();
|
||||
new_path.pop();
|
||||
new_path.push("meta.invalid.ron");
|
||||
if let Err(e) = std::fs::rename(path.clone(), new_path.clone()) {
|
||||
warn!(?e, ?path, ?new_path, "Failed to rename meta file");
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
// This is reached if either:
|
||||
// - The file can't be opened (presumably it doesn't exist)
|
||||
// - Or there was an error parsing the file
|
||||
let default = Self::default();
|
||||
default.save_to_file_warn();
|
||||
default
|
||||
}
|
||||
|
||||
pub fn save_to_file_warn(&self) {
|
||||
if let Err(err) = self.save_to_file() {
|
||||
warn!(?e, "Failed to save settings");
|
||||
}
|
||||
}
|
||||
|
||||
pub fn save_to_file(&self) -> std::io::Result<()> {
|
||||
let path = Self::get_meta_path();
|
||||
if let Some(dir) = path.parent() {
|
||||
fs::create_dir_all(dir)?;
|
||||
}
|
||||
let mut meta_file = fs::File::create(path)?;
|
||||
|
||||
let s: &str = &ron::ser::to_string_pretty(self, ron::ser::PrettyConfig::default()).unwrap();
|
||||
meta_file.write_all(s.as_bytes()).unwrap();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn get_meta_path() -> PathBuf {
|
||||
if let Some(path) = std::env::var_os("VOXYGEN_CONFIG") {
|
||||
let meta = PathBuf::from(path).join("meta.ron");
|
||||
if meta.exists() || meta.parent().map(|x| x.exists()).unwrap_or(false) {
|
||||
return meta;
|
||||
}
|
||||
warn!(?path, "VOXYGEN_CONFIG points to invalid path.");
|
||||
}
|
||||
|
||||
let proj_dirs = ProjectDirs::from("net", "veloren", "voxygen")
|
||||
.expect("System's $HOME directory path not found!");
|
||||
proj_dirs.config_dir().join("meta").with_extension("ron")
|
||||
}
|
||||
}
|
@ -1,8 +1,12 @@
|
||||
use crate::{hud, settings};
|
||||
use crate::hud;
|
||||
use common::{character::CharacterId, comp::slot::InvSlotId};
|
||||
use hashbrown::HashMap;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{fs, io::Write, path::PathBuf};
|
||||
use std::{
|
||||
fs,
|
||||
io::Write,
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
use tracing::warn;
|
||||
|
||||
/// Represents a character in the profile.
|
||||
@ -76,8 +80,8 @@ impl Default for Profile {
|
||||
|
||||
impl Profile {
|
||||
/// Load the profile.ron file from the standard path or create it.
|
||||
pub fn load() -> Self {
|
||||
let path = Profile::get_path();
|
||||
pub fn load(config_dir: &Path) -> Self {
|
||||
let path = Profile::get_path(config_dir);
|
||||
|
||||
if let Ok(file) = fs::File::open(&path) {
|
||||
match ron::de::from_reader(file) {
|
||||
@ -100,13 +104,13 @@ impl Profile {
|
||||
// - The file can't be opened (presumably it doesn't exist)
|
||||
// - Or there was an error parsing the file
|
||||
let default_profile = Self::default();
|
||||
default_profile.save_to_file_warn();
|
||||
default_profile.save_to_file_warn(config_dir);
|
||||
default_profile
|
||||
}
|
||||
|
||||
/// Save the current profile to disk, warn on failure.
|
||||
pub fn save_to_file_warn(&self) {
|
||||
if let Err(e) = self.save_to_file() {
|
||||
pub fn save_to_file_warn(&self, config_dir: &Path) {
|
||||
if let Err(e) = self.save_to_file(config_dir) {
|
||||
warn!(?e, "Failed to save profile");
|
||||
}
|
||||
}
|
||||
@ -194,8 +198,8 @@ impl Profile {
|
||||
}
|
||||
|
||||
/// Save the current profile to disk.
|
||||
fn save_to_file(&self) -> std::io::Result<()> {
|
||||
let path = Profile::get_path();
|
||||
fn save_to_file(&self, config_dir: &Path) -> std::io::Result<()> {
|
||||
let path = Profile::get_path(config_dir);
|
||||
if let Some(dir) = path.parent() {
|
||||
fs::create_dir_all(dir)?;
|
||||
}
|
||||
@ -206,19 +210,7 @@ impl Profile {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn get_path() -> PathBuf {
|
||||
if let Some(path) = std::env::var_os("VOXYGEN_CONFIG") {
|
||||
let profile = PathBuf::from(path.clone()).join("profile.ron");
|
||||
if profile.exists() || profile.parent().map(|x| x.exists()).unwrap_or(false) {
|
||||
return profile;
|
||||
}
|
||||
warn!(?path, "VOXYGEN_CONFIG points to invalid path.");
|
||||
}
|
||||
|
||||
let mut path = settings::voxygen_data_dir();
|
||||
path.push("profile.ron");
|
||||
path
|
||||
}
|
||||
fn get_path(config_dir: &Path) -> PathBuf { config_dir.join("profile.ron") }
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -83,8 +83,12 @@ pub fn run(mut global_state: GlobalState, event_loop: EventLoop) {
|
||||
},
|
||||
winit::event::Event::LoopDestroyed => {
|
||||
// Save any unsaved changes to settings and profile
|
||||
global_state.settings.save_to_file_warn();
|
||||
global_state.profile.save_to_file_warn();
|
||||
global_state
|
||||
.settings
|
||||
.save_to_file_warn(&global_state.config_dir);
|
||||
global_state
|
||||
.profile
|
||||
.save_to_file_warn(&global_state.config_dir);
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
@ -100,7 +104,7 @@ fn handle_main_events_cleared(
|
||||
// Screenshot / Fullscreen toggle
|
||||
global_state
|
||||
.window
|
||||
.resolve_deduplicated_events(&mut global_state.settings);
|
||||
.resolve_deduplicated_events(&mut global_state.settings, &global_state.config_dir);
|
||||
// Run tick here
|
||||
|
||||
// What's going on here?
|
||||
|
@ -259,7 +259,9 @@ impl SessionState {
|
||||
},
|
||||
client::Event::SetViewDistance(vd) => {
|
||||
global_state.settings.graphics.view_distance = vd;
|
||||
global_state.settings.save_to_file_warn();
|
||||
global_state
|
||||
.settings
|
||||
.save_to_file_warn(&global_state.config_dir);
|
||||
},
|
||||
client::Event::Outcome(outcome) => outcomes.push(outcome),
|
||||
client::Event::CharacterCreated(_) => {},
|
||||
@ -1305,7 +1307,9 @@ impl PlayState for SessionState {
|
||||
state.slots,
|
||||
);
|
||||
|
||||
global_state.profile.save_to_file_warn();
|
||||
global_state
|
||||
.profile
|
||||
.save_to_file_warn(&global_state.config_dir);
|
||||
|
||||
info!("Event! -> ChangedHotbarState")
|
||||
},
|
||||
|
@ -202,7 +202,6 @@ impl SettingsChange {
|
||||
global_state.audio.set_sfx_volume(audio.sfx_volume);
|
||||
},
|
||||
}
|
||||
settings.save_to_file_warn();
|
||||
},
|
||||
SettingsChange::Chat(chat_change) => {
|
||||
let chat_tabs = &mut settings.chat.chat_tabs;
|
||||
@ -242,7 +241,6 @@ impl SettingsChange {
|
||||
settings.chat = ChatSettings::default();
|
||||
},
|
||||
}
|
||||
settings.save_to_file_warn();
|
||||
},
|
||||
SettingsChange::Control(control_change) => match control_change {
|
||||
Control::ChangeBinding(game_input) => {
|
||||
@ -250,7 +248,6 @@ impl SettingsChange {
|
||||
},
|
||||
Control::ResetKeyBindings => {
|
||||
settings.controls = ControlSettings::default();
|
||||
settings.save_to_file_warn();
|
||||
},
|
||||
},
|
||||
SettingsChange::Gamepad(gamepad_change) => match gamepad_change {},
|
||||
@ -323,7 +320,6 @@ impl SettingsChange {
|
||||
window.mouse_y_inversion = settings.gameplay.mouse_y_inversion;
|
||||
},
|
||||
}
|
||||
settings.save_to_file_warn();
|
||||
},
|
||||
SettingsChange::Graphics(graphics_change) => {
|
||||
match graphics_change {
|
||||
@ -423,7 +419,6 @@ impl SettingsChange {
|
||||
global_state.window.set_size(graphics.window_size.into());
|
||||
},
|
||||
}
|
||||
settings.save_to_file_warn();
|
||||
},
|
||||
SettingsChange::Interface(interface_change) => {
|
||||
match interface_change {
|
||||
@ -534,7 +529,6 @@ impl SettingsChange {
|
||||
.set_scaling_mode(settings.interface.ui_scale);
|
||||
},
|
||||
}
|
||||
settings.save_to_file_warn();
|
||||
},
|
||||
SettingsChange::Language(language_change) => match language_change {
|
||||
Language::ChangeLanguage(new_language) => {
|
||||
@ -556,5 +550,6 @@ impl SettingsChange {
|
||||
},
|
||||
SettingsChange::Networking(networking_change) => match networking_change {},
|
||||
}
|
||||
settings.save_to_file_warn(&global_state.config_dir);
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,9 @@
|
||||
use directories_next::UserDirs;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{fs, path::PathBuf};
|
||||
use std::{
|
||||
fs,
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
use tracing::warn;
|
||||
|
||||
pub mod audio;
|
||||
@ -23,40 +26,6 @@ pub use interface::InterfaceSettings;
|
||||
pub use language::LanguageSettings;
|
||||
pub use networking::NetworkingSettings;
|
||||
|
||||
/// `Log` stores whether we should create a log file
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
#[serde(default)]
|
||||
pub struct Log {
|
||||
// Whether to create a log file or not.
|
||||
// Default is to create one.
|
||||
pub log_to_file: bool,
|
||||
// The path on which the logs will be stored
|
||||
pub logs_path: PathBuf,
|
||||
}
|
||||
|
||||
impl Default for Log {
|
||||
fn default() -> Self {
|
||||
// Chooses a path to store the logs by the following order:
|
||||
// - The VOXYGEN_LOGS environment variable
|
||||
// - The ProjectsDirs data local directory
|
||||
// This function is only called if there isn't already an entry in the settings
|
||||
// file. However, the VOXYGEN_LOGS environment variable always overrides
|
||||
// the log file path if set.
|
||||
let logs_path = std::env::var_os("VOXYGEN_LOGS")
|
||||
.map(PathBuf::from)
|
||||
.unwrap_or_else(|| {
|
||||
let mut path = voxygen_data_dir();
|
||||
path.push("logs");
|
||||
path
|
||||
});
|
||||
|
||||
Self {
|
||||
log_to_file: true,
|
||||
logs_path,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// `Settings` contains everything that can be configured in the settings.ron
|
||||
/// file.
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
@ -67,7 +36,6 @@ pub struct Settings {
|
||||
pub interface: InterfaceSettings,
|
||||
pub gameplay: GameplaySettings,
|
||||
pub networking: NetworkingSettings,
|
||||
pub log: Log,
|
||||
pub graphics: GraphicsSettings,
|
||||
pub audio: AudioSettings,
|
||||
pub show_disclaimer: bool,
|
||||
@ -104,7 +72,6 @@ impl Default for Settings {
|
||||
interface: InterfaceSettings::default(),
|
||||
gameplay: GameplaySettings::default(),
|
||||
networking: NetworkingSettings::default(),
|
||||
log: Log::default(),
|
||||
graphics: GraphicsSettings::default(),
|
||||
audio: AudioSettings::default(),
|
||||
show_disclaimer: true,
|
||||
@ -118,25 +85,12 @@ impl Default for Settings {
|
||||
}
|
||||
|
||||
impl Settings {
|
||||
pub fn load() -> Self {
|
||||
let path = Self::get_settings_path();
|
||||
pub fn load(config_dir: &Path) -> Self {
|
||||
let path = Self::get_path(config_dir);
|
||||
|
||||
if let Ok(file) = fs::File::open(&path) {
|
||||
match ron::de::from_reader::<_, Self>(file) {
|
||||
Ok(mut s) => {
|
||||
// Override the logs path if it is explicitly set using the VOXYGEN_LOGS
|
||||
// environment variable. This is needed to support package managers that enforce
|
||||
// strict application confinement (e.g. snap). In fact, the veloren snap package
|
||||
// relies on this environment variable to be respected in
|
||||
// order to communicate a path where the snap package is
|
||||
// allowed to write to.
|
||||
if let Some(logs_path_override) =
|
||||
std::env::var_os("VOXYGEN_LOGS").map(PathBuf::from)
|
||||
{
|
||||
s.log.logs_path = logs_path_override;
|
||||
}
|
||||
return s;
|
||||
},
|
||||
Ok(s) => return s,
|
||||
Err(e) => {
|
||||
warn!(?e, "Failed to parse setting file! Fallback to default.");
|
||||
// Rename the corrupted settings file
|
||||
@ -153,18 +107,18 @@ impl Settings {
|
||||
// - The file can't be opened (presumably it doesn't exist)
|
||||
// - Or there was an error parsing the file
|
||||
let default_settings = Self::default();
|
||||
default_settings.save_to_file_warn();
|
||||
default_settings.save_to_file_warn(config_dir);
|
||||
default_settings
|
||||
}
|
||||
|
||||
pub fn save_to_file_warn(&self) {
|
||||
if let Err(e) = self.save_to_file() {
|
||||
pub fn save_to_file_warn(&self, config_dir: &Path) {
|
||||
if let Err(e) = self.save_to_file(config_dir) {
|
||||
warn!(?e, "Failed to save settings");
|
||||
}
|
||||
}
|
||||
|
||||
pub fn save_to_file(&self) -> std::io::Result<()> {
|
||||
let path = Self::get_settings_path();
|
||||
pub fn save_to_file(&self, config_dir: &Path) -> std::io::Result<()> {
|
||||
let path = Self::get_path(config_dir);
|
||||
if let Some(dir) = path.parent() {
|
||||
fs::create_dir_all(dir)?;
|
||||
}
|
||||
@ -173,25 +127,5 @@ impl Settings {
|
||||
fs::write(path, ron.as_bytes())
|
||||
}
|
||||
|
||||
pub fn get_settings_path() -> PathBuf {
|
||||
if let Some(path) = std::env::var_os("VOXYGEN_CONFIG") {
|
||||
let settings = PathBuf::from(&path).join("settings.ron");
|
||||
if settings.exists() || settings.parent().map(|x| x.exists()).unwrap_or(false) {
|
||||
return settings;
|
||||
}
|
||||
warn!(?path, "VOXYGEN_CONFIG points to invalid path.");
|
||||
}
|
||||
|
||||
let mut path = voxygen_data_dir();
|
||||
path.push("settings.ron");
|
||||
path
|
||||
}
|
||||
}
|
||||
|
||||
pub fn voxygen_data_dir() -> PathBuf {
|
||||
// Note: since voxygen is technically a lib we made need to lift this up to
|
||||
// run.rs
|
||||
let mut path = common_base::userdata_dir_workspace!();
|
||||
path.push("voxygen");
|
||||
path
|
||||
fn get_path(config_dir: &Path) -> PathBuf { config_dir.join("settings.ron") }
|
||||
}
|
||||
|
@ -703,7 +703,11 @@ impl Window {
|
||||
|
||||
pub fn renderer_mut(&mut self) -> &mut Renderer { &mut self.renderer }
|
||||
|
||||
pub fn resolve_deduplicated_events(&mut self, settings: &mut Settings) {
|
||||
pub fn resolve_deduplicated_events(
|
||||
&mut self,
|
||||
settings: &mut Settings,
|
||||
config_dir: &std::path::Path,
|
||||
) {
|
||||
// Handle screenshots and toggling fullscreen
|
||||
if self.take_screenshot {
|
||||
self.take_screenshot = false;
|
||||
@ -711,7 +715,7 @@ impl Window {
|
||||
}
|
||||
if self.toggle_fullscreen {
|
||||
self.toggle_fullscreen = false;
|
||||
self.toggle_fullscreen(settings);
|
||||
self.toggle_fullscreen(settings, config_dir);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1170,7 +1174,7 @@ impl Window {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn toggle_fullscreen(&mut self, settings: &mut Settings) {
|
||||
pub fn toggle_fullscreen(&mut self, settings: &mut Settings, config_dir: &std::path::Path) {
|
||||
let fullscreen = FullScreenSettings {
|
||||
enabled: !self.is_fullscreen(),
|
||||
..settings.graphics.fullscreen
|
||||
@ -1178,7 +1182,7 @@ impl Window {
|
||||
|
||||
self.set_fullscreen_mode(fullscreen);
|
||||
settings.graphics.fullscreen = fullscreen;
|
||||
settings.save_to_file_warn();
|
||||
settings.save_to_file_warn(config_dir);
|
||||
}
|
||||
|
||||
pub fn is_fullscreen(&self) -> bool { self.fullscreen.enabled }
|
||||
|
Loading…
Reference in New Issue
Block a user