-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathConfigurationUtil.cs
129 lines (121 loc) · 4.86 KB
/
ConfigurationUtil.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
using System;
using System.Linq;
using System.IO;
using System.Xml.Serialization;
namespace PopulationDemographics
{
/// <summary>
/// Handle loading and saving a global configuration file for a mod
/// Based on code by boformer:
/// https://gist.githubusercontent.com/boformer/cb6840867c6febd25c8f/raw/a56159664b974be4b3e7d6625d08bc35b7a3f9a6/Configuration.cs
/// By default, the config file is saved in the same location as Cities.exe. For Windows, this is:
/// C:\Program Files (x86)\Steam\steamapps\common\Cities_Skylines
/// </summary>
/// <typeparam name="C">configuration file name</typeparam>
public abstract class ConfigurationUtil<C> where C : class, new()
{
// the one and only instance of the config class to be loaded/saved
private static C instance;
/// <summary>
/// Return the config class from the file
/// </summary>
/// <returns>an instance of the config class from the config file or a new instance of the config class</returns>
public static C Load()
{
// check for an instance
if (instance == null)
{
try
{
// check if the config file exists
string configFile = GetConfigFile();
if (File.Exists(configFile))
{
// load the config file into the instance
using (StreamReader streamReader = new StreamReader(configFile))
{
// if a value from C is missing in the file, no exception is thrown, the value in C is simply not updated
// this is one reason why each config value in C must have a default value
XmlSerializer xmlSerializer = new XmlSerializer(typeof(C));
instance = xmlSerializer.Deserialize(streamReader) as C;
}
}
else
{
// no config file, create a new instance of the config class
// this is one reason why each config value in C must have a default value
instance = new C();
}
}
catch (Exception ex)
{
LogUtil.LogException(ex);
instance = new C();
}
}
// return the instance (either loaded or new)
return instance;
}
/// <summary>
/// Save the instance to the config file
/// </summary>
public static void Save()
{
// the config must have been loaded prior to attempting to save
if (instance == null)
{
LogUtil.LogError("Attempt to save configuration for " + typeof(C).Name + " before an instance was loaded.");
return;
}
try
{
// save the instance to the config file
string configFile = GetConfigFile();
using (StreamWriter streamWriter = new StreamWriter(configFile))
{
XmlSerializerNamespaces noNamespaces = new XmlSerializerNamespaces();
noNamespaces.Add("", "");
XmlSerializer xmlSerializer = new XmlSerializer(typeof(C));
xmlSerializer.Serialize(streamWriter, instance, noNamespaces);
}
}
catch (Exception ex)
{
LogUtil.LogException(ex);
}
}
/// <summary>
/// get the config file name from the attribute
/// </summary>
/// <returns>config file name</returns>
private static string GetConfigFile()
{
// get the attribute
ConfigurationFileNameAttribute configFileAttribute = typeof(C).GetCustomAttributes(typeof(ConfigurationFileNameAttribute), true)
.FirstOrDefault() as ConfigurationFileNameAttribute;
if (configFileAttribute != null)
{
// found the attribute, return it
return configFileAttribute.Value;
}
else
{
// log an error and return a default file name
LogUtil.LogError("ConfigurationFile attribute missing in " + typeof(C).Name);
return typeof(C).Name + "Config.xml";
}
}
}
/// <summary>
/// the configuration file name attribute
/// </summary>
[AttributeUsage(AttributeTargets.Class)]
public class ConfigurationFileNameAttribute : Attribute
{
public ConfigurationFileNameAttribute(string value)
{
Value = value;
}
public string Value { get; private set; }
}
}