[Milestone] AssemblyLoader completed.
Details: - Assembly Mgmt Service for loading now a separate interface, not intended for normal use. - Assembly Loader work; implemented custom dictionary key and table. - Assembly loading work. - EventService completed. - Moved assembly extensions to ModUtils.cs - Work to event service. NetworkService work - Added ImpromptuInterfaces package. - Networking Service work to support NetVars - Event Service - Added assemblies references package for script compilation. Updated Roslyn version for compatibility. - Package Loading work. Swap Harmony to HarmonyX - More refactor conversion to FluentResults. - Updated StylesService to return Results. - Refactor of PackageService partially complete. - Made IService.Reset() required to return a Result. - Moved plugin/assembly related code to their own folder (same namespace). - Updated interfaces to reflect the use of Result<T>. - Partial refactor, incomplete. - Added 'FluentResults' so we can stop using cursed Exception-based flow control in loading code. - Added 'OneOf' nuget package: https://github.com/mcintyre321/OneOf for the implementation of the Optional<T> pattern and complex discrete return types instead of cursed enums (see current AssemblyManager.cs). - Reapplied old branch changes.
This commit is contained in:
+46
@@ -0,0 +1,46 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
// ReSharper disable InconsistentNaming
|
||||
|
||||
namespace Barotrauma.LuaCs.Services;
|
||||
|
||||
public interface IAssemblyManagementService : IReusableService
|
||||
{
|
||||
/// <summary>
|
||||
/// Searches for an assembly given it's fully qualified name, while excluding the contexts with the given Guids, if supplied.
|
||||
/// </summary>
|
||||
/// <param name="assemblyName">The fully-qualified assembly name.</param>
|
||||
/// <param name="excludedContexts">Guids of excluded contexts.</param>
|
||||
/// <returns><b>On Success:</b> The assembly. <br/><b>On Failure:</b> nothing.</returns>
|
||||
FluentResults.Result<Assembly> GetLoadedAssembly(string assemblyName, in Guid[] excludedContexts);
|
||||
/// <summary>
|
||||
/// Searches for an assembly given it's fully qualified name, while excluding the contexts with the given Guids, if supplied.
|
||||
/// </summary>
|
||||
/// <param name="assemblyName">The assembly info.</param>
|
||||
/// <param name="excludedContexts">Guids of excluded contexts.</param>
|
||||
/// <returns><b>On Success:</b> The assembly. <br/><b>On Failure:</b> nothing.</returns>
|
||||
FluentResults.Result<Assembly> GetLoadedAssembly(AssemblyName assemblyName, in Guid[] excludedContexts);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the assembly <see cref="MetadataReference"/> collection for the BCL and base game assemblies.
|
||||
/// </summary>
|
||||
/// <returns><see cref="MetadataReference"/> collection, if any are found. Returns an empty collection otherwise.</returns>
|
||||
ImmutableArray<MetadataReference> GetDefaultMetadataReferences();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the assembly <see cref="MetadataReference"/> collection for all add-in assemblies loaded.
|
||||
/// </summary>
|
||||
/// <returns><see cref="MetadataReference"/> collection, if any are found. Returns an empty collection otherwise.</returns>
|
||||
ImmutableArray<MetadataReference> GetAddInContextsMetadataReferences();
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
ImmutableArray<IAssemblyLoaderService> AssemblyLoaderServices { get; }
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Barotrauma.LuaCs.Configuration;
|
||||
using Barotrauma.LuaCs.Data;
|
||||
using Barotrauma.LuaCs.Networking;
|
||||
using Barotrauma.LuaCs.Services.Safe;
|
||||
using Barotrauma.Networking;
|
||||
|
||||
namespace Barotrauma.LuaCs.Services;
|
||||
|
||||
public partial interface IConfigService : IReusableService, ILuaConfigService
|
||||
{
|
||||
/*
|
||||
* Resource Files.
|
||||
*/
|
||||
FluentResults.Result AddConfigs(ImmutableArray<IConfigResourceInfo> configResources);
|
||||
FluentResults.Result AddConfigsProfiles(ImmutableArray<IConfigProfileResourceInfo> configProfileResources);
|
||||
FluentResults.Result RemoveConfigs(ImmutableArray<IConfigResourceInfo> configResources);
|
||||
FluentResults.Result RemoveConfigsProfiles(ImmutableArray<IConfigProfileResourceInfo> configProfilesResources);
|
||||
|
||||
|
||||
/*
|
||||
* From resources
|
||||
*/
|
||||
FluentResults.Result AddConfigs(ImmutableArray<IConfigInfo> configs);
|
||||
FluentResults.Result AddConfigsProfiles(ImmutableArray<IConfigProfileInfo> configProfiles);
|
||||
FluentResults.Result RemoveConfigs(ImmutableArray<IConfigInfo> configs);
|
||||
FluentResults.Result RemoveConfigsProfiles(ImmutableArray<IConfigProfileInfo> configProfiles);
|
||||
|
||||
/*
|
||||
* Immediate mode
|
||||
*/
|
||||
FluentResults.Result<IConfigEntry<T>> AddConfigEntry<T>(ContentPackage package, string name,
|
||||
T defaultValue,
|
||||
NetSync syncMode = NetSync.None,
|
||||
ClientPermissions permissions = ClientPermissions.None,
|
||||
Func<T, bool> valueChangePredicate = null,
|
||||
Action<IConfigEntry<T>> onValueChanged = null) where T : IConvertible, IEquatable<T>;
|
||||
|
||||
FluentResults.Result<IConfigList> AddConfigList(ContentPackage package, string name,
|
||||
int defaultIndex, IReadOnlyList<string> values,
|
||||
NetSync syncMode = NetSync.None,
|
||||
ClientPermissions permissions = ClientPermissions.None,
|
||||
Func<IConfigList, int, bool> valueChangePredicate = null,
|
||||
Action<IConfigList, int> onValueChanged = null);
|
||||
|
||||
FluentResults.Result<IConfigRangeEntry<T>> AddConfigRangeEntry<T>(ContentPackage package, string name,
|
||||
T defaultValue, T minValue, T maxValue,
|
||||
Func<IConfigRangeEntry<T>, int> getStepCount,
|
||||
NetSync syncMode = NetSync.None,
|
||||
ClientPermissions permissions = ClientPermissions.None,
|
||||
Func<T, bool> valueChangePredicate = null,
|
||||
Action<IConfigEntry<T>> onValueChanged = null) where T : IConvertible, IEquatable<T>;
|
||||
|
||||
FluentResults.Result<IConfigEntry<T>> AddConfigEntry<T>(string packageName, string name,
|
||||
T defaultValue,
|
||||
NetSync syncMode = NetSync.None,
|
||||
ClientPermissions permissions = ClientPermissions.None,
|
||||
Func<T, bool> valueChangePredicate = null,
|
||||
Action<IConfigEntry<T>> onValueChanged = null) where T : IConvertible, IEquatable<T>;
|
||||
|
||||
FluentResults.Result<IConfigList> AddConfigList(string packageName, string name,
|
||||
int defaultIndex, IReadOnlyList<string> values,
|
||||
NetSync syncMode = NetSync.None,
|
||||
ClientPermissions permissions = ClientPermissions.None,
|
||||
Func<IConfigList, int, bool> valueChangePredicate = null,
|
||||
Action<IConfigList, int> onValueChanged = null);
|
||||
|
||||
FluentResults.Result<IConfigRangeEntry<T>> AddConfigRangeEntry<T>(string packageName, string name,
|
||||
T defaultValue, T minValue, T maxValue,
|
||||
Func<IConfigRangeEntry<T>, int> getStepCount,
|
||||
NetSync syncMode = NetSync.None,
|
||||
ClientPermissions permissions = ClientPermissions.None,
|
||||
Func<T, bool> valueChangePredicate = null,
|
||||
Action<IConfigEntry<T>> onValueChanged = null) where T : IConvertible, IEquatable<T>;
|
||||
|
||||
FluentResults.Result<IReadOnlyDictionary<string, IConfigBase>> GetConfigsForPackage(ContentPackage package);
|
||||
FluentResults.Result<IReadOnlyDictionary<string, IConfigBase>> GetConfigsForPackage(string packageName);
|
||||
IReadOnlyDictionary<(ContentPackage, string), IConfigBase> GetAllConfigs();
|
||||
FluentResults.Result<IConfigBase> GetConfig(ContentPackage package, string name);
|
||||
FluentResults.Result<IConfigBase> GetConfig(string packageName, string name);
|
||||
FluentResults.Result<T> GetConfig<T>(ContentPackage package, string name) where T : IConfigBase;
|
||||
FluentResults.Result<T> GetConfig<T>(string packageName, string name) where T : IConfigBase;
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using Barotrauma.LuaCs.Events;
|
||||
using Barotrauma.LuaCs.Services.Compatibility;
|
||||
using Barotrauma.LuaCs.Services.Safe;
|
||||
|
||||
namespace Barotrauma.LuaCs.Services;
|
||||
|
||||
public interface IEventService : IReusableService, ILuaEventService
|
||||
{
|
||||
FluentResults.Result SetLegacyLuaRunnerFactory<T>(Func<LuaCsFunc, T> runnerFactory) where T : IEvent<T>;
|
||||
void RemoveLegacyLuaRunnerFactory<T>() where T : IEvent<T>;
|
||||
void SetAliasToEvent<T>(string alias) where T : IEvent<T>;
|
||||
void RemoveEventAlias(string alias);
|
||||
void RemoveAllEventAliases<T>() where T : IEvent<T>;
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="subscriber"></param>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <returns></returns>
|
||||
FluentResults.Result Subscribe<T>(T subscriber) where T : IEvent<T>;
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="subscriber"></param>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
void Unsubscribe<T>(T subscriber) where T : IEvent;
|
||||
/// <summary>
|
||||
/// Clears all subscribers for a given event type and removes any registration to the type.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The event type.</typeparam>
|
||||
void ClearAllEventSubscribers<T>() where T : IEvent;
|
||||
/// <summary>
|
||||
/// Clears all subscribers lists.
|
||||
/// </summary>
|
||||
void ClearAllSubscribers();
|
||||
/// <summary>
|
||||
/// Invokes all alive subscribers of the given event using the provided invocation factory.
|
||||
/// </summary>
|
||||
/// <param name="action"></param>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <returns></returns>
|
||||
FluentResults.Result PublishEvent<T>(Action<T> action) where T : IEvent<T>;
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using Barotrauma.LuaCs.Data;
|
||||
|
||||
namespace Barotrauma.LuaCs.Services;
|
||||
|
||||
public interface ILocalizationService : IReusableService
|
||||
{
|
||||
IReadOnlyCollection<CultureInfo> GetLoadedLocales();
|
||||
void Remove(ImmutableArray<ILocalizationResourceInfo> localizations);
|
||||
FluentResults.Result SetCurrentCulture(CultureInfo culture);
|
||||
FluentResults.Result SetCurrentCulture(string cultureName);
|
||||
FluentResults.Result LoadLocalizations(ImmutableArray<ILocalizationResourceInfo> localizationResources);
|
||||
|
||||
/// <summary>
|
||||
/// Tries to get a localized string without a fallback. Returns success/failure and associated data.
|
||||
/// </summary>
|
||||
/// <param name="key">Neutral localization key.</param>
|
||||
/// <returns></returns>
|
||||
FluentResults.Result<string> GetLocalizedString(string key);
|
||||
FluentResults.Result<string> GetLocalizedString(string key, CultureInfo targetCulture);
|
||||
string GetLocalizedString(string key, string fallback);
|
||||
string GetLocalizedString(string key, string fallback, CultureInfo targetCulture);
|
||||
FluentResults.Result<string> GetLocalizedStringForPackage(ContentPackage package, string key);
|
||||
FluentResults.Result<string> GetLocalizedStringForPackage(ContentPackage package, string key, CultureInfo targetCulture);
|
||||
string GetLocalizedStringForPackage(ContentPackage package, string key, string fallback);
|
||||
string GetLocalizedStringForPackage(ContentPackage package, string key, string fallback, CultureInfo targetCulture);
|
||||
FluentResults.Result RegisterLocalizationResolver(CultureInfo targetCulture, Func<string, CultureInfo, string> factoryResolver);
|
||||
bool IsCurrentCultureSupported(IResourceCultureInfo culturesInfo);
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
using System;
|
||||
using Barotrauma.Networking;
|
||||
using FluentResults;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace Barotrauma.LuaCs.Services;
|
||||
|
||||
/// <summary>
|
||||
/// Provides console and debug logging services
|
||||
/// </summary>
|
||||
public interface ILoggerService : IReusableService
|
||||
{
|
||||
void HandleException(Exception exception, string prefix = null);
|
||||
void LogError(string message);
|
||||
void LogWarning(string message);
|
||||
void LogMessage(string message, Color? serverColor = null, Color? clientColor = null);
|
||||
void Log(string message, Color? color = null, ServerLog.MessageType messageType = ServerLog.MessageType.ServerMessage);
|
||||
void LogResults(FluentResults.Result result);
|
||||
|
||||
#region DebugBuilds
|
||||
|
||||
void LogDebug(string message, Color? color = null);
|
||||
void LogDebugWarning(string message);
|
||||
void LogDebugError(string message);
|
||||
|
||||
#endregion
|
||||
}
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Reflection;
|
||||
using Barotrauma.LuaCs.Data;
|
||||
using MoonSharp.Interpreter;
|
||||
using MoonSharp.Interpreter.Interop;
|
||||
|
||||
namespace Barotrauma.LuaCs.Services;
|
||||
|
||||
public interface ILuaScriptService : IReusableService
|
||||
{
|
||||
#region Script_File_Collector
|
||||
|
||||
/// <summary>
|
||||
/// Adds the script files to the runner but does not execute them.
|
||||
/// </summary>
|
||||
/// <param name="luaResource"></param>
|
||||
/// <returns></returns>
|
||||
FluentResults.Result AddScriptFiles(ImmutableArray<ILuaResourceInfo> luaResource);
|
||||
|
||||
/// <summary>
|
||||
/// Removes the specific resources from the script runner. Important: Does not stop the
|
||||
/// execution of any code related to the files nor guarantee cleanup of resources!
|
||||
/// </summary>
|
||||
/// <param name="luaResource"></param>
|
||||
void RemoveScriptFiles(ImmutableArray<ILuaResourceInfo> luaResource);
|
||||
|
||||
/// <summary>
|
||||
/// Executes loaded script files on the management service.
|
||||
/// </summary>
|
||||
/// <param name="pauseExecutionOnScriptError"></param>
|
||||
/// <param name="verboseLogging"></param>
|
||||
/// <returns></returns>
|
||||
FluentResults.Result ExecuteScripts(bool pauseExecutionOnScriptError = false, bool verboseLogging = false);
|
||||
|
||||
ImmutableArray<ILuaResourceInfo> GetScriptResources();
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
public interface ILuaScriptManagementService : IReusableService
|
||||
{
|
||||
#region Script_File_Execution
|
||||
|
||||
FluentResults.Result ExecuteLoadedScripts(ContentPackage package, bool pauseExecutionOnError = false, bool verboseLogging = false);
|
||||
FluentResults.Result ExecuteLoadedScripts(ImmutableArray<ILuaResourceInfo> scripts, bool pauseExecutionOnError = false, bool verboseLogging = false);
|
||||
FluentResults.Result ExecuteLoadedScripts(bool pauseExecutionOnError = false, bool verboseLogging = false);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Type_Registration
|
||||
|
||||
IUserDataDescriptor RegisterType(Type type);
|
||||
IUserDataDescriptor RegisterType(string typeName);
|
||||
IUserDataDescriptor RegisterGenericType(Type type);
|
||||
IUserDataDescriptor RegisterGenericType(string typeName, params string[] typeNameArgs);
|
||||
void UnregisterType(Type type);
|
||||
void UnregisterType(string typeName);
|
||||
void UnregisterAllTypes();
|
||||
|
||||
#endregion
|
||||
|
||||
#region Type_Checks_&Utilities
|
||||
|
||||
bool IsRegistered(Type type);
|
||||
bool IsTargetType(object obj, string typeName);
|
||||
string TypeOf(object obj);
|
||||
object CreateStatic(string typeName);
|
||||
object CreateEnumTable(string typeName);
|
||||
FieldInfo FindFieldRecursively(Type type, string fieldName);
|
||||
void MakeFieldAccessible(IUserDataDescriptor descriptor, string fieldName);
|
||||
MethodInfo FindMethodRecursively(Type type, string methodName, Type[] types = null);
|
||||
void MakeMethodAccessible(IUserDataDescriptor descriptor, string methodName, string[] parameters = null);
|
||||
PropertyInfo FindPropertyRecursively(Type type, string propertyName);
|
||||
void MakePropertyAccessible(IUserDataDescriptor descriptor, string propertyName);
|
||||
void AddMethod(IUserDataDescriptor descriptor, string methodName, object function);
|
||||
void AddField(IUserDataDescriptor descriptor, string fieldName, DynValue value);
|
||||
void RemoveMember(IUserDataDescriptor descriptor, string memberName);
|
||||
bool HasMember(object obj, string memberName);
|
||||
DynValue CreateUserDataFromDescriptor(DynValue scriptObject, IUserDataDescriptor descriptor);
|
||||
DynValue CreateUserDataFromType(DynValue scriptObject, Type desiredType);
|
||||
|
||||
#endregion
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
using System;
|
||||
using Barotrauma.LuaCs.Data;
|
||||
using Barotrauma.LuaCs.Networking;
|
||||
using Barotrauma.LuaCs.Services.Compatibility;
|
||||
using Barotrauma.Networking;
|
||||
|
||||
namespace Barotrauma.LuaCs.Services;
|
||||
|
||||
internal delegate void NetMessageReceived(IReadMessage netMessage);
|
||||
|
||||
internal interface INetworkingService : IReusableService, ILuaCsNetworking
|
||||
{
|
||||
bool IsActive { get; }
|
||||
bool IsSynchronized { get; }
|
||||
|
||||
public INetWriteMessage Start(Guid netId);
|
||||
public void Receive(Guid netId, NetMessageReceived action);
|
||||
#if SERVER
|
||||
public void Send(IWriteMessage netMessage, NetworkConnection connection = null, DeliveryMethod deliveryMethod = DeliveryMethod.Reliable);
|
||||
#elif CLIENT
|
||||
public void Send(IWriteMessage netMessage, DeliveryMethod deliveryMethod = DeliveryMethod.Reliable);
|
||||
#endif
|
||||
public void RegisterNetVar(INetVar netVar);
|
||||
public void SendNetVar(INetVar netVar);
|
||||
}
|
||||
+91
@@ -0,0 +1,91 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Globalization;
|
||||
using Barotrauma.Extensions;
|
||||
using Barotrauma.LuaCs.Data;
|
||||
|
||||
namespace Barotrauma.LuaCs.Services;
|
||||
|
||||
public interface IPackageManagementService : IReusableService
|
||||
{
|
||||
/// <summary>
|
||||
/// Adds packages to the queue of loadable packages without initializing them.
|
||||
/// </summary>
|
||||
/// <param name="packages"></param>
|
||||
void QueuePackages(ImmutableArray<LoadablePackage> packages);
|
||||
|
||||
/// <summary>
|
||||
/// Generates the ModConfigInfo for all queued packages and adds them to the store.
|
||||
/// </summary>
|
||||
/// <param name="loadParallel">Use multithreaded loading.</param>
|
||||
/// <param name="reportFailOnDuplicates">Whether duplicate packages should be reported as errors.</param>
|
||||
/// <returns>Failure/Success records for each package.</returns>
|
||||
FluentResults.Result ParseQueuedPackages(bool loadParallel = true, bool reportFailOnDuplicates = false);
|
||||
/// <summary>
|
||||
/// Loads only the localizations, configs, and config profiles for stored packages.
|
||||
/// </summary>
|
||||
/// <param name="loadParallel"></param>
|
||||
/// <returns></returns>
|
||||
FluentResults.Result LoadPackageConfigsResourcesGroup(bool loadParallel = true);
|
||||
/// <summary>
|
||||
/// Loads all resources for stored packages.
|
||||
/// </summary>
|
||||
/// <param name="loadParallel">Use multithreaded loading.</param>
|
||||
/// <param name="safeResourcesOnly">Only load safe scripting resources, such as Lua. C# plugins disabled.</param>
|
||||
/// <returns></returns>
|
||||
FluentResults.Result LoadAllPackageResources(bool loadParallel = true, bool safeResourcesOnly = true);
|
||||
FluentResults.Result UnloadPackages();
|
||||
bool IsPackageLoaded(ContentPackage package);
|
||||
bool CheckDependencyLoaded(IPackageDependencyInfo info);
|
||||
bool CheckDependenciesLoaded([NotNull]IEnumerable<IPackageDependencyInfo> infos, out ImmutableArray<IPackageDependencyInfo> missingPackages);
|
||||
bool CheckEnvironmentSupported(IPlatformInfo platform);
|
||||
/// <summary>
|
||||
/// Tries to get the package dependency record to refer to that specific package if it exists, optionally create it.
|
||||
/// </summary>
|
||||
/// <param name="package">ContentPackage reference</param>
|
||||
/// <param name="addIfMissing">Register a new IPackageDependencyInfo reference.</param>
|
||||
/// <returns></returns>
|
||||
FluentResults.Result<IPackageDependencyInfo> GetPackageDependencyInfoRecord(ContentPackage package,
|
||||
bool addIfMissing = false);
|
||||
/// <summary>
|
||||
/// Tries to get the package dependency record to refer to that specific package if it exists, optionally create it.
|
||||
/// </summary>
|
||||
/// <param name="steamWorkshopId">The Steam Workshop ID, if available, if not enter zero ('0').</param>
|
||||
/// <param name="packageName">The name of the package.</param>
|
||||
/// <param name="folderPath">The folder path, as formatted in [ContentPackage.Path].</param>
|
||||
/// <param name="addIfMissing">Register a new IPackageDependencyInfo reference.</param>
|
||||
/// <returns></returns>
|
||||
FluentResults.Result<IPackageDependencyInfo> GetPackageDependencyInfoRecord(ulong steamWorkshopId,
|
||||
string packageName, string folderPath = null, bool addIfMissing = false);
|
||||
/// <summary>
|
||||
/// Tries to get the package dependency record to refer to that specific package if it exists.
|
||||
/// Note: This overload does not allow the registration of a new dependency.
|
||||
/// </summary>
|
||||
/// <param name="folderPath">The folder path, as formatted in [ContentPackage.Path].</param>
|
||||
/// <returns></returns>
|
||||
FluentResults.Result<IPackageDependencyInfo> GetPackageDependencyInfoRecord(string folderPath);
|
||||
|
||||
IPackageDependencyInfo CreateOrphanPackageDependencyInfoRecord(string packageName,
|
||||
string packagePath, ulong steamWorkshopId);
|
||||
}
|
||||
|
||||
public readonly record struct LoadablePackage
|
||||
{
|
||||
public ContentPackage Package { get; }
|
||||
public bool IsEnabled { get; }
|
||||
|
||||
public LoadablePackage(ContentPackage package, bool isEnabled)
|
||||
{
|
||||
Package = package;
|
||||
IsEnabled = isEnabled;
|
||||
}
|
||||
|
||||
public static ImmutableArray<LoadablePackage> FromEnumerable(IEnumerable<ContentPackage> packages, bool isEnabled)
|
||||
{
|
||||
var builder = ImmutableArray.CreateBuilder<LoadablePackage>();
|
||||
packages.ForEach(p => builder.Add(new LoadablePackage(p, isEnabled)));
|
||||
return builder.ToImmutable();
|
||||
}
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Barotrauma.LuaCs.Data;
|
||||
using FluentResults;
|
||||
|
||||
namespace Barotrauma.LuaCs.Services;
|
||||
|
||||
public interface IPackageService : IReusableService,
|
||||
// These allow us the pass the IContentPackageService to anything that needs the data without having to directly reference the member
|
||||
IResourceCultureInfo, IAssembliesResourcesInfo, ILocalizationsResourcesInfo, ILuaScriptsResourcesInfo
|
||||
{
|
||||
ContentPackage Package { get; }
|
||||
IModConfigInfo ModConfigInfo { get; }
|
||||
bool IsEnabledInModList { get; }
|
||||
/// <summary>
|
||||
/// Try to load the XML config and resources information from the given package.
|
||||
/// </summary>
|
||||
/// <param name="package"></param>
|
||||
/// <returns>Whether the package was parsed without errors.</returns>
|
||||
FluentResults.Result LoadResourcesInfo([NotNull]LoadablePackage package);
|
||||
/// <summary>
|
||||
/// Tries to load all assemblies and instance plugins for the given resources list, regardless whether they're marked as optional and/or lazy load.
|
||||
/// Will sort by load priority unless overriden/bypassed.
|
||||
/// </summary>
|
||||
/// <param name="assembliesInfo"></param>
|
||||
/// <param name="ignoreDependencySorting"></param>
|
||||
/// <returns>Whether loading is successful. Returns true on an empty list.</returns>
|
||||
FluentResults.Result LoadPlugins([NotNull]IAssembliesResourcesInfo assembliesInfo, bool ignoreDependencySorting = false);
|
||||
FluentResults.Result LoadLocalizations([NotNull]ILocalizationsResourcesInfo localizationsInfo);
|
||||
FluentResults.Result AddLuaScripts([NotNull]ILuaScriptsResourcesInfo luaScriptsInfo);
|
||||
#if CLIENT
|
||||
FluentResults.Result LoadStyles([NotNull]IStylesResourcesInfo stylesInfo);
|
||||
#endif
|
||||
FluentResults.Result LoadConfig([NotNull]IConfigsResourcesInfo configsResourcesInfo, [NotNull]IConfigProfilesResourcesInfo configProfilesResourcesInfo);
|
||||
}
|
||||
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
using System;
|
||||
using System.Collections.Immutable;
|
||||
using System.Reflection;
|
||||
using Barotrauma.LuaCs.Data;
|
||||
using Microsoft.CodeAnalysis;
|
||||
|
||||
namespace Barotrauma.LuaCs.Services;
|
||||
|
||||
public interface IPluginManagementService : IReusableService
|
||||
{
|
||||
/// <summary>
|
||||
/// Checks if an assembly with either the fully-qualified name globally or a 'friendly name' within loaded plugins
|
||||
/// with the given name is loaded.
|
||||
/// </summary>
|
||||
/// <param name="friendlyName"></param>
|
||||
/// <returns></returns>
|
||||
bool IsAssemblyLoadedGlobal(string friendlyName);
|
||||
|
||||
// TODO: Documentation.
|
||||
FluentResults.Result<ImmutableArray<T>> GetTypes<T>(
|
||||
ContentPackage package = null,
|
||||
string namespacePrefix = null,
|
||||
bool includeInterfaces = false,
|
||||
bool includeAbstractTypes = false,
|
||||
bool includeDefaultContext = true,
|
||||
bool includeExplicitAssembliesOnly = false);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the assembly <c>MetadataReference</c> collection for the BCL and base game assemblies.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
ImmutableArray<MetadataReference> GetStandardMetadataReferences();
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
ImmutableArray<MetadataReference> GetPluginMetadataReferences();
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="package"></param>
|
||||
/// <returns></returns>
|
||||
FluentResults.Result<ImmutableArray<IAssemblyResourceInfo>> GetCachedAssembliesForPackage(ContentPackage package);
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="resource"></param>
|
||||
/// <returns>Success/Failure and list of failed resources, if any.</returns>
|
||||
FluentResults.Result<ImmutableArray<IAssemblyResourceInfo>> LoadAssemblyResources(ImmutableArray<IAssemblyResourceInfo> resource);
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Reflection;
|
||||
using Barotrauma.LuaCs.Data;
|
||||
|
||||
namespace Barotrauma.LuaCs.Services;
|
||||
|
||||
public interface IPluginService : IReusableService
|
||||
{
|
||||
bool IsAssemblyLoaded(string friendlyName);
|
||||
/// <summary>
|
||||
/// Loads the assemblies for the given information
|
||||
/// </summary>
|
||||
/// <param name="assemblyResourcesInfo"></param>
|
||||
/// <param name="injectServices"></param>
|
||||
/// <param name="typeInstances"></param>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <returns></returns>
|
||||
FluentResults.Result LoadAndInstanceTypes<T>(IEnumerable<IAssemblyResourceInfo> assemblyResourcesInfo, bool injectServices, out ImmutableArray<T> typeInstances) where T : class, IAssemblyPlugin;
|
||||
FluentResults.Result<ImmutableArray<T>> GetLoadedPluginTypesInPackage<T>() where T : class, IAssemblyPlugin;
|
||||
/// <summary>
|
||||
/// Advances the loading/execution state of the plugin. IMPORTANT: You cannot set the execution state of plugins
|
||||
/// to 'Disposed'. You must instead call the 'DisposePlugins' method.
|
||||
/// </summary>
|
||||
/// <param name="newState"></param>
|
||||
/// <returns></returns>
|
||||
FluentResults.Result AdvancePluginStates(PluginRunState newState);
|
||||
|
||||
/// <summary>
|
||||
/// Disposes of all running plugins hosted by the service and releases their references to allow unloading.
|
||||
/// </summary>
|
||||
/// <returns>Success of the operation. Returns false if any plugin threw errors during disposal.</returns>
|
||||
FluentResults.Result DisposePlugins();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current plugin execution state.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
PluginRunState GetPluginRunState();
|
||||
}
|
||||
|
||||
public enum PluginRunState
|
||||
{
|
||||
Instanced=0,
|
||||
PreInitialization=1,
|
||||
Initialized=2,
|
||||
LoadingCompleted=3,
|
||||
Disposed=4
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
using System;
|
||||
|
||||
namespace Barotrauma.LuaCs.Services;
|
||||
|
||||
/// <summary>
|
||||
/// Defines a service that can be reset to it's post-constructor state and reused without needing to be disposed.
|
||||
/// Intended for persistent services.
|
||||
/// </summary>
|
||||
public interface IReusableService : IService
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns the service to its original state (post-instantiation).
|
||||
/// Allows a service instance to be reused without disposing of the instance.
|
||||
/// </summary>
|
||||
FluentResults.Result Reset();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Base interface inherited by all services.
|
||||
/// </summary>
|
||||
public interface IService : IDisposable
|
||||
{
|
||||
bool IsDisposed { get; }
|
||||
public void CheckDisposed()
|
||||
{
|
||||
if (IsDisposed)
|
||||
throw new ObjectDisposedException($"Tried to call method on disposed object '{this.GetType().Name}'!");
|
||||
}
|
||||
}
|
||||
+110
@@ -0,0 +1,110 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using LightInject;
|
||||
|
||||
namespace Barotrauma.LuaCs.Services;
|
||||
|
||||
/// <summary>
|
||||
/// Provides instancing and management of IServices.
|
||||
/// </summary>
|
||||
public interface IServicesProvider
|
||||
{
|
||||
#region Type_Registration
|
||||
|
||||
/// <summary>
|
||||
/// Registers a type as a service for a given interface.
|
||||
/// </summary>
|
||||
/// <param name="lifetime"></param>
|
||||
/// <param name="lifetimeInstance"></param>
|
||||
/// <typeparam name="TSvcInterface"></typeparam>
|
||||
/// <typeparam name="TService"></typeparam>
|
||||
void RegisterServiceType<TSvcInterface, TService>(ServiceLifetime lifetime, ILifetime lifetimeInstance = null) where TSvcInterface : class, IReusableService where TService : class, IReusableService, TSvcInterface;
|
||||
|
||||
/// <summary>
|
||||
/// Registers a type as a service for a given interface that can be requested by name.
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <param name="lifetime"></param>
|
||||
/// <param name="lifetimeInstance"></param>
|
||||
/// <typeparam name="TSvcInterface"></typeparam>
|
||||
/// <typeparam name="TService"></typeparam>
|
||||
void RegisterServiceType<TSvcInterface, TService>(string name, ServiceLifetime lifetime, ILifetime lifetimeInstance = null) where TSvcInterface : class, IReusableService where TService : class, IReusableService, TSvcInterface;
|
||||
|
||||
/// <summary>
|
||||
/// Called whenever a new service type for a given interface is implemented.
|
||||
/// Args[0]: Interface type
|
||||
/// Args[1]: Implementing type
|
||||
/// </summary>
|
||||
event System.Action<Type, Type> OnServiceRegistered;
|
||||
|
||||
/// <summary>
|
||||
/// Runs compilation of registered services.
|
||||
/// </summary>
|
||||
public void Compile();
|
||||
|
||||
#endregion
|
||||
|
||||
#region Services_Instancing_Injection
|
||||
|
||||
/// <summary>
|
||||
/// Injects services into the properties of already instanced objects.
|
||||
/// </summary>
|
||||
/// <param name="inst"></param>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
void InjectServices<T>(T inst) where T : class;
|
||||
|
||||
/// <summary>
|
||||
/// Tries to get a service for the given interface, returns success/failure.
|
||||
/// </summary>
|
||||
/// <param name="service"></param>
|
||||
/// <param name="lifetime"></param>
|
||||
/// <typeparam name="TSvcInterface"></typeparam>
|
||||
/// <returns></returns>
|
||||
bool TryGetService<TSvcInterface>(out TSvcInterface service) where TSvcInterface : class, IReusableService;
|
||||
|
||||
/// <summary>
|
||||
/// Tries to get a service for the given name and interface, returns success/failure.
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <param name="service"></param>
|
||||
/// <param name="lifetime"></param>
|
||||
/// <typeparam name="TSvcInterface"></typeparam>
|
||||
/// <returns></returns>
|
||||
bool TryGetService<TSvcInterface>(string name, out TSvcInterface service) where TSvcInterface : class, IReusableService;
|
||||
|
||||
/// <summary>
|
||||
/// Called whenever a new service is created/instanced.
|
||||
/// Args[0]: The interface type of the service.
|
||||
/// Args[1]: The instance of the service.
|
||||
/// </summary>
|
||||
event System.Action<Type, IReusableService> OnServiceInstanced;
|
||||
|
||||
#endregion
|
||||
|
||||
#region ActiveServices
|
||||
|
||||
/// <summary>
|
||||
/// Returns all services for the given interface.
|
||||
/// </summary>
|
||||
/// <typeparam name="TSvc"></typeparam>
|
||||
/// <returns></returns>
|
||||
ImmutableArray<TSvc> GetAllServices<TSvc>() where TSvc : class, IReusableService;
|
||||
|
||||
#endregion
|
||||
|
||||
// Notes: Left public due to the common use of Publicizers
|
||||
#region Internal_Use
|
||||
|
||||
/// <summary>
|
||||
/// Notes: Internal use only if hosted by LuaCsForBarotrauma. Disposes of all services and resets DI container. Warning: unable to dispose of services held by other objects.
|
||||
/// </summary>
|
||||
void DisposeAndReset();
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
public enum ServiceLifetime
|
||||
{
|
||||
Transient, Singleton, PerThread, Invalid, Custom
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
using System.Collections.Immutable;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Barotrauma.LuaCs.Services;
|
||||
|
||||
public interface IStorageService : IReusableService
|
||||
{
|
||||
#region LocalGameData
|
||||
|
||||
FluentResults.Result<XDocument> LoadLocalXml(ContentPackage package, string localFilePath);
|
||||
FluentResults.Result<byte[]> LoadLocalBinary(ContentPackage package, string localFilePath);
|
||||
FluentResults.Result<string> LoadLocalText(ContentPackage package, string localFilePath);
|
||||
FluentResults.Result<bool> FileExistsInLocalData(ContentPackage package, string localFilePath);
|
||||
|
||||
#endregion
|
||||
|
||||
#region ContentPackageData
|
||||
FluentResults.Result<XDocument> LoadPackageXml(ContentPackage package, string localFilePath, out XDocument document);
|
||||
FluentResults.Result<byte[]> LoadPackageBinary(ContentPackage package, string localFilePath, out byte[] bytes);
|
||||
FluentResults.Result<string> LoadPackageText(ContentPackage package, string localFilePath, out string text);
|
||||
|
||||
FluentResults.Result<ImmutableArray<XDocument>> LoadPackageXmlFiles(ContentPackage package, ImmutableArray<string> localFilePath);
|
||||
FluentResults.Result<ImmutableArray<byte[]>> TryLoadPackageBinaryFiles(ContentPackage package, ImmutableArray<string> localFilePath);
|
||||
FluentResults.Result<ImmutableArray<string>> TryLoadPackageTextFiles(ContentPackage package, ImmutableArray<string> localFilePath);
|
||||
|
||||
FluentResults.Result<ImmutableArray<string>> FindFilesInPackage(ContentPackage package, string localSubfolder, string regexFilter, bool searchRecursively);
|
||||
FluentResults.Result<bool> FileExistsInPackage(ContentPackage package, string localFilePath);
|
||||
|
||||
#endregion
|
||||
|
||||
#region AbsolutePaths
|
||||
|
||||
FluentResults.Result<XDocument> TryLoadXml(string filePatht);
|
||||
FluentResults.Result TrySaveXml(string filePath, in XDocument document);
|
||||
FluentResults.Result<byte[]> TryLoadBinary(string filePath);
|
||||
FluentResults.Result TrySaveBinary(string filePath, in byte[] bytes);
|
||||
FluentResults.Result<string> TryLoadText(string filePath);
|
||||
FluentResults.Result TrySaveText(string filePath, string text);
|
||||
FluentResults.Result<bool> FileExists(string filePath);
|
||||
|
||||
#endregion
|
||||
}
|
||||
Reference in New Issue
Block a user