- ConfigService.cs alpha testing.
This commit is contained in:
@@ -1,103 +0,0 @@
|
||||
using System;
|
||||
using System.Xml.Linq;
|
||||
using Barotrauma.LuaCs.Data;
|
||||
using Barotrauma.LuaCs.Services;
|
||||
using Barotrauma.Networking;
|
||||
using OneOf;
|
||||
|
||||
namespace Barotrauma.LuaCs.Configuration;
|
||||
|
||||
public class ConfigEntry<T> : IConfigEntry<T> where T : IEquatable<T>
|
||||
{
|
||||
|
||||
private readonly Action<ConfigEntry<T>, INetReadMessage> _readMessageHandler;
|
||||
private readonly Action<ConfigEntry<T>, INetWriteMessage> _writeMessageHandler;
|
||||
|
||||
public ConfigEntry(IConfigInfo configInfo, Action<ConfigEntry<T>, INetReadMessage> readMessageHandler,
|
||||
Action<ConfigEntry<T>, INetWriteMessage> writeMessageHandler)
|
||||
{
|
||||
_readMessageHandler = readMessageHandler;
|
||||
_writeMessageHandler = writeMessageHandler;
|
||||
}
|
||||
|
||||
public string InternalName { get; init; }
|
||||
public ContentPackage OwnerPackage { get; init; }
|
||||
|
||||
public bool Equals(IConfigBase other)
|
||||
{
|
||||
if (ReferenceEquals(this, other))
|
||||
return true;
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Type GetValueType()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public string GetValue()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public bool TrySetValue(OneOf<string, XElement> value)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public bool IsAssignable(OneOf<string, XElement> value)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private event Action<IConfigEntry<T>> _onValueChanged;
|
||||
public event Action<IConfigEntry<T>> OnValueChanged
|
||||
{
|
||||
add => _onValueChanged += value;
|
||||
remove => _onValueChanged -= value;
|
||||
}
|
||||
|
||||
event Action<IConfigBase> IConfigBase.OnValueChanged
|
||||
{
|
||||
add => _onValueChanged += value;
|
||||
remove => _onValueChanged -= value;
|
||||
}
|
||||
|
||||
public OneOf<string, XElement> GetSerializableValue()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Guid InstanceId => throw new NotImplementedException();
|
||||
|
||||
public NetSync SyncType => throw new NotImplementedException();
|
||||
|
||||
public ClientPermissions WritePermissions => throw new NotImplementedException();
|
||||
|
||||
public void ReadNetMessage(INetReadMessage message)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void WriteNetMessage(INetWriteMessage message)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public T Value => throw new NotImplementedException();
|
||||
|
||||
public bool TrySetValue(T value)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public bool IsAssignable(T value)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
@@ -1,111 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Xml.Linq;
|
||||
using Barotrauma.LuaCs.Data;
|
||||
using Barotrauma.LuaCs.Services;
|
||||
using Barotrauma.Networking;
|
||||
using OneOf;
|
||||
|
||||
namespace Barotrauma.LuaCs.Configuration;
|
||||
|
||||
public class ConfigList<T> : IConfigList<T> where T : IEquatable<T>
|
||||
{
|
||||
private readonly Action<ConfigList<T>, INetReadMessage> _readMessageHandler;
|
||||
private readonly Action<ConfigList<T>, INetWriteMessage> _writeMessageHandler;
|
||||
|
||||
public ConfigList(IConfigInfo configInfo, Action<ConfigList<T>, INetReadMessage> readMessageHandler,
|
||||
Action<ConfigList<T>, INetWriteMessage> writeMessageHandler)
|
||||
{
|
||||
_readMessageHandler = readMessageHandler;
|
||||
_writeMessageHandler = writeMessageHandler;
|
||||
}
|
||||
|
||||
public string InternalName => throw new NotImplementedException();
|
||||
|
||||
public ContentPackage OwnerPackage => throw new NotImplementedException();
|
||||
|
||||
public bool Equals(IConfigBase other)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Type GetValueType()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public string GetValue()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public bool TrySetValue(OneOf<string, XElement> value)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public bool IsAssignable(OneOf<string, XElement> value)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private event Action<IConfigList<T>> _onValueChanged;
|
||||
|
||||
public event Action<IConfigList<T>> OnValueChanged
|
||||
{
|
||||
add => _onValueChanged += value;
|
||||
remove => _onValueChanged -= value;
|
||||
}
|
||||
|
||||
event Action<IConfigEntry<T>> IConfigEntry<T>.OnValueChanged
|
||||
{
|
||||
add => _onValueChanged += value;
|
||||
remove => _onValueChanged -= value;
|
||||
}
|
||||
|
||||
event Action<IConfigBase> IConfigBase.OnValueChanged
|
||||
{
|
||||
add => _onValueChanged += value;
|
||||
remove => _onValueChanged -= value;
|
||||
}
|
||||
|
||||
public T Value => throw new NotImplementedException();
|
||||
|
||||
public bool TrySetValue(T value)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public bool IsAssignable(T value)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public OneOf<string, XElement> GetSerializableValue()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Guid InstanceId => throw new NotImplementedException();
|
||||
|
||||
public NetSync SyncType => throw new NotImplementedException();
|
||||
|
||||
public ClientPermissions WritePermissions => throw new NotImplementedException();
|
||||
|
||||
public void ReadNetMessage(INetReadMessage message)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void WriteNetMessage(INetWriteMessage message)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public IReadOnlyList<T> Options => throw new NotImplementedException();
|
||||
}
|
||||
+4
-3
@@ -6,12 +6,13 @@ using Barotrauma.Networking;
|
||||
|
||||
namespace Barotrauma.LuaCs.Configuration;
|
||||
|
||||
public partial interface IConfigBase : IDataInfo, IEquatable<IConfigBase>, IDisposable
|
||||
public partial interface ISettingBase : IDataInfo, IEquatable<ISettingBase>, IDisposable
|
||||
{
|
||||
Type GetValueType();
|
||||
string GetValue();
|
||||
string GetStringValue();
|
||||
bool TrySetValue(OneOf.OneOf<string, XElement> value);
|
||||
bool IsAssignable(OneOf.OneOf<string, XElement> value);
|
||||
event Action<IConfigBase> OnValueChanged;
|
||||
event Func<OneOf.OneOf<string, XElement>, bool> IsNewValueValid;
|
||||
event Action<ISettingBase> OnValueChanged;
|
||||
OneOf.OneOf<string, XElement> GetSerializableValue();
|
||||
}
|
||||
+2
-2
@@ -3,10 +3,10 @@ using Barotrauma.LuaCs.Services;
|
||||
|
||||
namespace Barotrauma.LuaCs.Configuration;
|
||||
|
||||
public interface IConfigEntry<T> : IConfigBase, INetworkSyncEntity where T : IEquatable<T>
|
||||
public interface ISettingEntry<T> : ISettingBase, INetworkSyncEntity where T : IEquatable<T>
|
||||
{
|
||||
T Value { get; }
|
||||
bool TrySetValue(T value);
|
||||
bool IsAssignable(T value);
|
||||
new event Action<IConfigEntry<T>> OnValueChanged;
|
||||
new event Action<ISettingEntry<T>> OnValueChanged;
|
||||
}
|
||||
+1
-1
@@ -3,7 +3,7 @@ using Barotrauma.LuaCs.Services;
|
||||
|
||||
namespace Barotrauma.LuaCs.Configuration;
|
||||
|
||||
public interface IConfigEnum : IConfigBase, INetworkSyncEntity
|
||||
public interface ISettingEnum : ISettingBase, INetworkSyncEntity
|
||||
{
|
||||
|
||||
}
|
||||
+2
-2
@@ -4,8 +4,8 @@ using Barotrauma.LuaCs.Services;
|
||||
|
||||
namespace Barotrauma.LuaCs.Configuration;
|
||||
|
||||
public interface IConfigList<T> : IConfigEntry<T>, INetworkSyncEntity where T : IEquatable<T>
|
||||
public interface ISettingList<T> : ISettingEntry<T>, INetworkSyncEntity where T : IEquatable<T>
|
||||
{
|
||||
IReadOnlyList<T> Options { get; }
|
||||
new event Action<IConfigList<T>> OnValueChanged;
|
||||
new event Action<ISettingList<T>> OnValueChanged;
|
||||
}
|
||||
+1
-1
@@ -2,7 +2,7 @@ using System;
|
||||
|
||||
namespace Barotrauma.LuaCs.Configuration;
|
||||
|
||||
public interface IConfigRangeEntry<T> : IConfigEntry<T> where T : IConvertible, IEquatable<T>
|
||||
public interface ISettingRangeEntry<T> : ISettingEntry<T> where T : IConvertible, IEquatable<T>
|
||||
{
|
||||
T MinValue { get; }
|
||||
T MaxValue { get; }
|
||||
@@ -0,0 +1,85 @@
|
||||
using System;
|
||||
using System.Xml.Linq;
|
||||
using Barotrauma.LuaCs.Data;
|
||||
using Barotrauma.LuaCs.Services;
|
||||
using Barotrauma.Networking;
|
||||
using OneOf;
|
||||
|
||||
namespace Barotrauma.LuaCs.Configuration;
|
||||
|
||||
public class SettingEntry<T> : ISettingEntry<T> where T : IEquatable<T>
|
||||
{
|
||||
public string InternalName { get; }
|
||||
public ContentPackage OwnerPackage { get; }
|
||||
public bool Equals(ISettingBase other)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Type GetValueType()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public string GetStringValue()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public bool TrySetValue(OneOf<string, XElement> value)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public bool IsAssignable(OneOf<string, XElement> value)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public event Func<OneOf<string, XElement>, bool> IsNewValueValid;
|
||||
public T Value { get; }
|
||||
public bool TrySetValue(T value)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public bool IsAssignable(T value)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
event Action<ISettingEntry<T>> ISettingEntry<T>.OnValueChanged
|
||||
{
|
||||
add => throw new NotImplementedException();
|
||||
remove => throw new NotImplementedException();
|
||||
}
|
||||
|
||||
event Action<ISettingBase> ISettingBase.OnValueChanged
|
||||
{
|
||||
add => throw new NotImplementedException();
|
||||
remove => throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public OneOf<string, XElement> GetSerializableValue()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Guid InstanceId { get; }
|
||||
public NetSync SyncType { get; }
|
||||
public ClientPermissions WritePermissions { get; }
|
||||
public void ReadNetMessage(INetReadMessage message)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void WriteNetMessage(INetWriteMessage message)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Xml.Linq;
|
||||
using Barotrauma.LuaCs.Data;
|
||||
using Barotrauma.LuaCs.Services;
|
||||
using Barotrauma.Networking;
|
||||
using OneOf;
|
||||
|
||||
namespace Barotrauma.LuaCs.Configuration;
|
||||
|
||||
public class SettingList<T> : ISettingList<T> where T : IEquatable<T>
|
||||
{
|
||||
public string InternalName { get; }
|
||||
public ContentPackage OwnerPackage { get; }
|
||||
public bool Equals(ISettingBase other)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Type GetValueType()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public string GetStringValue()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public bool TrySetValue(OneOf<string, XElement> value)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public bool IsAssignable(OneOf<string, XElement> value)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public event Func<OneOf<string, XElement>, bool> IsNewValueValid;
|
||||
public T Value { get; }
|
||||
public bool TrySetValue(T value)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public bool IsAssignable(T value)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
event Action<ISettingList<T>> ISettingList<T>.OnValueChanged
|
||||
{
|
||||
add => throw new NotImplementedException();
|
||||
remove => throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public IReadOnlyList<T> Options { get; }
|
||||
|
||||
event Action<ISettingEntry<T>> ISettingEntry<T>.OnValueChanged
|
||||
{
|
||||
add => throw new NotImplementedException();
|
||||
remove => throw new NotImplementedException();
|
||||
}
|
||||
|
||||
event Action<ISettingBase> ISettingBase.OnValueChanged
|
||||
{
|
||||
add => throw new NotImplementedException();
|
||||
remove => throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public OneOf<string, XElement> GetSerializableValue()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Guid InstanceId { get; }
|
||||
public NetSync SyncType { get; }
|
||||
public ClientPermissions WritePermissions { get; }
|
||||
public void ReadNetMessage(INetReadMessage message)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void WriteNetMessage(INetWriteMessage message)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
@@ -67,9 +67,8 @@ public record ConfigInfo : IConfigInfo
|
||||
{
|
||||
public string InternalName { get; init; }
|
||||
public ContentPackage OwnerPackage { get; init; }
|
||||
public Type DataType { get; init; }
|
||||
public OneOf<string, XElement> DefaultValue { get; init; }
|
||||
public OneOf<string, XElement> Value { get; init; }
|
||||
public string DataType { get; init; }
|
||||
public XElement Element { get; init; }
|
||||
public RunState EditableStates { get; init; }
|
||||
public NetSync NetSync { get; init; }
|
||||
|
||||
@@ -79,7 +78,7 @@ public record ConfigInfo : IConfigInfo
|
||||
public string DisplayCategory { get; init; }
|
||||
public bool ShowInMenus { get; init; }
|
||||
public string Tooltip { get; init; }
|
||||
public string ImageIconPath { get; init; }
|
||||
public ContentPath ImageIconPath { get; init; }
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -87,7 +86,7 @@ public record ConfigProfileInfo : IConfigProfileInfo
|
||||
{
|
||||
public string InternalName { get; init; }
|
||||
public ContentPackage OwnerPackage { get; init; }
|
||||
public IReadOnlyList<(string ConfigName, OneOf<string, XElement> Value)> ProfileValues { get; init; }
|
||||
public IReadOnlyList<(string ConfigName, XElement Element)> ProfileValues { get; init; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -13,26 +13,18 @@ public partial interface IConfigInfo : IDataInfo
|
||||
/// <summary>
|
||||
/// Specifies the type initializer that will be used to instantiate the config var.
|
||||
/// </summary>
|
||||
Type DataType { get; }
|
||||
string DataType { get; }
|
||||
/// <summary>
|
||||
/// The default value.
|
||||
/// The 'Setting' XML element.
|
||||
/// </summary>
|
||||
OneOf.OneOf<string, XElement> DefaultValue { get; }
|
||||
/// <summary>
|
||||
/// The value the last time this config was saved. If not found, returns the default value.
|
||||
/// <br/><b>[If(Type='<see cref="string"/>')]</b><br/>
|
||||
/// The value is from the 'Value' Attribute. Typically used for types with single/simple values, such as primitives.
|
||||
/// <br/><b>[If(Type='<see cref="XElement"/>')]</b><br/>
|
||||
/// The value is from the first 'Value' child element. Typically used with complex config types, such as range and list.
|
||||
/// </summary>
|
||||
OneOf.OneOf<string, XElement> Value { get; }
|
||||
XElement Element { get; }
|
||||
/// <summary>
|
||||
/// In what <see cref="RunState"/>(s) is this config editable. Will be editable in the selected state, and lower value states.
|
||||
/// <br/><br/>
|
||||
/// <b>[Important]</b><br/> Setting this to value lower than 'Configuration` will render this config read-only.
|
||||
/// <br/><br/><b>Expected Behaviour</b>:
|
||||
/// <br/><b>[<see cref="RunState.Unloaded"/>|<see cref="RunState.Parsed"/>]</b>: Read-Only.
|
||||
/// <br/><b>[<see cref="RunState.Configuration"/>]</b>: Can only be changed at the Main Menu (not in a lobby).
|
||||
/// <br/><b>[<see cref="RunState.Unloaded"/>|<see cref="RunState.Unloaded"/>]</b>: Read-Only.
|
||||
/// <br/><b>[<see cref="RunState.LoadedNoExec"/>]</b>: Can only be changed at the Main Menu (not in a lobby).
|
||||
/// <br/><b>[<see cref="RunState.Running"/>]</b>: Can be changed at the Main Menu and while a lobby is active.
|
||||
/// </summary>
|
||||
RunState EditableStates { get; }
|
||||
|
||||
@@ -5,5 +5,5 @@ namespace Barotrauma.LuaCs.Data;
|
||||
|
||||
public interface IConfigProfileInfo : IDataInfo
|
||||
{
|
||||
IReadOnlyList<(string ConfigName, OneOf.OneOf<string, XElement> Value)> ProfileValues { get; }
|
||||
IReadOnlyList<(string ConfigName, XElement Element)> ProfileValues { get; }
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ public interface IEvent<out T> : IEvent where T : IEvent<T>
|
||||
}
|
||||
}
|
||||
|
||||
#region RuntimeEvents
|
||||
#region RuntimeServiceEvents
|
||||
|
||||
/// <summary>
|
||||
/// Called when the current <see cref="Screen"/> (game state) changes. Upstream Type 'Screen' is internal.
|
||||
@@ -61,6 +61,12 @@ internal interface IEventReloadAllPackages : IEvent<IEventReloadAllPackages>
|
||||
void OnReloadAllPackages();
|
||||
}
|
||||
|
||||
internal interface IEventSettingInstanceLifetime : IEvent<IEventSettingInstanceLifetime>
|
||||
{
|
||||
void OnSettingInstanceCreated<T>(T configInstance) where T : ISettingBase;
|
||||
void OnSettingInstanceDisposed<T>(T configInstance) where T : ISettingBase;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region GameEvents
|
||||
|
||||
@@ -99,56 +99,56 @@ namespace Barotrauma
|
||||
/// <summary>
|
||||
/// Whether C# plugin code is enabled.
|
||||
/// </summary>
|
||||
internal IConfigEntry<bool> IsCsEnabled { get; private set; }
|
||||
internal ISettingEntry<bool> IsCsEnabled { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether mods marked as 'forced' or 'always load' should only be loaded if they're in the enabled mods list.
|
||||
/// </summary>
|
||||
internal IConfigEntry<bool> TreatForcedModsAsNormal { get; private set; }
|
||||
internal ISettingEntry<bool> TreatForcedModsAsNormal { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether the lua script runner from Workshop package should be used over the in-built version.
|
||||
/// </summary>
|
||||
internal IConfigEntry<bool> PreferToUseWorkshopLuaSetup { get; private set; }
|
||||
internal ISettingEntry<bool> PreferToUseWorkshopLuaSetup { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether the popup error GUI should be hidden/suppressed.
|
||||
/// </summary>
|
||||
internal IConfigEntry<bool> DisableErrorGUIOverlay { get; private set; }
|
||||
internal ISettingEntry<bool> DisableErrorGUIOverlay { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether usernames are anonymized or show in logs.
|
||||
/// </summary>
|
||||
internal IConfigEntry<bool> HideUserNamesInLogs { get; private set; }
|
||||
internal ISettingEntry<bool> HideUserNamesInLogs { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The SteamId of the Workshop LuaCs CPackage in use, if available.
|
||||
/// </summary>
|
||||
internal IConfigEntry<ulong> LuaForBarotraumaSteamId { get; private set; }
|
||||
internal ISettingEntry<ulong> LuaForBarotraumaSteamId { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// TODO: @evilfactory@users.noreply.github.com
|
||||
/// </summary>
|
||||
internal IConfigEntry<bool> RestrictMessageSize { get; private set; }
|
||||
internal ISettingEntry<bool> RestrictMessageSize { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The local save path for all local data storage for mods.
|
||||
/// </summary>
|
||||
internal IConfigEntry<string> LocalDataSavePath { get; private set; }
|
||||
internal ISettingEntry<string> LocalDataSavePath { get; private set; }
|
||||
|
||||
void LoadLuaCsConfig()
|
||||
{
|
||||
IsCsEnabled = ConfigService.TryGetConfig<IConfigEntry<bool>>(ContentPackageManager.VanillaCorePackage, "IsCsEnabled", out var val1) ? val1
|
||||
IsCsEnabled = ConfigService.TryGetConfig<ISettingEntry<bool>>(ContentPackageManager.VanillaCorePackage, "IsCsEnabled", out var val1) ? val1
|
||||
: throw new NullReferenceException($"{nameof(IsCsEnabled)} cannot be loaded.");
|
||||
TreatForcedModsAsNormal = ConfigService.TryGetConfig<IConfigEntry<bool>>(ContentPackageManager.VanillaCorePackage, "TreatForcedModsAsNormal", out var val2) ? val2
|
||||
TreatForcedModsAsNormal = ConfigService.TryGetConfig<ISettingEntry<bool>>(ContentPackageManager.VanillaCorePackage, "TreatForcedModsAsNormal", out var val2) ? val2
|
||||
: throw new NullReferenceException($"{nameof(TreatForcedModsAsNormal)} cannot be loaded.");
|
||||
DisableErrorGUIOverlay = ConfigService.TryGetConfig<IConfigEntry<bool>>(ContentPackageManager.VanillaCorePackage, "DisableErrorGUIOverlay", out var val3) ? val3
|
||||
DisableErrorGUIOverlay = ConfigService.TryGetConfig<ISettingEntry<bool>>(ContentPackageManager.VanillaCorePackage, "DisableErrorGUIOverlay", out var val3) ? val3
|
||||
: throw new NullReferenceException($"{nameof(DisableErrorGUIOverlay)} cannot be loaded.");
|
||||
HideUserNamesInLogs = ConfigService.TryGetConfig<IConfigEntry<bool>>(ContentPackageManager.VanillaCorePackage, "HideUserNamesInLogs", out var val4) ? val4
|
||||
HideUserNamesInLogs = ConfigService.TryGetConfig<ISettingEntry<bool>>(ContentPackageManager.VanillaCorePackage, "HideUserNamesInLogs", out var val4) ? val4
|
||||
: throw new NullReferenceException($"{nameof(HideUserNamesInLogs)} cannot be loaded.");
|
||||
LuaForBarotraumaSteamId = ConfigService.TryGetConfig<IConfigEntry<ulong>>(ContentPackageManager.VanillaCorePackage, "LuaForBarotraumaSteamId", out var val5) ? val5
|
||||
LuaForBarotraumaSteamId = ConfigService.TryGetConfig<ISettingEntry<ulong>>(ContentPackageManager.VanillaCorePackage, "LuaForBarotraumaSteamId", out var val5) ? val5
|
||||
: throw new NullReferenceException($"{nameof(LuaForBarotraumaSteamId)} cannot be loaded.");
|
||||
RestrictMessageSize = ConfigService.TryGetConfig<IConfigEntry<bool>>(ContentPackageManager.VanillaCorePackage, "RestrictMessageSize", out var val7) ? val7
|
||||
RestrictMessageSize = ConfigService.TryGetConfig<ISettingEntry<bool>>(ContentPackageManager.VanillaCorePackage, "RestrictMessageSize", out var val7) ? val7
|
||||
: throw new NullReferenceException($"{nameof(RestrictMessageSize)} cannot be loaded.");
|
||||
}
|
||||
|
||||
@@ -170,9 +170,11 @@ namespace Barotrauma
|
||||
// TODO: INetworkingService
|
||||
servicesProvider.RegisterServiceType<IConfigService, ConfigService>(ServiceLifetime.Singleton);
|
||||
servicesProvider.RegisterServiceType<IModConfigService, ModConfigService>(ServiceLifetime.Transient);
|
||||
servicesProvider.RegisterServiceType<IParserServiceAsync<ResourceParserInfo, IAssemblyResourceInfo>, ConfigFileParserService>(ServiceLifetime.Transient);
|
||||
servicesProvider.RegisterServiceType<IParserServiceAsync<ResourceParserInfo, ILuaScriptResourceInfo>, ConfigFileParserService>(ServiceLifetime.Transient);
|
||||
servicesProvider.RegisterServiceType<IParserServiceAsync<ResourceParserInfo, IConfigResourceInfo>, ConfigFileParserService>(ServiceLifetime.Transient);
|
||||
servicesProvider.RegisterServiceType<IParserServiceAsync<ResourceParserInfo, IAssemblyResourceInfo>, ModConfigFileParserService>(ServiceLifetime.Transient);
|
||||
servicesProvider.RegisterServiceType<IParserServiceAsync<ResourceParserInfo, ILuaScriptResourceInfo>, ModConfigFileParserService>(ServiceLifetime.Transient);
|
||||
servicesProvider.RegisterServiceType<IParserServiceAsync<ResourceParserInfo, IConfigResourceInfo>, ModConfigFileParserService>(ServiceLifetime.Transient);
|
||||
servicesProvider.RegisterServiceType<IParserServiceOneToManyAsync<IConfigResourceInfo, IConfigInfo>, SettingsFileParserService>(ServiceLifetime.Transient);
|
||||
servicesProvider.RegisterServiceType<IParserServiceOneToManyAsync<IConfigResourceInfo, IConfigProfileInfo>, SettingsFileParserService>(ServiceLifetime.Transient);
|
||||
// service config data
|
||||
servicesProvider.RegisterServiceType<IStorageServiceConfig, StorageServiceConfig>(ServiceLifetime.Singleton);
|
||||
servicesProvider.RegisterServiceType<ILuaScriptServicesConfig, LuaScriptServicesConfig>(ServiceLifetime.Singleton);
|
||||
|
||||
@@ -26,37 +26,19 @@ public class ConfigInitializers : IService
|
||||
// stateless service
|
||||
public bool IsDisposed => false;
|
||||
|
||||
private Result<IConfigEntry<T>> CreateConfigEntry<T>(IConfigInfo configInfo,
|
||||
Action<ConfigEntry<T>, INetReadMessage> readHandler,
|
||||
Action<ConfigEntry<T>, INetWriteMessage> writeHandler)
|
||||
private Result<ISettingEntry<T>> CreateConfigEntry<T>(IConfigInfo configInfo,
|
||||
Action<SettingEntry<T>, INetReadMessage> readHandler,
|
||||
Action<SettingEntry<T>, INetWriteMessage> writeHandler)
|
||||
where T : IEquatable<T>
|
||||
{
|
||||
try
|
||||
{
|
||||
var ice = new ConfigEntry<T>(configInfo, readHandler, writeHandler);
|
||||
return FluentResults.Result.Ok<IConfigEntry<T>>(ice);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return FluentResults.Result.Fail($"Error while initializing config var: {configInfo?.OwnerPackage} - {configInfo?.InternalName}")
|
||||
.WithError(new ExceptionalError(e));
|
||||
}
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private Result<IConfigList<T>> CreateConfigList<T>(IConfigInfo configInfo,
|
||||
Action<IConfigList<T>, INetReadMessage> readHandler, Action<IConfigList<T>, INetWriteMessage> writeHandler)
|
||||
private Result<ISettingList<T>> CreateConfigList<T>(IConfigInfo configInfo,
|
||||
Action<ISettingList<T>, INetReadMessage> readHandler, Action<ISettingList<T>, INetWriteMessage> writeHandler)
|
||||
where T : IEquatable<T>
|
||||
{
|
||||
try
|
||||
{
|
||||
var icl = new ConfigList<T>(configInfo, readHandler, writeHandler);
|
||||
return FluentResults.Result.Ok<IConfigList<T>>(icl);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return FluentResults.Result.Fail($"Error while initializing config var: {configInfo?.OwnerPackage} - {configInfo?.InternalName}")
|
||||
.WithError(new ExceptionalError(e));
|
||||
}
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void RegisterTypeInitializers(IConfigService configService)
|
||||
@@ -64,30 +46,30 @@ public class ConfigInitializers : IService
|
||||
if (configService == null)
|
||||
throw new ArgumentNullException($"{nameof(RegisterTypeInitializers)}: {nameof(IConfigService)} is null.");
|
||||
|
||||
configService.RegisterTypeInitializer<bool, IConfigEntry<bool>>(this.CreateConfigBool);
|
||||
configService.RegisterTypeInitializer<sbyte, IConfigEntry<sbyte>>(this.CreateConfigSbyte);
|
||||
configService.RegisterTypeInitializer<byte, IConfigEntry<byte>>(this.CreateConfigByte);
|
||||
configService.RegisterTypeInitializer<short, IConfigEntry<short>>(this.CreateConfigShort);
|
||||
configService.RegisterTypeInitializer<ushort, IConfigEntry<ushort>>(this.CreateConfigUShort);
|
||||
configService.RegisterTypeInitializer<int, IConfigEntry<int>>(this.CreateConfigInt32);
|
||||
configService.RegisterTypeInitializer<uint, IConfigEntry<uint>>(this.CreateConfigUInt32);
|
||||
configService.RegisterTypeInitializer<long, IConfigEntry<long>>(this.CreateConfigInt64);
|
||||
configService.RegisterTypeInitializer<ulong, IConfigEntry<ulong>>(this.CreateConfigUInt64);
|
||||
configService.RegisterTypeInitializer<float, IConfigEntry<float>>(this.CreateConfigFloat32);
|
||||
configService.RegisterTypeInitializer<double, IConfigEntry<double>>(this.CreateConfigFloat64);
|
||||
configService.RegisterTypeInitializer<decimal, IConfigEntry<decimal>>(this.CreateConfigFloat128);
|
||||
configService.RegisterTypeInitializer<char, IConfigEntry<char>>(this.CreateConfigChar);
|
||||
configService.RegisterTypeInitializer<string, IConfigEntry<string>>(this.CreateConfigString);
|
||||
configService.RegisterTypeInitializer<Color, IConfigEntry<Color>>(this.CreateConfigColor);
|
||||
configService.RegisterTypeInitializer<Vector2, IConfigEntry<Vector2>>(this.CreateConfigVector2);
|
||||
configService.RegisterTypeInitializer<Vector3, IConfigEntry<Vector3>>(this.CreateConfigVector3);
|
||||
configService.RegisterTypeInitializer<Vector4, IConfigEntry<Vector4>>(this.CreateConfigVector4);
|
||||
/*configService.RegisterTypeInitializer<bool, ISettingEntry<bool>>(this.CreateConfigBool);
|
||||
configService.RegisterTypeInitializer<sbyte, ISettingEntry<sbyte>>(this.CreateConfigSbyte);
|
||||
configService.RegisterTypeInitializer<byte, ISettingEntry<byte>>(this.CreateConfigByte);
|
||||
configService.RegisterTypeInitializer<short, ISettingEntry<short>>(this.CreateConfigShort);
|
||||
configService.RegisterTypeInitializer<ushort, ISettingEntry<ushort>>(this.CreateConfigUShort);
|
||||
configService.RegisterTypeInitializer<int, ISettingEntry<int>>(this.CreateConfigInt32);
|
||||
configService.RegisterTypeInitializer<uint, ISettingEntry<uint>>(this.CreateConfigUInt32);
|
||||
configService.RegisterTypeInitializer<long, ISettingEntry<long>>(this.CreateConfigInt64);
|
||||
configService.RegisterTypeInitializer<ulong, ISettingEntry<ulong>>(this.CreateConfigUInt64);
|
||||
configService.RegisterTypeInitializer<float, ISettingEntry<float>>(this.CreateConfigFloat32);
|
||||
configService.RegisterTypeInitializer<double, ISettingEntry<double>>(this.CreateConfigFloat64);
|
||||
configService.RegisterTypeInitializer<decimal, ISettingEntry<decimal>>(this.CreateConfigFloat128);
|
||||
configService.RegisterTypeInitializer<char, ISettingEntry<char>>(this.CreateConfigChar);
|
||||
configService.RegisterTypeInitializer<string, ISettingEntry<string>>(this.CreateConfigString);
|
||||
configService.RegisterTypeInitializer<Color, ISettingEntry<Color>>(this.CreateConfigColor);
|
||||
configService.RegisterTypeInitializer<Vector2, ISettingEntry<Vector2>>(this.CreateConfigVector2);
|
||||
configService.RegisterTypeInitializer<Vector3, ISettingEntry<Vector3>>(this.CreateConfigVector3);
|
||||
configService.RegisterTypeInitializer<Vector4, ISettingEntry<Vector4>>(this.CreateConfigVector4);*/
|
||||
}
|
||||
|
||||
|
||||
#region InitializerWrappers_NetworkInjected
|
||||
|
||||
private void AssignValueConditional<T>(T val, IConfigEntry<T> inst) where T : IEquatable<T>
|
||||
private void AssignValueConditional<T>(T val, ISettingEntry<T> inst) where T : IEquatable<T>
|
||||
{
|
||||
#if SERVER
|
||||
if (inst.SyncType is NetSync.None or NetSync.ServerAuthority)
|
||||
@@ -100,7 +82,7 @@ public class ConfigInitializers : IService
|
||||
#endif
|
||||
}
|
||||
|
||||
private Result<IConfigEntry<bool>> CreateConfigBool(IConfigInfo configInfo)
|
||||
private Result<ISettingEntry<bool>> CreateConfigBool(IConfigInfo configInfo)
|
||||
{
|
||||
return CreateConfigEntry<bool>(configInfo, (inst, readMsg) =>
|
||||
{
|
||||
@@ -112,7 +94,7 @@ public class ConfigInitializers : IService
|
||||
});
|
||||
}
|
||||
|
||||
private Result<IConfigEntry<sbyte>> CreateConfigSbyte(IConfigInfo configInfo)
|
||||
private Result<ISettingEntry<sbyte>> CreateConfigSbyte(IConfigInfo configInfo)
|
||||
{
|
||||
return CreateConfigEntry<sbyte>(configInfo, (inst, readMsg) =>
|
||||
{
|
||||
@@ -124,7 +106,7 @@ public class ConfigInitializers : IService
|
||||
});
|
||||
}
|
||||
|
||||
private Result<IConfigEntry<byte>> CreateConfigByte(IConfigInfo configInfo)
|
||||
private Result<ISettingEntry<byte>> CreateConfigByte(IConfigInfo configInfo)
|
||||
{
|
||||
return CreateConfigEntry<byte>(configInfo, (inst, readMsg) =>
|
||||
{
|
||||
@@ -136,7 +118,7 @@ public class ConfigInitializers : IService
|
||||
});
|
||||
}
|
||||
|
||||
private Result<IConfigEntry<short>> CreateConfigShort(IConfigInfo configInfo)
|
||||
private Result<ISettingEntry<short>> CreateConfigShort(IConfigInfo configInfo)
|
||||
{
|
||||
return CreateConfigEntry<short>(configInfo, (inst, readMsg) =>
|
||||
{
|
||||
@@ -148,7 +130,7 @@ public class ConfigInitializers : IService
|
||||
});
|
||||
}
|
||||
|
||||
private Result<IConfigEntry<ushort>> CreateConfigUShort(IConfigInfo configInfo)
|
||||
private Result<ISettingEntry<ushort>> CreateConfigUShort(IConfigInfo configInfo)
|
||||
{
|
||||
return CreateConfigEntry<ushort>(configInfo, (inst, readMsg) =>
|
||||
{
|
||||
@@ -160,7 +142,7 @@ public class ConfigInitializers : IService
|
||||
});
|
||||
}
|
||||
|
||||
private Result<IConfigEntry<int>> CreateConfigInt32(IConfigInfo configInfo)
|
||||
private Result<ISettingEntry<int>> CreateConfigInt32(IConfigInfo configInfo)
|
||||
{
|
||||
return CreateConfigEntry<int>(configInfo, (inst, readMsg) =>
|
||||
{
|
||||
@@ -172,7 +154,7 @@ public class ConfigInitializers : IService
|
||||
});
|
||||
}
|
||||
|
||||
private Result<IConfigEntry<uint>> CreateConfigUInt32(IConfigInfo configInfo)
|
||||
private Result<ISettingEntry<uint>> CreateConfigUInt32(IConfigInfo configInfo)
|
||||
{
|
||||
return CreateConfigEntry<uint>(configInfo, (inst, readMsg) =>
|
||||
{
|
||||
@@ -184,7 +166,7 @@ public class ConfigInitializers : IService
|
||||
});
|
||||
}
|
||||
|
||||
private Result<IConfigEntry<long>> CreateConfigInt64(IConfigInfo configInfo)
|
||||
private Result<ISettingEntry<long>> CreateConfigInt64(IConfigInfo configInfo)
|
||||
{
|
||||
return CreateConfigEntry<long>(configInfo, (inst, readMsg) =>
|
||||
{
|
||||
@@ -196,7 +178,7 @@ public class ConfigInitializers : IService
|
||||
});
|
||||
}
|
||||
|
||||
private Result<IConfigEntry<ulong>> CreateConfigUInt64(IConfigInfo configInfo)
|
||||
private Result<ISettingEntry<ulong>> CreateConfigUInt64(IConfigInfo configInfo)
|
||||
{
|
||||
return CreateConfigEntry<ulong>(configInfo, (inst, readMsg) =>
|
||||
{
|
||||
@@ -208,7 +190,7 @@ public class ConfigInitializers : IService
|
||||
});
|
||||
}
|
||||
|
||||
private Result<IConfigEntry<float>> CreateConfigFloat32(IConfigInfo configInfo)
|
||||
private Result<ISettingEntry<float>> CreateConfigFloat32(IConfigInfo configInfo)
|
||||
{
|
||||
return CreateConfigEntry<float>(configInfo, (inst, readMsg) =>
|
||||
{
|
||||
@@ -220,7 +202,7 @@ public class ConfigInitializers : IService
|
||||
});
|
||||
}
|
||||
|
||||
private Result<IConfigEntry<double>> CreateConfigFloat64(IConfigInfo configInfo)
|
||||
private Result<ISettingEntry<double>> CreateConfigFloat64(IConfigInfo configInfo)
|
||||
{
|
||||
return CreateConfigEntry<double>(configInfo, (inst, readMsg) =>
|
||||
{
|
||||
@@ -232,7 +214,7 @@ public class ConfigInitializers : IService
|
||||
});
|
||||
}
|
||||
|
||||
private Result<IConfigEntry<decimal>> CreateConfigFloat128(IConfigInfo configInfo)
|
||||
private Result<ISettingEntry<decimal>> CreateConfigFloat128(IConfigInfo configInfo)
|
||||
{
|
||||
return CreateConfigEntry<decimal>(configInfo, (inst, readMsg) =>
|
||||
{
|
||||
@@ -253,7 +235,7 @@ public class ConfigInitializers : IService
|
||||
});
|
||||
}
|
||||
|
||||
private Result<IConfigEntry<char>> CreateConfigChar(IConfigInfo configInfo)
|
||||
private Result<ISettingEntry<char>> CreateConfigChar(IConfigInfo configInfo)
|
||||
{
|
||||
return CreateConfigEntry<char>(configInfo, (inst, readMsg) =>
|
||||
{
|
||||
@@ -265,7 +247,7 @@ public class ConfigInitializers : IService
|
||||
});
|
||||
}
|
||||
|
||||
private Result<IConfigEntry<string>> CreateConfigString(IConfigInfo configInfo)
|
||||
private Result<ISettingEntry<string>> CreateConfigString(IConfigInfo configInfo)
|
||||
{
|
||||
return CreateConfigEntry<string>(configInfo, (inst, readMsg) =>
|
||||
{
|
||||
@@ -277,7 +259,7 @@ public class ConfigInitializers : IService
|
||||
});
|
||||
}
|
||||
|
||||
private Result<IConfigEntry<Color>> CreateConfigColor(IConfigInfo configInfo)
|
||||
private Result<ISettingEntry<Color>> CreateConfigColor(IConfigInfo configInfo)
|
||||
{
|
||||
return CreateConfigEntry<Color>(configInfo, (inst, readMsg) =>
|
||||
{
|
||||
@@ -289,7 +271,7 @@ public class ConfigInitializers : IService
|
||||
});
|
||||
}
|
||||
|
||||
private Result<IConfigEntry<Vector2>> CreateConfigVector2(IConfigInfo configInfo)
|
||||
private Result<ISettingEntry<Vector2>> CreateConfigVector2(IConfigInfo configInfo)
|
||||
{
|
||||
return CreateConfigEntry<Vector2>(configInfo, (inst, readMsg) =>
|
||||
{
|
||||
@@ -302,7 +284,7 @@ public class ConfigInitializers : IService
|
||||
});
|
||||
}
|
||||
|
||||
private Result<IConfigEntry<Vector3>> CreateConfigVector3(IConfigInfo configInfo)
|
||||
private Result<ISettingEntry<Vector3>> CreateConfigVector3(IConfigInfo configInfo)
|
||||
{
|
||||
return CreateConfigEntry<Vector3>(configInfo, (inst, readMsg) =>
|
||||
{
|
||||
@@ -316,7 +298,7 @@ public class ConfigInitializers : IService
|
||||
});
|
||||
}
|
||||
|
||||
private Result<IConfigEntry<Vector4>> CreateConfigVector4(IConfigInfo configInfo)
|
||||
private Result<ISettingEntry<Vector4>> CreateConfigVector4(IConfigInfo configInfo)
|
||||
{
|
||||
return CreateConfigEntry<Vector4>(configInfo, (inst, readMsg) =>
|
||||
{
|
||||
|
||||
@@ -6,217 +6,318 @@ using System.Collections.Immutable;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml.Linq;
|
||||
using Barotrauma.LuaCs.Configuration;
|
||||
using Barotrauma.LuaCs.Data;
|
||||
using Barotrauma.LuaCs.Events;
|
||||
using Barotrauma.LuaCs.Services.Processing;
|
||||
using Barotrauma.Networking;
|
||||
using Dynamitey.DynamicObjects;
|
||||
using FluentResults;
|
||||
using Microsoft.Xna.Framework;
|
||||
using OneOf;
|
||||
using Path = Barotrauma.IO.Path;
|
||||
using Microsoft.Toolkit.Diagnostics;
|
||||
|
||||
namespace Barotrauma.LuaCs.Services;
|
||||
|
||||
public partial class ConfigService : IConfigService
|
||||
public sealed partial class ConfigService : IConfigService
|
||||
{
|
||||
#region Disposal_Locks_Reset
|
||||
|
||||
private readonly AsyncReaderWriterLock _operationLock = new ();
|
||||
private readonly AsyncReaderWriterLock _settingsByPackageLock = new ();
|
||||
private int _isDisposed = 0;
|
||||
public bool IsDisposed
|
||||
{
|
||||
get => ModUtils.Threading.GetBool(ref _isDisposed);
|
||||
private set => ModUtils.Threading.SetBool(ref _isDisposed, value);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
using var lck = _operationLock.AcquireWriterLock().ConfigureAwait(false).GetAwaiter().GetResult();
|
||||
using var settingsLck = _settingsByPackageLock.AcquireWriterLock().ConfigureAwait(false).GetAwaiter().GetResult();
|
||||
if (!ModUtils.Threading.CheckIfClearAndSetBool(ref _isDisposed))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_logger.LogDebug($"{nameof(ConfigService)}: Disposing.");
|
||||
|
||||
_configInfoParserService.Dispose();
|
||||
_configProfileInfoParserService.Dispose();
|
||||
|
||||
public bool IsDisposed { get; }
|
||||
if (!_settingsInstances.IsEmpty)
|
||||
{
|
||||
foreach (var instance in _settingsInstances)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (instance.Value is null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
_eventService.PublishEvent<IEventSettingInstanceLifetime>(sub =>
|
||||
// ReSharper disable once AccessToDisposedClosure
|
||||
sub.OnSettingInstanceDisposed(instance.Value));
|
||||
instance.Value.Dispose();
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_settingsInstances.Clear();
|
||||
_instanceFactory.Clear();
|
||||
_settingsInstancesByPackage.Clear();
|
||||
|
||||
_storageService = null;
|
||||
_logger = null;
|
||||
_eventService = null;
|
||||
_configInfoParserService = null;
|
||||
_configProfileInfoParserService = null;
|
||||
}
|
||||
|
||||
public FluentResults.Result Reset()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
using var lck = _operationLock.AcquireWriterLock().ConfigureAwait(false).GetAwaiter().GetResult();
|
||||
IService.CheckDisposed(this);
|
||||
|
||||
var result = new FluentResults.Result();
|
||||
|
||||
if (!_settingsInstances.IsEmpty)
|
||||
{
|
||||
foreach (var instance in _settingsInstances)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (instance.Value is null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
#region LuaInterface
|
||||
_eventService.PublishEvent<IEventSettingInstanceLifetime>(sub =>
|
||||
// ReSharper disable once AccessToDisposedClosure
|
||||
sub.OnSettingInstanceDisposed(instance.Value));
|
||||
instance.Value.Dispose();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
result.WithError(new ExceptionalError(e));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_settingsInstances.Clear();
|
||||
_instanceFactory.Clear();
|
||||
_settingsInstancesByPackage.Clear();
|
||||
|
||||
public bool TryGetConfigBool(string packageName, string configName, out bool value)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
return result;
|
||||
}
|
||||
|
||||
public bool TryGetConfigInt(string packageName, string configName, out int value)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public bool TryGetConfigFloat(string packageName, string configName, out float value)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public bool TryGetConfigNumber(string packageName, string configName, out double value)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public bool TryGetConfigString(string packageName, string configName, out string value)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public bool TryGetConfigVector2(string packageName, string configName, out Vector2 value)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public bool TryGetConfigVector3(string packageName, string configName, out Vector3 value)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public bool TryGetConfigColor(string packageName, string configName, out Color value)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public bool TryGetConfigList(string packageName, string configName, out IReadOnlyList<string> value)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void SetConfigBool(string packageName, string configName, bool value)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void SetConfigInt(string packageName, string configName, int value)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void SetConfigFloat(string packageName, string configName, float value)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void SetConfigNumber(string packageName, string configName, double value)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void SetConfigString(string packageName, string configName, string value)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void SetConfigVector2(string packageName, string configName, Vector2 value)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void SetConfigVector3(string packageName, string configName, Vector3 value)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void SetConfigColor(string packageName, string configName, Color value)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void SetConfigList(string packageName, string configName, string value)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public bool TryApplyProfileSettings(string packageName, string profileName)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
public void RegisterTypeInitializer<TData, TConfig>(Func<IConfigInfo, Result<TConfig>> initializer, bool replaceIfExists = false) where TData : IEquatable<TData> where TConfig : IConfigBase
|
||||
private readonly ConcurrentDictionary<(ContentPackage OwnerPackage, string InternalName), ISettingBase>
|
||||
_settingsInstances = new();
|
||||
private readonly ConcurrentDictionary<string, Func<IConfigInfo, ISettingBase>>
|
||||
_instanceFactory = new();
|
||||
private readonly ConcurrentDictionary<ContentPackage, ConcurrentBag<ISettingBase>>
|
||||
_settingsInstancesByPackage = new();
|
||||
|
||||
private IStorageService _storageService;
|
||||
private ILoggerService _logger;
|
||||
private IEventService _eventService;
|
||||
private IParserServiceOneToManyAsync<IConfigResourceInfo, IConfigInfo> _configInfoParserService;
|
||||
private IParserServiceOneToManyAsync<IConfigResourceInfo, IConfigProfileInfo> _configProfileInfoParserService;
|
||||
|
||||
public ConfigService(ILoggerService logger,
|
||||
IStorageService storageService,
|
||||
IParserServiceOneToManyAsync<IConfigResourceInfo, IConfigInfo> configInfoParserService,
|
||||
IParserServiceOneToManyAsync<IConfigResourceInfo, IConfigProfileInfo> configProfileInfoParserService, IEventService eventService)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
_logger = logger;
|
||||
_storageService = storageService;
|
||||
_configInfoParserService = configInfoParserService;
|
||||
_configProfileInfoParserService = configProfileInfoParserService;
|
||||
_eventService = eventService;
|
||||
}
|
||||
|
||||
|
||||
public void RegisterSettingTypeInitializer<T>(string typeIdentifier, Func<IConfigInfo, T> settingFactory) where T : class, ISettingBase
|
||||
{
|
||||
Guard.IsNotNullOrWhiteSpace(typeIdentifier, nameof(typeIdentifier));
|
||||
Guard.IsNotNull(settingFactory, nameof(settingFactory));
|
||||
using var lck = _operationLock.AcquireReaderLock().ConfigureAwait(false).GetAwaiter().GetResult();
|
||||
IService.CheckDisposed(this);
|
||||
|
||||
if (_instanceFactory.ContainsKey(typeIdentifier))
|
||||
{
|
||||
ThrowHelper.ThrowArgumentException($"{nameof(RegisterSettingTypeInitializer)}: The type identifier {typeIdentifier} is already registered.");
|
||||
}
|
||||
|
||||
_instanceFactory[typeIdentifier] = settingFactory;
|
||||
}
|
||||
|
||||
public async Task<FluentResults.Result> LoadConfigsAsync(ImmutableArray<IConfigResourceInfo> configResources)
|
||||
{
|
||||
#if DEBUG
|
||||
return FluentResults.Result.Ok(); // just for startup testing
|
||||
#endif
|
||||
throw new NotImplementedException();
|
||||
using var lck = _operationLock.AcquireReaderLock().ConfigureAwait(false).GetAwaiter().GetResult();
|
||||
IService.CheckDisposed(this);
|
||||
if (configResources.IsDefaultOrEmpty)
|
||||
{
|
||||
return FluentResults.Result.Ok();
|
||||
}
|
||||
|
||||
var taskBuilder = ImmutableArray.CreateBuilder<Task<ImmutableArray<IConfigInfo>>>();
|
||||
var toProcessErrors = new ConcurrentStack<IError>();
|
||||
|
||||
var taskCtx = TaskScheduler.FromCurrentSynchronizationContext();
|
||||
|
||||
foreach (var resource in configResources)
|
||||
{
|
||||
taskBuilder.Add(await Task.Factory.StartNew<Task<ImmutableArray<IConfigInfo>>>(async Task<ImmutableArray<IConfigInfo>> () =>
|
||||
{
|
||||
var r = await _configInfoParserService.TryParseResourcesAsync(resource);
|
||||
if (r.IsFailed)
|
||||
{
|
||||
toProcessErrors.PushRange(r.Errors.ToArray());
|
||||
return ImmutableArray<IConfigInfo>.Empty;
|
||||
}
|
||||
return r.Value;
|
||||
}));
|
||||
}
|
||||
|
||||
var taskResults = await Task.WhenAll(taskBuilder.MoveToImmutable());
|
||||
|
||||
if (toProcessErrors.Count > 0)
|
||||
{
|
||||
return FluentResults.Result.Fail($"{nameof(LoadConfigsAsync)}: Errors while loading configuration info: ").WithErrors(toProcessErrors.ToArray());
|
||||
}
|
||||
|
||||
var toProcessDocs = taskResults
|
||||
.Where(tr => !tr.IsDefaultOrEmpty)
|
||||
.SelectMany(tr => tr)
|
||||
.ToImmutableArray();
|
||||
|
||||
var instanceQueue = new Queue<(IConfigInfo configInfo, Func<IConfigInfo, ISettingBase> factory)>();
|
||||
|
||||
foreach (var info in toProcessDocs)
|
||||
{
|
||||
if (!_instanceFactory.TryGetValue(info.DataType, out var factory))
|
||||
{
|
||||
return FluentResults.Result.Fail($"{nameof(LoadConfigsAsync)}: Could not retrieve the instance factory for the data type of '{info.DataType}'!");
|
||||
}
|
||||
if (_settingsInstances.ContainsKey((info.OwnerPackage, info.InternalName)))
|
||||
{
|
||||
// duplicate for some reason (ie. double loading). This should never happen.
|
||||
ThrowHelper.ThrowInvalidOperationException($"{nameof(LoadConfigsAsync)}: A setting for the [ContentPackage].[InternalName] of '[{info.OwnerPackage.Name}].[{info.InternalName}]' already exists!");
|
||||
}
|
||||
|
||||
instanceQueue.Enqueue((info, factory));
|
||||
}
|
||||
|
||||
var toProcessInstanceQueue = new Queue<(IConfigInfo info, ISettingBase instance)>();
|
||||
|
||||
while (instanceQueue.TryDequeue(out var instanceFactoryInfo))
|
||||
{
|
||||
try
|
||||
{
|
||||
toProcessInstanceQueue.Enqueue((instanceFactoryInfo.configInfo, instanceFactoryInfo.factory(instanceFactoryInfo.configInfo)));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
FluentResults.Result.Fail(
|
||||
$"{nameof(LoadConfigsAsync)}: Error while instancing setting for '{instanceFactoryInfo.configInfo.OwnerPackage}.{instanceFactoryInfo.configInfo.InternalName}': {e.Message}!");
|
||||
}
|
||||
}
|
||||
|
||||
using var settingsLck = await _settingsByPackageLock.AcquireWriterLock(); // block to protect new bag instance creation
|
||||
var result = new FluentResults.Result();
|
||||
|
||||
while (toProcessInstanceQueue.TryDequeue(out var newInstanceData))
|
||||
{
|
||||
_settingsInstances[(newInstanceData.info.OwnerPackage, newInstanceData.info.InternalName)] = newInstanceData.instance;
|
||||
if (!_settingsInstancesByPackage.TryGetValue(newInstanceData.info.OwnerPackage, out _))
|
||||
{
|
||||
_settingsInstancesByPackage[newInstanceData.info.OwnerPackage] = new ConcurrentBag<ISettingBase>();
|
||||
}
|
||||
_settingsInstancesByPackage[newInstanceData.info.OwnerPackage].Add(newInstanceData.instance);
|
||||
result.WithReasons(_eventService.PublishEvent<IEventSettingInstanceLifetime>(sub =>
|
||||
sub.OnSettingInstanceCreated(newInstanceData.instance)).Reasons);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task<FluentResults.Result> LoadConfigsProfilesAsync(ImmutableArray<IConfigResourceInfo> configProfileResources)
|
||||
{
|
||||
#if DEBUG
|
||||
return FluentResults.Result.Ok(); // just for startup testing
|
||||
// TODO: Implement profiles.
|
||||
return FluentResults.Result.Ok();
|
||||
#endif
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Result<TConfig> AddConfig<TConfig>(IConfigInfo configInfo) where TConfig : IConfigBase
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public FluentResults.Result ApplyProfileSettings(ContentPackage package, string profileName)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public FluentResults.Result DisposePackageData(ContentPackage package)
|
||||
{
|
||||
#if DEBUG
|
||||
return FluentResults.Result.Ok(); // just for startup testing
|
||||
#endif
|
||||
throw new NotImplementedException();
|
||||
Guard.IsNotNull(package, nameof(package));
|
||||
using var lck = _operationLock.AcquireReaderLock().ConfigureAwait(false).GetAwaiter().GetResult();
|
||||
ConcurrentBag<ISettingBase> toDispose;
|
||||
using (var settingsLck = _settingsByPackageLock.AcquireWriterLock().ConfigureAwait(false).GetAwaiter().GetResult())
|
||||
{
|
||||
if (!_settingsInstancesByPackage.TryRemove(package, out toDispose) || toDispose is null)
|
||||
{
|
||||
return FluentResults.Result.Ok();
|
||||
}
|
||||
}
|
||||
|
||||
var result = new FluentResults.Result();
|
||||
|
||||
foreach (var setting in toDispose)
|
||||
{
|
||||
result.WithReasons(_eventService.PublishEvent<IEventSettingInstanceLifetime>(sub => sub.OnSettingInstanceDisposed(setting)).Reasons);
|
||||
try
|
||||
{
|
||||
setting.Dispose();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
result.WithError(new ExceptionalError(e));
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public FluentResults.Result DisposeAllPackageData()
|
||||
{
|
||||
#if DEBUG
|
||||
return FluentResults.Result.Ok(); // just for startup testing
|
||||
#endif
|
||||
throw new NotImplementedException();
|
||||
return this.Reset();
|
||||
}
|
||||
|
||||
public Result<IReadOnlyDictionary<(ContentPackage Package, string ConfigName), IConfigBase>> GetConfigsForPackage(ContentPackage package)
|
||||
public bool TryGetConfig<T>(ContentPackage package, string internalName, out T instance) where T : ISettingBase
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
Guard.IsNotNull(package, nameof(package));
|
||||
Guard.IsNotNullOrWhiteSpace(internalName, nameof(internalName));
|
||||
using var lck = _operationLock.AcquireReaderLock().ConfigureAwait(false).GetAwaiter().GetResult();
|
||||
using var settingsLck =
|
||||
_settingsByPackageLock.AcquireReaderLock().ConfigureAwait(false).GetAwaiter().GetResult();
|
||||
IService.CheckDisposed(this);
|
||||
|
||||
instance = default;
|
||||
|
||||
if(!_settingsInstances.TryGetValue((package, internalName), out var inst))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public Result<IReadOnlyDictionary<(ContentPackage Package, string ConfigName), ImmutableArray<(string ConfigName, OneOf<string, XElement> Value)>>> GetProfilesForPackage(ContentPackage package)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public IReadOnlyDictionary<(ContentPackage Package, string Name), IConfigBase> GetAllConfigs()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public bool TryGetConfig<T>(ContentPackage package, string name, out T config) where T : IConfigBase
|
||||
{
|
||||
#if DEBUG
|
||||
config = default(T);
|
||||
return true; // just for startup testing
|
||||
#endif
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public async Task<FluentResults.Result> SaveAllConfigs()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public async Task<FluentResults.Result> SaveConfigsForPackage(ContentPackage package)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public async Task<FluentResults.Result> SaveConfig((ContentPackage Package, string ConfigName) config)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
if (inst is not T instanceT)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
instance = instanceT;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -325,6 +325,9 @@ public class EventService : IEventService, IEventAssemblyContextUnloading
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
#if DEBUG
|
||||
throw; //make errors apparent
|
||||
#endif
|
||||
errors.Enqueue(new Error($"Error while executing runner for {eventType.Name} on type {eventSub.GetType().Name}.")
|
||||
.WithMetadata(MetadataType.ExceptionObject, this)
|
||||
.WithMetadata(MetadataType.RootObject, eventSub)
|
||||
|
||||
+5
@@ -18,3 +18,8 @@ public interface IParserServiceAsync<in TSrc, TOut> : IService
|
||||
Task<Result<TOut>> TryParseResourceAsync(TSrc src);
|
||||
Task<ImmutableArray<Result<TOut>>> TryParseResourcesAsync(IEnumerable<TSrc> sources);
|
||||
}
|
||||
|
||||
public interface IParserServiceOneToManyAsync<in TSrc, TOut> : IService
|
||||
{
|
||||
Task<Result<ImmutableArray<TOut>>> TryParseResourcesAsync(TSrc src);
|
||||
}
|
||||
|
||||
+2
-2
@@ -10,7 +10,7 @@ using Microsoft.Toolkit.Diagnostics;
|
||||
|
||||
namespace Barotrauma.LuaCs.Services.Processing;
|
||||
|
||||
public sealed class ConfigFileParserService :
|
||||
public sealed class ModConfigFileParserService :
|
||||
IParserServiceAsync<ResourceParserInfo, IAssemblyResourceInfo>,
|
||||
IParserServiceAsync<ResourceParserInfo, ILuaScriptResourceInfo>,
|
||||
IParserServiceAsync<ResourceParserInfo, IConfigResourceInfo>
|
||||
@@ -18,7 +18,7 @@ public sealed class ConfigFileParserService :
|
||||
private IStorageService _storageService;
|
||||
private readonly AsyncReaderWriterLock _operationsLock = new();
|
||||
|
||||
public ConfigFileParserService(IStorageService storageService)
|
||||
public ModConfigFileParserService(IStorageService storageService)
|
||||
{
|
||||
_storageService = storageService;
|
||||
}
|
||||
+212
@@ -0,0 +1,212 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml.Linq;
|
||||
using Barotrauma.LuaCs.Data;
|
||||
using FluentResults;
|
||||
using Microsoft.Toolkit.Diagnostics;
|
||||
using OneOf;
|
||||
|
||||
namespace Barotrauma.LuaCs.Services.Processing;
|
||||
|
||||
public sealed class SettingsFileParserService :
|
||||
IParserServiceOneToManyAsync<IConfigResourceInfo, IConfigInfo>,
|
||||
IParserServiceOneToManyAsync<IConfigResourceInfo, IConfigProfileInfo>
|
||||
{
|
||||
#region DisposalControl
|
||||
|
||||
private AsyncReaderWriterLock _operationLock = new();
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
using var lck = _operationLock.AcquireWriterLock().ConfigureAwait(false).GetAwaiter().GetResult();
|
||||
if (!ModUtils.Threading.CheckIfClearAndSetBool(ref _isDisposed))
|
||||
{
|
||||
return;
|
||||
}
|
||||
_storageService.Dispose();
|
||||
_storageService = null;
|
||||
}
|
||||
|
||||
private int _isDisposed = 0;
|
||||
public bool IsDisposed
|
||||
{
|
||||
get => ModUtils.Threading.GetBool(ref _isDisposed);
|
||||
private set => ModUtils.Threading.SetBool(ref _isDisposed, value);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private IStorageService _storageService;
|
||||
|
||||
public SettingsFileParserService(IStorageService storageService)
|
||||
{
|
||||
_storageService = storageService;
|
||||
}
|
||||
|
||||
async Task<Result<ImmutableArray<IConfigInfo>>> IParserServiceOneToManyAsync<IConfigResourceInfo, IConfigInfo>
|
||||
.TryParseResourcesAsync(IConfigResourceInfo src)
|
||||
{
|
||||
Guard.IsNotNull(src, nameof(src));
|
||||
Guard.IsNotNull(src.OwnerPackage, nameof(src.OwnerPackage));
|
||||
using var lck = await _operationLock.AcquireReaderLock();
|
||||
IService.CheckDisposed(this);
|
||||
|
||||
if (src.FilePaths.IsDefaultOrEmpty)
|
||||
{
|
||||
return ReturnFail($"The config file list is empty.");
|
||||
}
|
||||
|
||||
var parsedInfo = ImmutableArray.CreateBuilder<IConfigInfo>();
|
||||
|
||||
foreach ((ContentPath path, Result<XDocument> docLoadResult) res in await _storageService.LoadPackageXmlFilesAsync(src.FilePaths))
|
||||
{
|
||||
if (res.docLoadResult.IsFailed)
|
||||
{
|
||||
return ReturnFail($"Failed to load document for {src.OwnerPackage.Name}").WithErrors(res.docLoadResult.Errors);
|
||||
}
|
||||
|
||||
var settingElements = res.docLoadResult.Value.GetChildElement("Configuration")
|
||||
.GetChildElements("Settings").SelectMany(e => e.GetChildElements("Setting")).ToImmutableArray();
|
||||
if (settingElements.IsDefaultOrEmpty)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var packageIdent = res.path.ContentPackage.ToIdentifier().ToString();
|
||||
|
||||
foreach (var element in settingElements)
|
||||
{
|
||||
var name = element.GetAttributeString("Name", string.Empty);
|
||||
if (name.IsNullOrWhiteSpace())
|
||||
{
|
||||
return ReturnFail(
|
||||
$"The internal name for a setting in the config file '{res.path.FullPath}' is empty!");
|
||||
}
|
||||
|
||||
var newSetting = new ConfigInfo()
|
||||
{
|
||||
InternalName = name,
|
||||
OwnerPackage = res.path.ContentPackage,
|
||||
DataType = element.GetAttributeString("Type", string.Empty),
|
||||
Element = element,
|
||||
EditableStates = element.GetAttributeBool("AllowChangesWhileExecuting", true) ? RunState.Running :
|
||||
element.GetAttributeBool("ReadOnly", false) ? RunState.LoadedNoExec :
|
||||
RunState.Unloaded,
|
||||
NetSync = element.GetAttributeEnum("NetSync", NetSync.None),
|
||||
#if CLIENT
|
||||
DisplayName = $"{packageIdent}.{name}.DisplayName",
|
||||
Description = $"{packageIdent}.{name}.Description",
|
||||
DisplayCategory = $"{packageIdent}.{name}.DisplayCategory",
|
||||
ShowInMenus = element.GetAttributeBool("ShowInMenus", true),
|
||||
Tooltip = $"{packageIdent}.{name}.Tooltip",
|
||||
ImageIconPath = element.GetAttributeString("ImageIcon", string.Empty) is {} val && !val.IsNullOrWhiteSpace() ?
|
||||
ContentPath.FromRaw(res.path.ContentPackage, val) : ContentPath.Empty
|
||||
#endif
|
||||
};
|
||||
if (!IsInfoValid(newSetting))
|
||||
{
|
||||
return ReturnFail($"A setting was invalid. ContentPackage: {res.path.ContentPackage}");
|
||||
}
|
||||
parsedInfo.Add(newSetting);
|
||||
}
|
||||
}
|
||||
|
||||
return FluentResults.Result.Ok(parsedInfo.MoveToImmutable());
|
||||
|
||||
// Helpers
|
||||
|
||||
FluentResults.Result ReturnFail(string msg)
|
||||
{
|
||||
return FluentResults.Result.Fail($"{nameof(IParserServiceOneToManyAsync<IConfigResourceInfo, IConfigInfo>.TryParseResourcesAsync)}: {msg}");
|
||||
}
|
||||
|
||||
bool IsInfoValid(ConfigInfo info)
|
||||
{
|
||||
return info.OwnerPackage != null
|
||||
&& !info.InternalName.IsNullOrWhiteSpace()
|
||||
&& !info.DataType.IsNullOrWhiteSpace()
|
||||
&& !info.DataType.IsNullOrWhiteSpace()
|
||||
&& info.Element != null
|
||||
#if CLIENT
|
||||
&& !info.DisplayName.IsNullOrWhiteSpace()
|
||||
&& !info.Description.IsNullOrWhiteSpace()
|
||||
&& !info.DisplayCategory.IsNullOrWhiteSpace()
|
||||
&& !info.Tooltip.IsNullOrWhiteSpace()
|
||||
#endif
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
async Task<Result<ImmutableArray<IConfigProfileInfo>>>
|
||||
IParserServiceOneToManyAsync<IConfigResourceInfo, IConfigProfileInfo>
|
||||
.TryParseResourcesAsync(IConfigResourceInfo src)
|
||||
{
|
||||
Guard.IsNotNull(src, nameof(src));
|
||||
Guard.IsNotNull(src.OwnerPackage, nameof(src.OwnerPackage));
|
||||
using var lck = await _operationLock.AcquireReaderLock();
|
||||
IService.CheckDisposed(this);
|
||||
|
||||
if (src.FilePaths.IsDefaultOrEmpty)
|
||||
{
|
||||
return ReturnFail($"The config file list is empty.");
|
||||
}
|
||||
|
||||
var parsedInfo = ImmutableArray.CreateBuilder<IConfigProfileInfo>();
|
||||
|
||||
foreach ((ContentPath path, Result<XDocument> docLoadResult) res in await _storageService
|
||||
.LoadPackageXmlFilesAsync(src.FilePaths))
|
||||
{
|
||||
if (res.docLoadResult.IsFailed)
|
||||
{
|
||||
return ReturnFail($"Failed to load document for {src.OwnerPackage.Name}")
|
||||
.WithErrors(res.docLoadResult.Errors);
|
||||
}
|
||||
|
||||
var profileCollection = res.docLoadResult.Value.GetChildElement("Configuration")
|
||||
.GetChildElement("Profiles");
|
||||
if (profileCollection == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach (var profile in profileCollection.GetChildElements("Profile"))
|
||||
{
|
||||
var profileName = profile.GetAttributeString("Name", string.Empty);
|
||||
Guard.IsNotNullOrWhiteSpace(profileName, nameof(profileName));
|
||||
|
||||
var settingValues = profile.GetChildElements("SettingValue").ToImmutableArray();
|
||||
if (settingValues.IsDefaultOrEmpty)
|
||||
{
|
||||
ThrowHelper.ThrowArgumentNullException(nameof(settingValues));
|
||||
}
|
||||
|
||||
var profileValuesBuilder = ImmutableArray.CreateBuilder<(string ConfigName, XElement Value)>();
|
||||
|
||||
foreach (var settingValue in settingValues)
|
||||
{
|
||||
var cfgName = settingValue.GetAttributeString("Name", string.Empty);
|
||||
Guard.IsNotNullOrWhiteSpace(cfgName, nameof(cfgName));
|
||||
profileValuesBuilder.Add((cfgName, settingValue));
|
||||
}
|
||||
|
||||
parsedInfo.Add(new ConfigProfileInfo()
|
||||
{
|
||||
InternalName = profileName,
|
||||
OwnerPackage = res.path.ContentPackage,
|
||||
ProfileValues = profileValuesBuilder.MoveToImmutable()
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return parsedInfo.MoveToImmutable();
|
||||
|
||||
FluentResults.Result ReturnFail(string msg)
|
||||
{
|
||||
return FluentResults.Result.Fail($"{nameof(IParserServiceOneToManyAsync<IConfigResourceInfo, IConfigProfileInfo>.TryParseResourcesAsync)}: {msg}");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -6,27 +6,5 @@ namespace Barotrauma.LuaCs.Services.Safe;
|
||||
|
||||
public interface ILuaConfigService : ILuaService
|
||||
{
|
||||
// get values
|
||||
bool TryGetConfigBool(string packageName, string configName, out bool value);
|
||||
bool TryGetConfigInt(string packageName, string configName, out int value);
|
||||
bool TryGetConfigFloat(string packageName, string configName, out float value);
|
||||
bool TryGetConfigNumber(string packageName, string configName, out double value);
|
||||
bool TryGetConfigString(string packageName, string configName, out string value);
|
||||
bool TryGetConfigVector2(string packageName, string configName, out Vector2 value);
|
||||
bool TryGetConfigVector3(string packageName, string configName, out Vector3 value);
|
||||
bool TryGetConfigColor(string packageName, string configName, out Color value);
|
||||
bool TryGetConfigList(string packageName, string configName, out IReadOnlyList<string> value);
|
||||
// set values
|
||||
void SetConfigBool(string packageName, string configName, bool value);
|
||||
void SetConfigInt(string packageName, string configName, int value);
|
||||
void SetConfigFloat(string packageName, string configName, float value);
|
||||
void SetConfigNumber(string packageName, string configName, double value);
|
||||
void SetConfigString(string packageName, string configName, string value);
|
||||
void SetConfigVector2(string packageName, string configName, Vector2 value);
|
||||
void SetConfigVector3(string packageName, string configName, Vector3 value);
|
||||
void SetConfigColor(string packageName, string configName, Color value);
|
||||
void SetConfigList(string packageName, string configName, string value);
|
||||
// profiles
|
||||
bool TryApplyProfileSettings(string packageName, string profileName);
|
||||
|
||||
|
||||
}
|
||||
|
||||
+8
-23
@@ -15,33 +15,18 @@ namespace Barotrauma.LuaCs.Services;
|
||||
|
||||
public partial interface IConfigService : IReusableService, ILuaConfigService
|
||||
{
|
||||
void RegisterSettingTypeInitializer<T>(string typeIdentifier, Func<IConfigInfo, T> settingFactory)
|
||||
where T : class, ISettingBase;
|
||||
/// <summary>
|
||||
/// Registers a type initializer from instancing config types by indicated type from config.
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="initializer"></param>
|
||||
/// <param name="replaceIfExists"></param>
|
||||
/// <typeparam name="TData">The <see cref="Type"/> as parsed from the configuration info.</typeparam>
|
||||
/// <typeparam name="TConfig">The resulting configuration instance.</typeparam>
|
||||
void RegisterTypeInitializer<TData, TConfig>(Func<IConfigInfo, FluentResults.Result<TConfig>> initializer, bool replaceIfExists = false)
|
||||
where TData : IEquatable<TData> where TConfig : IConfigBase;
|
||||
|
||||
// Config Files/Resources
|
||||
/// <param name="configResources"></param>
|
||||
/// <exception cref="ArgumentException"></exception>
|
||||
/// <exception cref="NullReferenceException"></exception>
|
||||
/// <returns></returns>
|
||||
Task<FluentResults.Result> LoadConfigsAsync(ImmutableArray<IConfigResourceInfo> configResources);
|
||||
Task<FluentResults.Result> LoadConfigsProfilesAsync(ImmutableArray<IConfigResourceInfo> configProfileResources);
|
||||
|
||||
// Immediate Mode
|
||||
FluentResults.Result<TConfig> AddConfig<TConfig>(IConfigInfo configInfo) where TConfig : IConfigBase;
|
||||
|
||||
// Utility
|
||||
FluentResults.Result ApplyProfileSettings(ContentPackage package, string profileName);
|
||||
FluentResults.Result DisposePackageData(ContentPackage package);
|
||||
FluentResults.Result DisposeAllPackageData();
|
||||
FluentResults.Result<IReadOnlyDictionary<(ContentPackage Package, string ConfigName), IConfigBase>> GetConfigsForPackage(ContentPackage package);
|
||||
FluentResults.Result<IReadOnlyDictionary<(ContentPackage Package, string ConfigName), ImmutableArray<(string ConfigName, OneOf.OneOf<string, XElement> Value)>>>
|
||||
GetProfilesForPackage(ContentPackage package);
|
||||
IReadOnlyDictionary<(ContentPackage Package, string Name), IConfigBase> GetAllConfigs();
|
||||
bool TryGetConfig<T>(ContentPackage package, string name, out T config) where T : IConfigBase;
|
||||
Task<FluentResults.Result> SaveAllConfigs();
|
||||
Task<FluentResults.Result> SaveConfigsForPackage(ContentPackage package);
|
||||
Task<FluentResults.Result> SaveConfig((ContentPackage Package, string ConfigName) config);
|
||||
bool TryGetConfig<T>(ContentPackage package, string internalName, out T instance) where T : ISettingBase;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user