Skip to content

Commit bc8230a

Browse files
committed
🎨 bulk save modular settings
1 parent 0a9236b commit bc8230a

File tree

5 files changed

+78
-21
lines changed

5 files changed

+78
-21
lines changed

Biyori/App.xaml

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
<Application x:Class="Biyori.App"
22
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
33
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4-
xmlns:local="clr-namespace:Biyori"
5-
StartupUri="MainWindow.xaml">
4+
xmlns:local="clr-namespace:Biyori">
65
<Application.Resources>
76
<ResourceDictionary>
87
<ResourceDictionary.MergedDictionaries>

Biyori/App.xaml.cs

+7-2
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,16 @@ namespace Biyori
1313
/// </summary>
1414
public partial class App : Application
1515
{
16-
public readonly static ServiceProvider ServiceProvider = new ServiceProvider();
16+
public static readonly ServiceProviderCollector ServiceProvider = new ServiceProviderCollector();
17+
public App() : base()
18+
{
19+
}
1720
protected override void OnStartup(StartupEventArgs e)
1821
{
1922
base.OnStartup(e);
20-
ServiceProvider.ScanCurrent();
23+
24+
App.ServiceProvider.ScanCurrent();
25+
new MainWindow().Show();
2126
}
2227
}
2328
}

Biyori/ServiceProvider.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@
77

88
namespace Biyori
99
{
10-
public class ServiceProvider
10+
public class ServiceProviderCollector
1111
{
1212
private List<ServiceProviderBase> serviceProviders { get; set; }
13-
public ServiceProvider()
13+
public ServiceProviderCollector()
1414
{
1515
this.serviceProviders = new List<ServiceProviderBase>();
1616
}

Biyori/Settings/SettingsProvider.cs

+61-8
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
using Newtonsoft.Json;
2+
using Newtonsoft.Json.Linq;
23
using PropertyChanged;
34
using System;
5+
using System.Collections.Concurrent;
46
using System.Collections.Generic;
57
using System.IO;
68
using System.Linq;
@@ -16,22 +18,33 @@ public class SettingsProvider : ServiceProviderBase
1618
{
1719
private string configPath { get => Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "config"); }
1820
private string settingsPath { get => Path.Combine(configPath, "settings.json"); }
19-
private List<SettingsBase> Settings { get; set; } = new List<SettingsBase>();
21+
private ConcurrentDictionary<string, SettingsBase> Settings { get; set; } = new ConcurrentDictionary<string, SettingsBase>();
2022

2123
public SettingsProvider()
2224
{
25+
bool initialConfig = false;
2326
if (!Directory.Exists(this.configPath))
2427
{
2528
Directory.CreateDirectory(this.configPath);
2629
}
2730
if (!File.Exists(this.settingsPath))
2831
{
32+
initialConfig = true;
2933
initializeConfig();
3034
}
31-
this.Settings.AddRange(
32-
Assembly.GetEntryAssembly().GetTypes()
35+
Assembly.GetEntryAssembly().GetTypes()
3336
.Where(x => x.GetCustomAttributes<SettingsSectionAttribute>().Count() > 0)
34-
.Select(x => Activator.CreateInstance(x) as SettingsBase));
37+
.Select(x => Activator.CreateInstance(x) as SettingsBase).ToList().ForEach(x =>
38+
{
39+
this.Settings.AddOrUpdate(
40+
x.GetType().GetCustomAttribute<SettingsSectionAttribute>()?.name,
41+
key => x,
42+
(key, oldSettings) => oldSettings = x);
43+
});
44+
if (!initialConfig)
45+
{
46+
this.LoadSettings().Wait();
47+
}
3548

3649
}
3750
private void initializeConfig()
@@ -50,12 +63,52 @@ private void initializeConfig()
5063
}
5164
public T GetConfig<T>() where T : SettingsBase
5265
{
53-
return this.Settings.FirstOrDefault(x => x.GetType() == typeof(T)) as T;
66+
return this.Settings.FirstOrDefault(x => x.Value.GetType() == typeof(T)).Value as T;
67+
}
68+
public void UpdateConfig<T>(T settings, bool saveToFile = false) where T : SettingsBase
69+
{
70+
this.Settings.AddOrUpdate(
71+
settings.GetType().GetCustomAttribute<SettingsSectionAttribute>()?.name,
72+
key => settings,
73+
(key, oldSettings) => oldSettings = settings);
74+
if (saveToFile)
75+
{
76+
this.SaveSettings();
77+
}
5478
}
55-
public void UpdateConfig<T>(T settings) where T : SettingsBase
79+
public async Task LoadSettings()
5680
{
57-
var itemIndex = this.Settings.FindIndex(x => x.GetType() == typeof(T));
58-
this.Settings[itemIndex] = settings;
81+
var settingsIn = File.ReadAllText(this.settingsPath);
82+
var settings = JsonConvert.DeserializeObject<Dictionary<string, object>>(settingsIn);
83+
84+
var availableSettings = Assembly.GetEntryAssembly().GetTypes()
85+
.Where(x => x.GetCustomAttributes<SettingsSectionAttribute>().Count() > 0);
86+
settings.ToList().ForEach(x =>
87+
{
88+
if (this.Settings.ContainsKey(x.Key))
89+
{
90+
var avSetting = availableSettings.FirstOrDefault(y => y.GetCustomAttribute<SettingsSectionAttribute>()?.name == x.Key);
91+
if (avSetting != null)
92+
{
93+
var obj = (x.Value as JObject).ToObject(avSetting);
94+
this.Settings.AddOrUpdate(x.Key, key => obj as SettingsBase, (key, oldSetting) => oldSetting = obj as SettingsBase);
95+
}
96+
}
97+
});
98+
}
99+
public async Task SaveSettings()
100+
{
101+
try
102+
{
103+
File.WriteAllText(this.settingsPath, JsonConvert.SerializeObject(this.Settings, Formatting.Indented));
104+
}
105+
catch (Exception ex)
106+
{
107+
if (!(ex is FileNotFoundException || ex is DirectoryNotFoundException))
108+
{
109+
throw ex;
110+
}
111+
}
59112
}
60113
}
61114
public abstract class SettingsBase { }

Biyori/Settings/SettingsWindow.xaml.cs

+7-7
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ namespace Biyori.Settings
2424
public partial class SettingsWindow : Window
2525
{
2626
public IEnumerable<SettingsRouteAttribute> SettingRoutes { get => Assembly.GetEntryAssembly().GetTypes().Where(x => x.GetCustomAttributes<SettingsRouteAttribute>().Count() > 0).Select(x => x.GetCustomAttribute<SettingsRouteAttribute>()); }
27+
public SettingsProvider settingsProvider { get; private set; }
2728
public SettingsWindow()
2829
{
2930
InitializeComponent();
@@ -39,10 +40,9 @@ public SettingsWindow()
3940
protected override void OnInitialized(EventArgs e)
4041
{
4142
base.OnInitialized(e);
42-
var sp = App.ServiceProvider.GetProvider<SettingsProvider>();
43-
var accountConfig = sp.GetConfig<AccountSettings>();
44-
#if DEBUG
45-
if (accountConfig.Accounts.Count == 0)
43+
this.settingsProvider = App.ServiceProvider.GetProvider<SettingsProvider>();
44+
var accountConfig = this.settingsProvider.GetConfig<AccountSettings>();
45+
if (Debugger.IsAttached && accountConfig.Accounts.Count == 0)
4646
{
4747
accountConfig.Accounts.Add(new AccountInfo()
4848
{
@@ -51,9 +51,8 @@ protected override void OnInitialized(EventArgs e)
5151
EmailAddress = "[email protected]"
5252
});
5353
}
54-
#endif
55-
sp.UpdateConfig(accountConfig);
56-
Debug.WriteLine(JsonConvert.SerializeObject(sp.GetConfig<AccountSettings>()));
54+
this.settingsProvider.UpdateConfig(accountConfig);
55+
Debug.WriteLine(JsonConvert.SerializeObject(this.settingsProvider.GetConfig<AccountSettings>()));
5756
}
5857

5958
private void SettingsNav_SelectionChanged(object sender, SelectionChangedEventArgs e)
@@ -92,6 +91,7 @@ private void Window_PreviewKeyDown(object sender, KeyEventArgs e)
9291

9392
private void SaveChange_Click(object sender, RoutedEventArgs e)
9493
{
94+
this.settingsProvider.SaveSettings().Wait();
9595
this.Close();
9696
}
9797
}

0 commit comments

Comments
 (0)