diff --git a/Engine.Core/Config/BasicConfiguration.cs b/Engine.Core/Config/BasicConfiguration.cs new file mode 100644 index 0000000..9e8d2f1 --- /dev/null +++ b/Engine.Core/Config/BasicConfiguration.cs @@ -0,0 +1,50 @@ +using System.Collections.Generic; + +namespace Engine.Core.Config; + +public class BasicConfiguration : IConfiguration +{ + public Event OnAdded { get; } = new(); + public Event OnSet { get; } = new(); + public Event OnRemoved { get; } = new(); + + private readonly Dictionary values = []; + + public IReadOnlyDictionary Values => values; + + public T? Get(string key, T? defaultValue = default) + { + if (!values.TryGetValue(key, out object? value)) + return defaultValue; + + if (value is T castedObject) + return castedObject; + + try { return (T?)System.Convert.ChangeType(value, typeof(T)); } catch { } + + return defaultValue; + } + + public object? Get(string key) + { + values.TryGetValue(key, out object? value); + return value; + } + + public bool Has(string key) => values.ContainsKey(key); + + public void Remove(string key) + { + if (values.Remove(key)) + OnRemoved.Invoke(this, new(key)); + } + + public void Set(string key, T value) + { + if (!values.TryAdd(key, value)) + values[key] = value; + else + OnAdded.Invoke(this, new(key)); + OnSet.Invoke(this, new(key)); + } +} diff --git a/Engine.Core/Config/ConfigurationExtensions.cs b/Engine.Core/Config/ConfigurationExtensions.cs new file mode 100644 index 0000000..f83416f --- /dev/null +++ b/Engine.Core/Config/ConfigurationExtensions.cs @@ -0,0 +1,8 @@ +using Engine.Core.Exceptions; + +namespace Engine.Core.Config; + +public static class ConfigurationExtensions +{ + public static T GetRequired(this IConfiguration configuration, string key) => configuration.Get(key) ?? throw new NotFoundException($"Type of {typeof(T).FullName} with the key {key} was not present in the {configuration.GetType().FullName}"); +} diff --git a/Engine.Core/Config/IConfiguration.cs b/Engine.Core/Config/IConfiguration.cs new file mode 100644 index 0000000..0bd9dfe --- /dev/null +++ b/Engine.Core/Config/IConfiguration.cs @@ -0,0 +1,23 @@ +using System.Collections.Generic; + +namespace Engine.Core.Config; + +public interface IConfiguration +{ + static IConfiguration System { get; set; } = new SystemConfiguration(); + static IConfiguration Shared { get; set; } = new BasicConfiguration(); + + Event OnAdded { get; } + Event OnSet { get; } + Event OnRemoved { get; } + + IReadOnlyDictionary Values { get; } + + bool Has(string key); + object? Get(string key); + T? Get(string key, T? defaultValue = default); + void Set(string key, T value); + void Remove(string key); + + readonly record struct ConfigUpdateArguments(string Key); +} diff --git a/Engine.Core/Config/SystemConfiguration.cs b/Engine.Core/Config/SystemConfiguration.cs new file mode 100644 index 0000000..895b4bf --- /dev/null +++ b/Engine.Core/Config/SystemConfiguration.cs @@ -0,0 +1,11 @@ +namespace Engine.Core.Config; + +public class SystemConfiguration : BasicConfiguration, IConfiguration +{ + public SystemConfiguration() + { + foreach (System.Collections.DictionaryEntry entry in System.Environment.GetEnvironmentVariables()) + if (entry is { Key: string key, Value: not null }) + Set(key, entry.Value); + } +}