forked from VictorPhilipp/OptionsFramework
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathOptionsWrapper.cs
145 lines (137 loc) · 4.27 KB
/
OptionsWrapper.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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
using System;
using System.IO;
using System.Xml;
using System.Xml.Serialization;
using ColossalFramework.IO;
using OptionsFramework.Attibutes;
using UnityEngine;
namespace OptionsFramework
{
public class OptionsWrapper<T>
{
private static T _instance;
public static T Options
{
get
{
try
{
Ensure();
}
catch (XmlException e)
{
UnityEngine.Debug.LogError("Error reading options XML file");
UnityEngine.Debug.LogException(e);
}
return _instance;
}
}
public static void Ensure()
{
if (_instance != null)
{
return;
}
var type = typeof(T);
var attrs = type.GetCustomAttributes(typeof(OptionsAttribute), false);
if (attrs.Length != 1)
{
throw new Exception($"Type {type.FullName} is not an options type!");
}
_instance = (T)Activator.CreateInstance(typeof(T));
LoadOptions();
}
private static void LoadOptions()
{
try
{
if (GetLegacyFileName() != string.Empty)
{
try
{
ReadOptionsFile(GetLegacyFileName());
try
{
File.Delete(GetLegacyFileName());
}
catch (Exception e)
{
UnityEngine.Debug.LogException(e);
}
SaveOptions();
}
catch (FileNotFoundException)
{
ReadOptionsFile(GetFileName());
}
}
else
{
ReadOptionsFile(GetFileName());
}
}
catch (FileNotFoundException)
{
SaveOptions(); // No options file yet
}
}
private static void ReadOptionsFile(string fileName)
{
var xmlSerializer = new XmlSerializer(typeof(T));
using (var streamReader = new StreamReader(fileName))
{
var options = (T)xmlSerializer.Deserialize(streamReader);
foreach (var propertyInfo in typeof(T).GetProperties())
{
if (!propertyInfo.CanWrite)
{
continue;
}
var value = propertyInfo.GetValue(options, null);
propertyInfo.SetValue(_instance, value, null);
}
}
}
internal static void SaveOptions()
{
try
{
var xmlSerializer = new XmlSerializer(typeof(T));
using (var streamWriter = new StreamWriter(GetFileName()))
{
xmlSerializer.Serialize(streamWriter, _instance);
}
}
catch (Exception e)
{
Debug.LogException(e);
}
}
private static string GetFileName()
{
var type = _instance.GetType();
var attrs = type.GetCustomAttributes(typeof(OptionsAttribute), false);
var fileName = Path.Combine(DataLocation.localApplicationData, ((OptionsAttribute)attrs[0]).FileName);
if (!fileName.EndsWith(".xml"))
{
fileName = fileName + ".xml";
}
return fileName;
}
private static string GetLegacyFileName()
{
var type = _instance.GetType();
var attrs = type.GetCustomAttributes(typeof(OptionsAttribute), false);
var fileName = ((OptionsAttribute)attrs[0]).LegacyFileName;
if (fileName == string.Empty)
{
return fileName;
}
if (!fileName.EndsWith(".xml"))
{
fileName = fileName + ".xml";
}
return fileName;
}
}
}