A game framework written with osu! in mind.
at master 101 lines 3.5 kB view raw
1// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. 2// See the LICENCE file in the repository root for full licence text. 3 4using System; 5using System.Collections.Generic; 6using System.IO; 7using osu.Framework.Bindables; 8using osu.Framework.Extensions.ObjectExtensions; 9using osu.Framework.Extensions.TypeExtensions; 10using osu.Framework.Logging; 11using osu.Framework.Platform; 12 13namespace osu.Framework.Configuration 14{ 15 public class IniConfigManager<TLookup> : ConfigManager<TLookup> 16 where TLookup : struct, Enum 17 { 18 /// <summary> 19 /// The backing file used to store the config. Null means no persistent storage. 20 /// </summary> 21 protected virtual string Filename => @"game.ini"; 22 23 private readonly Storage storage; 24 25 public IniConfigManager(Storage storage, IDictionary<TLookup, object> defaultOverrides = null) 26 : base(defaultOverrides) 27 { 28 this.storage = storage; 29 30 InitialiseDefaults(); 31 Load(); 32 } 33 34 protected override void PerformLoad() 35 { 36 if (string.IsNullOrEmpty(Filename)) return; 37 38 using (var stream = storage.GetStream(Filename)) 39 { 40 if (stream == null) 41 return; 42 43 using (var reader = new StreamReader(stream)) 44 { 45 string line; 46 47 while ((line = reader.ReadLine()) != null) 48 { 49 int equalsIndex = line.IndexOf('='); 50 51 if (line.Length == 0 || line[0] == '#' || equalsIndex < 0) continue; 52 53 string key = line.AsSpan(0, equalsIndex).Trim().ToString(); 54 string val = line.AsSpan(equalsIndex + 1).Trim().ToString(); 55 56 if (!Enum.TryParse(key, out TLookup lookup)) 57 continue; 58 59 if (ConfigStore.TryGetValue(lookup, out IBindable b)) 60 { 61 try 62 { 63 if (!(b is IParseable parseable)) 64 throw new InvalidOperationException($"Bindable type {b.GetType().ReadableName()} is not {nameof(IParseable)}."); 65 66 parseable.Parse(val); 67 } 68 catch (Exception e) 69 { 70 Logger.Log($@"Unable to parse config key {lookup}: {e}", LoggingTarget.Runtime, LogLevel.Important); 71 } 72 } 73 else if (AddMissingEntries) 74 SetDefault(lookup, val); 75 } 76 } 77 } 78 } 79 80 protected override bool PerformSave() 81 { 82 if (string.IsNullOrEmpty(Filename)) return false; 83 84 try 85 { 86 using (var stream = storage.GetStream(Filename, FileAccess.Write, FileMode.Create)) 87 using (var w = new StreamWriter(stream)) 88 { 89 foreach (var p in ConfigStore) 90 w.WriteLine(@"{0} = {1}", p.Key, p.Value.ToString().AsNonNull().Replace("\n", "").Replace("\r", "")); 91 } 92 } 93 catch 94 { 95 return false; 96 } 97 98 return true; 99 } 100 } 101}