1
1
using System ;
2
2
using System . Collections . Generic ;
3
+ using System . Globalization ;
3
4
using System . Linq ;
4
- using System . Reflection ;
5
5
using IxMilia . BCad . Settings ;
6
6
using IxMilia . Config ;
7
7
8
8
namespace IxMilia . BCad . Services
9
9
{
10
10
internal class SettingsService : ISettingsService
11
11
{
12
+ private delegate object ValueReader ( string value ) ;
13
+ private delegate string ValueWriter ( object value ) ;
14
+
12
15
private IWorkspace _workspace ;
13
- private Dictionary < string , Tuple < Type , object > > _settings = new Dictionary < string , Tuple < Type , object > > ( ) ;
16
+ private Dictionary < string , Tuple < Type , object > > _settings = new ( ) ;
17
+ private Dictionary < Type , Tuple < ValueReader , ValueWriter > > _typeConverters = new ( ) ;
14
18
15
19
public event SettingChangedEventHandler SettingChanged ;
16
20
21
+ private SettingsService ( )
22
+ {
23
+ _typeConverters . Add ( typeof ( bool ) , Tuple . Create < ValueReader , ValueWriter > ( BoolReader , BoolWriter ) ) ;
24
+ _typeConverters . Add ( typeof ( CadColor ) , Tuple . Create < ValueReader , ValueWriter > ( CadColorReader , CadColorWriter ) ) ;
25
+ _typeConverters . Add ( typeof ( double ) , Tuple . Create < ValueReader , ValueWriter > ( DoubleReader , DoubleWriter ) ) ;
26
+ _typeConverters . Add ( typeof ( double [ ] ) , Tuple . Create ( CreateArrayReader < double > ( DoubleReader ) , CreateArrayWriter ( DoubleWriter ) ) ) ;
27
+ _typeConverters . Add ( typeof ( DrawingUnits ) , Tuple . Create < ValueReader , ValueWriter > ( DrawingUnitsReader , DrawingUnitsWriter ) ) ;
28
+ _typeConverters . Add ( typeof ( int ) , Tuple . Create < ValueReader , ValueWriter > ( IntReader , IntWriter ) ) ;
29
+ _typeConverters . Add ( typeof ( string ) , Tuple . Create < ValueReader , ValueWriter > ( StringReader , StringWriter ) ) ;
30
+ _typeConverters . Add ( typeof ( UnitFormat ) , Tuple . Create < ValueReader , ValueWriter > ( UnitFormatReader , UnitFormatWriter ) ) ;
31
+ }
32
+
17
33
public SettingsService ( IWorkspace workspace )
34
+ : this ( )
18
35
{
19
36
_workspace = workspace ;
20
37
}
@@ -28,8 +45,32 @@ public void RegisterSetting(string name, Type type, object value)
28
45
else
29
46
{
30
47
_settings [ name ] = Tuple . Create ( type , ( object ) null ) ;
31
- SetValue ( name , value , ignoreTypeCheck : true ) ;
48
+ SetValue ( name , value ) ;
49
+ }
50
+ }
51
+
52
+ public string ValueToString ( Type type , object value )
53
+ {
54
+ if ( ! _typeConverters . TryGetValue ( type , out var pair ) )
55
+ {
56
+ throw new InvalidOperationException ( $ "No type converter for { type . Name } ") ;
57
+ }
58
+
59
+ var writer = pair . Item2 ;
60
+ var s = writer ( value ) ;
61
+ return s ;
62
+ }
63
+
64
+ public object StringToValue ( Type type , string value )
65
+ {
66
+ if ( ! _typeConverters . TryGetValue ( type , out var pair ) )
67
+ {
68
+ throw new InvalidOperationException ( $ "No type converter for { type . Name } ") ;
32
69
}
70
+
71
+ var reader = pair . Item1 ;
72
+ var o = reader ( value ) ;
73
+ return o ;
33
74
}
34
75
35
76
public T GetValue < T > ( string settingName )
@@ -49,46 +90,36 @@ public T GetValue<T>(string settingName)
49
90
}
50
91
51
92
public void SetValue < T > ( string settingName , T value )
52
- {
53
- SetValue ( settingName , value , ignoreTypeCheck : false ) ;
54
- }
55
-
56
- private void SetValue < T > ( string settingName , T value , bool ignoreTypeCheck = false )
57
93
{
58
94
if ( ! _settings . TryGetValue ( settingName , out var pair ) )
59
95
{
96
+ // no such setting
60
97
return ;
61
98
}
62
99
63
100
var type = pair . Item1 ;
64
101
var oldValue = pair . Item2 ;
65
102
object valueToSet = value ;
66
- if ( value is string && type != typeof ( string ) )
67
- {
68
- // a terrible hack to get the appropriate parse method
69
- var tryParseFunction = typeof ( ConfigExtensions ) . GetRuntimeMethods ( )
70
- . Single ( m => m . Name == nameof ( ConfigExtensions . TryParseValue ) && m . GetParameters ( ) . Length == 2 ) ;
71
- tryParseFunction = tryParseFunction . MakeGenericMethod ( type ) ;
72
- var parameters = new object [ ] { value , null } ;
73
- if ( ! ( bool ) tryParseFunction . Invoke ( null , parameters ) )
74
- {
75
- return ;
76
- }
77
-
78
- valueToSet = parameters [ 1 ] ;
79
- }
80
- else if ( ! ignoreTypeCheck && type != typeof ( T ) )
103
+ if ( Equals ( pair . Item2 , valueToSet ) )
81
104
{
105
+ // no change
82
106
return ;
83
107
}
84
108
85
- if ( Equals ( pair . Item2 , valueToSet ) )
109
+ _settings [ settingName ] = Tuple . Create ( type , valueToSet ) ;
110
+ SettingChanged ? . Invoke ( this , new SettingChangedEventArgs ( settingName , type , oldValue , value ) ) ;
111
+ }
112
+
113
+ public void SetValueFromString ( string settingName , string value )
114
+ {
115
+ if ( ! _settings . TryGetValue ( settingName , out var pair ) )
86
116
{
117
+ // no such setting
87
118
return ;
88
119
}
89
120
90
- _settings [ settingName ] = Tuple . Create ( type , valueToSet ) ;
91
- SettingChanged ? . Invoke ( this , new SettingChangedEventArgs ( settingName , type , oldValue , value ) ) ;
121
+ var nativeValue = StringToValue ( pair . Item1 , value ) ;
122
+ SetValue ( settingName , nativeValue ) ;
92
123
}
93
124
94
125
public void LoadFromLines ( string [ ] lines )
@@ -97,7 +128,14 @@ public void LoadFromLines(string[] lines)
97
128
fileValues . ParseConfig ( lines ) ;
98
129
foreach ( var kvp in fileValues )
99
130
{
100
- SetValue ( kvp . Key , kvp . Value ) ;
131
+ if ( ! _settings . TryGetValue ( kvp . Key , out var pair ) )
132
+ {
133
+ // no such setting
134
+ continue ;
135
+ }
136
+
137
+ var v = StringToValue ( pair . Item1 , kvp . Value ) ;
138
+ SetValue ( kvp . Key , v ) ;
101
139
}
102
140
}
103
141
@@ -106,7 +144,8 @@ public string WriteWithLines(string[] existingLines)
106
144
var values = new Dictionary < string , string > ( ) ;
107
145
foreach ( var kvp in _settings )
108
146
{
109
- values [ kvp . Key ] = kvp . Value . Item2 . ToConfigString ( ) ;
147
+ var s = ValueToString ( kvp . Value . Item1 , kvp . Value . Item2 ) ;
148
+ values [ kvp . Key ] = s ;
110
149
}
111
150
112
151
var newContent = values . WriteConfig ( existingLines ) ;
@@ -126,5 +165,42 @@ public SettingData(string name, Type type, object value)
126
165
Value = value ;
127
166
}
128
167
}
168
+
169
+ private static object BoolReader ( string value ) => bool . Parse ( value ) ;
170
+ private static string BoolWriter ( object value ) => ( ( bool ) value ) . ToString ( CultureInfo . InvariantCulture ) ;
171
+
172
+ private static object CadColorReader ( string value ) => CadColor . Parse ( value ) ;
173
+ private static string CadColorWriter ( object value ) => ( ( CadColor ) value ) . ToString ( ) ;
174
+
175
+ private static object DoubleReader ( string value ) => double . Parse ( value , CultureInfo . InvariantCulture ) ;
176
+ private static string DoubleWriter ( object value ) => ( ( double ) value ) . ToString ( CultureInfo . InvariantCulture ) ;
177
+
178
+ private static object DrawingUnitsReader ( string value ) => Enum . Parse ( typeof ( DrawingUnits ) , value ) ;
179
+ private static string DrawingUnitsWriter ( object value ) => ( ( DrawingUnits ) value ) . ToString ( ) ;
180
+
181
+ private static object IntReader ( string value ) => int . Parse ( value , CultureInfo . InvariantCulture ) ;
182
+ private static string IntWriter ( object value ) => ( ( int ) value ) . ToString ( CultureInfo . InvariantCulture ) ;
183
+
184
+ private static object StringReader ( string value ) => value ;
185
+ private static string StringWriter ( object value ) => value . ToString ( ) ;
186
+
187
+ private static object UnitFormatReader ( string value ) => Enum . Parse ( typeof ( UnitFormat ) , value ) ;
188
+ private static string UnitFormatWriter ( object value ) => ( ( UnitFormat ) value ) . ToString ( ) ;
189
+
190
+ private static ValueReader CreateArrayReader < T > ( Func < string , object > elementReader ) => value => value . Split ( ';' ) . Select ( elementReader ) . Cast < T > ( ) . ToArray ( ) ;
191
+ private static ValueWriter CreateArrayWriter ( Func < object , string > elementWriter )
192
+ {
193
+ return value =>
194
+ {
195
+ var array = ( Array ) value ;
196
+ var values = new List < object > ( ) ;
197
+ foreach ( var x in array )
198
+ {
199
+ values . Add ( elementWriter ( x ) ) ;
200
+ }
201
+
202
+ return string . Join ( ";" , values ) ;
203
+ } ;
204
+ }
129
205
}
130
206
}
0 commit comments