Skip to content

Commit c3113e5

Browse files
committed
Add thread-safe static cache for ConfigFile instances
- Introduced a static list `AllConfigFiles` to cache all `ConfigFile` instances created during runtime. - Exposed a read-only `AllConfigFilesReadOnly` property of type `IReadOnlyList<ConfigFile>` for external read-only access. - Synchronized all access to `AllConfigFiles` using a dedicated `lock` object (`LockObject`) to ensure thread safety. - Ensured consistent access to the `AllConfigFiles` collection, preventing race conditions and concurrent modification issues. - Updated XML documentation to reflect changes and provide additional usage guidelines for `AllConfigFilesReadOnly`.
1 parent 5b32500 commit c3113e5

File tree

2 files changed

+48
-1
lines changed

2 files changed

+48
-1
lines changed

Assets/CoreLibPackage/CoreLib/Scripts/Util/Data/ConfigFile/ConfigFile.cs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,48 @@ namespace CoreLib.Data.Configuration
1515
/// </summary>
1616
public class ConfigFile : IDictionary<ConfigDefinition, ConfigEntryBase>
1717
{
18+
/// <summary>
19+
/// A private static list that contains all <see cref="ConfigFile"/> instances created throughout the application's lifetime.
20+
/// This list should only be modified internally by the <see cref="ConfigFile"/> class.
21+
/// </summary>
22+
private static readonly List<ConfigFile> AllConfigFiles = new List<ConfigFile>();
23+
24+
/// <summary>
25+
/// An object used for locking access to the <see cref="AllConfigFiles"/> collection to ensure thread safety.
26+
/// </summary>
27+
private static readonly object LockObject = new object();
28+
29+
/// <summary>
30+
/// A read-only view of the static list containing all <see cref="ConfigFile"/> instances created throughout the application's lifetime.
31+
/// <para>
32+
/// This property provides read-only access to the list of configuration files. External callers can access this list to query
33+
/// existing configuration files but cannot modify the list, ensuring data integrity.
34+
/// </para>
35+
/// <example>
36+
/// The following example demonstrates how to access all cached <see cref="ConfigFile"/> instances:
37+
/// <code>
38+
/// foreach (var config in ConfigFile.AllConfigFiles)
39+
/// {
40+
/// Console.WriteLine($"Config file path: {config.ConfigFilePath}");
41+
/// }
42+
/// </code>
43+
/// </example>
44+
/// </summary>
45+
/// <remarks>
46+
/// This property is thread-safe for read access. Any modifications to the internal collection should be done through the <see cref="AllConfigFiles"/> field.
47+
/// </remarks>
48+
public static IReadOnlyList<ConfigFile> AllConfigFilesReadOnly
49+
{
50+
get
51+
{
52+
lock (LockObject)
53+
{
54+
// Return a copy of the list to ensure thread safety.
55+
return AllConfigFiles.AsReadOnly();
56+
}
57+
}
58+
}
59+
1860
private readonly LoadedMod _ownerMetadata;
1961
private static Encoding UTF8NoBom { get; } = new UTF8Encoding(false);
2062

@@ -33,6 +75,11 @@ public ConfigFile(string configPath, bool saveOnInit, LoadedMod ownerMetadata)
3375

3476
ConfigFilePath = configPath ?? throw new ArgumentNullException(nameof(configPath));
3577

78+
lock (LockObject)
79+
{
80+
AllConfigFiles.Add(this);
81+
}
82+
3683
if (API.ConfigFilesystem.FileExists(ConfigFilePath))
3784
Reload();
3885
else if (saveOnInit) Save();

Assets/Plugins/CoreKeeper.meta

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)