11using System ;
22using System . Collections . Generic ;
3- using System . Diagnostics ;
4- using System . IO ;
5- using System . Linq ;
63using EnumerableToolkit ;
7- using FrooxEngine ;
8- using HarmonyLib ;
94using MonkeyLoader ;
10- using MonkeyLoader . Configuration ;
11- using Newtonsoft . Json ;
12- using Newtonsoft . Json . Linq ;
135
146namespace ResoniteModLoader
157{
168 /// <summary>
17- /// Represents an interface for mod configurations.
18- /// </summary>
19- public interface IModConfigurationDefinition
20- {
21- /// <summary>
22- /// Gets the set of configuration keys defined in this configuration definition.
23- /// </summary>
24- ISet < ModConfigurationKey > ConfigurationItemDefinitions { get ; }
25-
26- /// <summary>
27- /// Gets the mod that owns this configuration definition.
28- /// </summary>
29- ResoniteModBase Owner { get ; }
30-
31- /// <summary>
32- /// Gets the semantic version for this configuration definition. This is used to check if the defined and saved configs are compatible.
33- /// </summary>
34- Version Version { get ; }
35- }
36-
37- /// <summary>
38- /// Defines options for the handling of incompatible configuration versions.
9+ /// The configuration for a mod. Each mod has zero or one configuration. The configuration object will never be reassigned once initialized.
3910 /// </summary>
40- public enum IncompatibleConfigurationHandlingOption
11+ public class ModConfiguration : IModConfigurationDefinition
4112 {
42- /// <summary>
43- /// Fail to read the config, and block saving over the config on disk.
44- /// </summary>
45- ERROR = IncompatibleConfigHandling . Error ,
13+ internal ModConfigurationDefinition Definition { get ; }
4614
4715 /// <summary>
48- /// Destroy the saved config and start over from scratch.
16+ /// Gets the internal <see cref="MonkeyLoader.Configuration.ConfigSection"/>
17+ /// that actually handles storing the data for this.
4918 /// </summary>
50- CLOBBER = IncompatibleConfigHandling . Clobber ,
51-
52- /// <summary>
53- /// Ignore the version number and attempt to load the config from disk.
54- /// </summary>
55- FORCELOAD = IncompatibleConfigHandling . ForceLoad ,
56- }
57-
58- /// <summary>
59- /// The configuration for a mod. Each mod has zero or one configuration. The configuration object will never be reassigned once initialized.
60- /// </summary>
61- public class ModConfiguration : ConfigSection , IModConfigurationDefinition
62- {
63- private readonly ModConfigurationDefinition _definition ;
64-
65- /// <inheritdoc/>
66- public ISet < ModConfigurationKey > ConfigurationItemDefinitions => _definition . ConfigurationItemDefinitions ;
67-
68- /// <inheritdoc/>
69- public override string Description => "RML Mod Config" ;
19+ internal RmlModConfigSection ConfigSection { get ; }
7020
7121 /// <inheritdoc/>
72- public override string Id => "values" ;
22+ public Version Version => Definition . Version ;
7323
7424 /// <inheritdoc/>
75- public ResoniteModBase Owner => _definition . Owner ;
25+ public ISet < ModConfigurationKey > ConfigurationItemDefinitions => Definition . ConfigurationItemDefinitions ;
7626
7727 /// <inheritdoc/>
78- public override Version Version => _definition . Version ;
28+ public ResoniteModBase Owner => Definition . Owner ;
7929
8030 internal ModConfiguration ( ModConfigurationDefinition definition )
8131 {
82- _definition = definition ;
83- }
84-
85- /// <inheritdoc/>
86- protected override IncompatibleConfigHandling HandleIncompatibleVersions ( Version serializedVersion )
87- {
88- if ( Owner is ResoniteMod resoniteMod )
89- return ( IncompatibleConfigHandling ) resoniteMod . HandleIncompatibleConfigurationVersions ( serializedVersion , Version ) ;
90-
91- return base . HandleIncompatibleVersions ( serializedVersion ) ;
32+ Definition = definition ;
33+ ConfigSection = new ( this ) ;
9234 }
9335
9436 /// <summary>
@@ -97,7 +39,8 @@ protected override IncompatibleConfigHandling HandleIncompatibleVersions(Version
9739 /// <param name="key">The key to get the value for.</param>
9840 /// <returns>The value for the key.</returns>
9941 /// <exception cref="KeyNotFoundException">The given key does not exist in the configuration.</exception>
100- public object GetValue ( ModConfigurationKey key ) => GetDefinedKey ( key . UntypedKey ) . GetValue ( ) ! ;
42+ public object GetValue ( ModConfigurationKey key )
43+ => ConfigSection . GetDefinedKey ( key . UntypedKey ) . GetValue ( ) ! ;
10144
10245 /// <summary>
10346 /// Get a value, throwing a <see cref="KeyNotFoundException"/> if the key is not found.
@@ -106,14 +49,16 @@ protected override IncompatibleConfigHandling HandleIncompatibleVersions(Version
10649 /// <param name="key">The key to get the value for.</param>
10750 /// <returns>The value for the key.</returns>
10851 /// <exception cref="KeyNotFoundException">The given key does not exist in the configuration.</exception>
109- public T ? GetValue < T > ( ModConfigurationKey < T > key ) => GetDefinedKey ( key . Key ) . GetValue ( ) ;
52+ public T ? GetValue < T > ( ModConfigurationKey < T > key )
53+ => ConfigSection . GetDefinedKey ( key . Key ) . GetValue ( ) ;
11054
11155 /// <summary>
11256 /// Checks if the given key is defined in this config.
11357 /// </summary>
11458 /// <param name="key">The key to check.</param>
11559 /// <returns><c>true</c> if the key is defined.</returns>
116- public bool IsKeyDefined ( ModConfigurationKey key ) => TryGetDefinedKey ( key . UntypedKey , out _ ) ;
60+ public bool IsKeyDefined ( ModConfigurationKey key )
61+ => ConfigSection . TryGetDefinedKey ( key . UntypedKey , out _ ) ;
11762
11863 /// <summary>
11964 /// Persist this configuration to disk.<br/>
@@ -125,7 +70,8 @@ protected override IncompatibleConfigHandling HandleIncompatibleVersions(Version
12570 /// </remarks>
12671#pragma warning disable IDE0060 // Remove unused parameter
12772
128- public void Save ( bool saveDefaultValues = false ) => Config . Save ( ) ;
73+ public void Save ( bool saveDefaultValues = false )
74+ => ConfigSection . Config . Save ( ) ;
12975
13076#pragma warning restore IDE0060 // Remove unused parameter
13177
@@ -139,7 +85,7 @@ protected override IncompatibleConfigHandling HandleIncompatibleVersions(Version
13985 /// <exception cref="KeyNotFoundException">The given key does not exist in the configuration.</exception>
14086 /// <exception cref="ArgumentException">The new value is not valid for the given key.</exception>
14187 public void Set ( ModConfigurationKey key , object ? value , string ? eventLabel = null )
142- => GetDefinedKey ( key . UntypedKey ) . SetValue ( value , eventLabel ) ;
88+ => ConfigSection . GetDefinedKey ( key . UntypedKey ) . SetValue ( value , eventLabel ) ;
14389
14490 /// <summary>
14591 /// Sets a configuration value for the given key, throwing a <see cref="KeyNotFoundException"/> if the key is not found
@@ -152,7 +98,7 @@ public void Set(ModConfigurationKey key, object? value, string? eventLabel = nul
15298 /// <exception cref="KeyNotFoundException">The given key does not exist in the configuration.</exception>
15399 /// <exception cref="ArgumentException">The new value is not valid for the given key.</exception>
154100 public void Set < T > ( ModConfigurationKey < T > key , T value , string ? eventLabel = null )
155- => GetDefinedKey ( key . Key ) . SetValue ( value , eventLabel ) ;
101+ => ConfigSection . GetDefinedKey ( key . Key ) . SetValue ( value , eventLabel ) ;
156102
157103 /// <summary>
158104 /// Tries to get a value, returning <c>default</c> if the key is not found.
@@ -162,7 +108,7 @@ public void Set<T>(ModConfigurationKey<T> key, T value, string? eventLabel = nul
162108 /// <returns><c>true</c> if the value was read successfully.</returns>
163109 public bool TryGetValue ( ModConfigurationKey key , out object ? value )
164110 {
165- if ( TryGetDefinedKey ( key . UntypedKey , out var definingKey ) )
111+ if ( ConfigSection . TryGetDefinedKey ( key . UntypedKey , out var definingKey ) )
166112 {
167113 value = definingKey . GetValue ( ) ;
168114 return true ;
@@ -180,7 +126,7 @@ public bool TryGetValue(ModConfigurationKey key, out object? value)
180126 /// <returns><c>true</c> if the value was read successfully.</returns>
181127 public bool TryGetValue < T > ( ModConfigurationKey < T > key , out T ? value )
182128 {
183- if ( TryGetDefinedKey ( key . Key , out var definingKey ) )
129+ if ( ConfigSection . TryGetDefinedKey ( key . Key , out var definingKey ) )
184130 {
185131 value = definingKey . GetValue ( ) ;
186132 return true ;
@@ -196,7 +142,8 @@ public bool TryGetValue<T>(ModConfigurationKey<T> key, out T? value)
196142 /// <param name="key">The key to remove the value for.</param>
197143 /// <returns><c>true</c> if a value was successfully found and removed, <c>false</c> if there was no value to remove.</returns>
198144 /// <exception cref="KeyNotFoundException">The given key does not exist in the configuration.</exception>
199- public bool Unset ( ModConfigurationKey key ) => GetDefinedKey ( key . UntypedKey ) . Unset ( ) ;
145+ public bool Unset ( ModConfigurationKey key )
146+ => ConfigSection . GetDefinedKey ( key . UntypedKey ) . Unset ( ) ;
200147
201148 internal void FireConfigurationChangedEvent ( ModConfigurationKey key , string ? label )
202149 {
@@ -208,7 +155,7 @@ internal void FireConfigurationChangedEvent(ModConfigurationKey key, string? lab
208155 }
209156 catch ( AggregateException ex )
210157 {
211- Config . Logger . Error ( ( ) => ex . Format ( $ "An OnAnyConfigurationChanged event subscriber threw an exception:") ) ;
158+ ConfigSection . Config . Logger . Error ( ( ) => ex . Format ( $ "An OnAnyConfigurationChanged event subscriber threw an exception:") ) ;
212159 }
213160
214161 try
@@ -217,14 +164,10 @@ internal void FireConfigurationChangedEvent(ModConfigurationKey key, string? lab
217164 }
218165 catch ( AggregateException ex )
219166 {
220- Config . Logger . Error ( ( ) => ex . Format ( $ "An OnThisConfigurationChanged event subscriber threw an exception:") ) ;
167+ ConfigSection . Config . Logger . Error ( ( ) => ex . Format ( $ "An OnThisConfigurationChanged event subscriber threw an exception:") ) ;
221168 }
222169 }
223170
224- /// <inheritdoc/>
225- protected override IEnumerable < IDefiningConfigKey > GetConfigKeys ( )
226- => _definition . ConfigurationItemDefinitions . Select ( item => item . UntypedKey ) ;
227-
228171 /// <summary>
229172 /// Called if any config value for any mod changed.
230173 /// </summary>
@@ -241,39 +184,4 @@ protected override IEnumerable<IDefiningConfigKey> GetConfigKeys()
241184 /// </summary>
242185 public event ConfigurationChangedHandler ? OnThisConfigurationChanged ;
243186 }
244-
245- /// <summary>
246- /// Defines a mod configuration. This should be defined by a <see cref="ResoniteMod"/> using the <see cref="ResoniteMod.DefineConfiguration(ModConfigurationDefinitionBuilder)"/> method.
247- /// </summary>
248- public class ModConfigurationDefinition : IModConfigurationDefinition
249- {
250- internal readonly HashSet < ModConfigurationKey > ConfigurationItems ;
251- internal bool AutoSave ;
252-
253- /// <inheritdoc/>
254- // clone the collection because I don't trust giving public API users shallow copies one bit
255- public ISet < ModConfigurationKey > ConfigurationItemDefinitions
256- => new HashSet < ModConfigurationKey > ( ConfigurationItems ) ;
257-
258- /// <inheritdoc/>
259- public ResoniteModBase Owner { get ; private set ; }
260-
261- /// <inheritdoc/>
262- public Version Version { get ; private set ; }
263-
264- /// <summary>
265- /// Creates a new <see cref="ModConfiguration"/> definition.
266- /// </summary>
267- /// <param name="owner">The mod owning the config.</param>
268- /// <param name="configVersion">The version of the config.</param>
269- /// <param name="keys">The config keys for the config.</param>
270- /// <param name="autoSaveConfig">Whether to automatically save the config.</param>
271- public ModConfigurationDefinition ( ResoniteModBase owner , Version configVersion , HashSet < ModConfigurationKey > keys , bool autoSaveConfig )
272- {
273- Owner = owner ;
274- Version = configVersion ;
275- ConfigurationItems = [ .. keys ] ;
276- AutoSave = autoSaveConfig ;
277- }
278- }
279187}
0 commit comments