Skip to content

Commit e4eb463

Browse files
- Initial migration of AssemblyManager to services.
- Config and Networking interface creation.
1 parent 08ff760 commit e4eb463

File tree

8 files changed

+230
-144
lines changed

8 files changed

+230
-144
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
namespace Barotrauma.Configuration;
2+
3+
public interface IConfigBase
4+
{
5+
6+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
namespace Barotrauma.Configuration;
2+
3+
public interface IConfigVar : IConfigBase
4+
{
5+
6+
}

Barotrauma/BarotraumaShared/SharedSource/LuaCs/LuaCsSetup.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
using System.Reflection;
1212
using System.Runtime.Loader;
1313
using System.Xml.Linq;
14+
using Barotrauma.LuaCs.Services;
1415
using Barotrauma.Networking;
1516

1617
namespace Barotrauma
@@ -99,7 +100,7 @@ public static bool IsRunningInsideWorkshop
99100
public CsPackageManager PluginPackageManager => _pluginPackageManager ??= new CsPackageManager(AssemblyManager, this);
100101

101102
public LuaCsModStore ModStore { get; private set; }
102-
private LuaRequire require { get; set; }
103+
private LuaRequire Require { get; set; }
103104
public LuaCsSetupConfig Config { get; private set; }
104105
public MoonSharpVsCodeDebugServer DebugServer { get; private set; }
105106
public bool IsInitialized { get; private set; }
@@ -394,7 +395,7 @@ public void Initialize(bool forceEnableCs = false)
394395
Lua.Options.CheckThreadAccess = false;
395396
Script.GlobalOptions.ShouldPCallCatchException = (Exception ex) => { return true; };
396397

397-
require = new LuaRequire(Lua);
398+
Require = new LuaRequire(Lua);
398399

399400
Game = new LuaGame();
400401
Networking = new LuaCsNetworking();
@@ -430,7 +431,7 @@ public void Initialize(bool forceEnableCs = false)
430431

431432
Lua.Globals["dofile"] = (Func<string, Table, string, DynValue>)DoFile;
432433
Lua.Globals["loadfile"] = (Func<string, Table, string, DynValue>)LoadFile;
433-
Lua.Globals["require"] = (Func<string, Table, DynValue>)require.Require;
434+
Lua.Globals["require"] = (Func<string, Table, DynValue>)Require.Require;
434435

435436
Lua.Globals["dostring"] = (Func<string, Table, string, DynValue>)Lua.DoString;
436437
Lua.Globals["load"] = (Func<string, Table, string, DynValue>)Lua.LoadString;
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
using System;
2+
3+
namespace Barotrauma.LuaCs.Networking;
4+
5+
public partial interface INetCallback
6+
{
7+
public ushort CallbackId { get; }
8+
}
9+
10+
#if SERVER
11+
public partial interface INetCallback
12+
{
13+
14+
}
15+
#endif

Barotrauma/BarotraumaShared/SharedSource/LuaCs/Plugins/CsPackageManager.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
using System.Runtime.CompilerServices;
99
using System.Text;
1010
using System.Threading;
11+
using Barotrauma.LuaCs.Services;
1112
using Barotrauma.Steam;
1213
using Microsoft.CodeAnalysis;
1314
using Microsoft.CodeAnalysis.CSharp;

Barotrauma/BarotraumaShared/SharedSource/LuaCs/Plugins/MemoryFileAssemblyContextLoader.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,14 @@
77
using System.Reflection;
88
using System.Runtime.CompilerServices;
99
using System.Runtime.Loader;
10+
using Barotrauma.LuaCs.Services;
1011
using Microsoft.CodeAnalysis;
1112
using Microsoft.CodeAnalysis.CSharp;
1213
// ReSharper disable ConditionIsAlwaysTrueOrFalse
1314

1415
[assembly: InternalsVisibleTo("CompiledAssembly")]
1516

16-
namespace Barotrauma;
17+
namespace Barotrauma.LuaCs;
1718

1819
/// <summary>
1920
/// AssemblyLoadContext to compile from syntax trees in memory and to load from disk/file. Provides dependency resolution.
@@ -31,11 +32,11 @@ public class MemoryFileAssemblyContextLoader : AssemblyLoadContext
3132
// internal
3233
private readonly Dictionary<string, AssemblyDependencyResolver> _dependencyResolvers = new(); // path-folder, resolver
3334
protected bool IsResolving; //this is to avoid circular dependency lookup.
34-
private AssemblyManager _assemblyManager;
35+
private IAssemblyManagementService _assemblyManager;
3536
public bool IsTemplateMode { get; set; }
3637
public bool IsDisposed { get; private set; }
3738

38-
public MemoryFileAssemblyContextLoader(AssemblyManager assemblyManager) : base(isCollectible: true)
39+
public MemoryFileAssemblyContextLoader(IAssemblyManagementService assemblyManager) : base(isCollectible: true)
3940
{
4041
this._assemblyManager = assemblyManager;
4142
this.IsDisposed = false;

Barotrauma/BarotraumaShared/SharedSource/LuaCs/Plugins/AssemblyManager.cs renamed to Barotrauma/BarotraumaShared/SharedSource/LuaCs/Services/AssemblyManager.cs

Lines changed: 11 additions & 137 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
// ReSharper disable EventNeverSubscribedTo.Global
1515
// ReSharper disable InconsistentNaming
1616

17-
namespace Barotrauma;
17+
namespace Barotrauma.LuaCs.Services;
1818

1919
/***
2020
* Note: This class was written to be thread-safe in order to allow parallelization in loading in the future if the need
@@ -25,36 +25,14 @@ namespace Barotrauma;
2525
/// Provides functionality for the loading, unloading and management of plugins implementing IAssemblyPlugin.
2626
/// All plugins are loaded into their own AssemblyLoadContext along with their dependencies.
2727
/// </summary>
28-
public class AssemblyManager
28+
public class AssemblyManager : IAssemblyManagementService
2929
{
3030
#region ExternalAPI
31-
32-
/// <summary>
33-
/// Called when an assembly is loaded.
34-
/// </summary>
31+
3532
public event Action<Assembly> OnAssemblyLoaded;
36-
37-
/// <summary>
38-
/// Called when an assembly is marked for unloading, before unloading begins. You should use this to cleanup
39-
/// any references that you have to this assembly.
40-
/// </summary>
4133
public event Action<Assembly> OnAssemblyUnloading;
42-
43-
/// <summary>
44-
/// Called whenever an exception is thrown. First arg is a formatted message, Second arg is the Exception.
45-
/// </summary>
4634
public event Action<string, Exception> OnException;
47-
48-
/// <summary>
49-
/// For unloading issue debugging. Called whenever MemoryFileAssemblyContextLoader [load context] is unloaded.
50-
/// </summary>
5135
public event Action<Guid> OnACLUnload;
52-
53-
54-
/// <summary>
55-
/// [DEBUG ONLY]
56-
/// Returns a list of the current unloading ACLs.
57-
/// </summary>
5836
public ImmutableList<WeakReference<MemoryFileAssemblyContextLoader>> StillUnloadingACLs
5937
{
6038
get
@@ -70,12 +48,6 @@ public ImmutableList<WeakReference<MemoryFileAssemblyContextLoader>> StillUnload
7048
}
7149
}
7250
}
73-
74-
75-
// ReSharper disable once MemberCanBePrivate.Global
76-
/// <summary>
77-
/// Checks if there are any AssemblyLoadContexts still in the process of unloading.
78-
/// </summary>
7951
public bool IsCurrentlyUnloading
8052
{
8153
get
@@ -95,21 +67,6 @@ public bool IsCurrentlyUnloading
9567
}
9668
}
9769
}
98-
99-
// Old API compatibility
100-
public IEnumerable<Type> GetSubTypesInLoadedAssemblies<T>()
101-
{
102-
return GetSubTypesInLoadedAssemblies<T>(false);
103-
}
104-
105-
106-
/// <summary>
107-
/// Allows iteration over all non-interface types in all loaded assemblies in the AsmMgr that are assignable to the given type (IsAssignableFrom).
108-
/// Warning: care should be used when using this method in hot paths as performance may be affected.
109-
/// </summary>
110-
/// <typeparam name="T">The type to compare against</typeparam>
111-
/// <param name="rebuildList">Forces caches to clear and for the lists of types to be rebuilt.</param>
112-
/// <returns>An Enumerator for matching types.</returns>
11370
public IEnumerable<Type> GetSubTypesInLoadedAssemblies<T>(bool rebuildList)
11471
{
11572
Type targetType = typeof(T);
@@ -165,14 +122,6 @@ public IEnumerable<Type> GetSubTypesInLoadedAssemblies<T>(bool rebuildList)
165122
OpsLockLoaded.ExitReadLock();
166123
}
167124
}
168-
169-
/// <summary>
170-
/// Tries to get types assignable to type from the ACL given the Guid.
171-
/// </summary>
172-
/// <param name="id"></param>
173-
/// <param name="types"></param>
174-
/// <typeparam name="T"></typeparam>
175-
/// <returns></returns>
176125
public bool TryGetSubTypesFromACL<T>(Guid id, out IEnumerable<Type> types)
177126
{
178127
Type targetType = typeof(T);
@@ -188,13 +137,6 @@ public bool TryGetSubTypesFromACL<T>(Guid id, out IEnumerable<Type> types)
188137
types = null;
189138
return false;
190139
}
191-
192-
/// <summary>
193-
/// Tries to get types from the ACL given the Guid.
194-
/// </summary>
195-
/// <param name="id"></param>
196-
/// <param name="types"></param>
197-
/// <returns></returns>
198140
public bool TryGetSubTypesFromACL(Guid id, out IEnumerable<Type> types)
199141
{
200142
if (TryGetACL(id, out var acl))
@@ -206,14 +148,6 @@ public bool TryGetSubTypesFromACL(Guid id, out IEnumerable<Type> types)
206148
types = null;
207149
return false;
208150
}
209-
210-
211-
/// <summary>
212-
/// Allows iteration over all types, including interfaces, in all loaded assemblies in the AsmMgr who's names match the string.
213-
/// Note: Will return the by-reference equivalent type if the type name is prefixed with "out " or "ref ".
214-
/// </summary>
215-
/// <param name="typeName">The string name of the type to search for.</param>
216-
/// <returns>An Enumerator for matching types. List will be empty if bad params are supplied.</returns>
217151
public IEnumerable<Type> GetTypesByName(string typeName)
218152
{
219153
List<Type> types = new();
@@ -299,12 +233,6 @@ void TypesListHelper()
299233
}
300234
}
301235
}
302-
303-
/// <summary>
304-
/// Allows iteration over all types (including interfaces) in all loaded assemblies managed by the AsmMgr.
305-
/// Warning: High usage may result in performance issues.
306-
/// </summary>
307-
/// <returns>An Enumerator for iteration.</returns>
308236
public IEnumerable<Type> GetAllTypesInLoadedAssemblies()
309237
{
310238
OpsLockLoaded.EnterReadLock();
@@ -325,13 +253,6 @@ public IEnumerable<Type> GetAllTypesInLoadedAssemblies()
325253
OpsLockLoaded.ExitReadLock();
326254
}
327255
}
328-
329-
/// <summary>
330-
/// Returns a list of all loaded ACLs.
331-
/// WARNING: References to these ACLs outside of the AssemblyManager should be kept in a WeakReference in order
332-
/// to avoid causing issues with unloading/disposal.
333-
/// </summary>
334-
/// <returns></returns>
335256
public IEnumerable<LoadedACL> GetAllLoadedACLs()
336257
{
337258
OpsLockLoaded.EnterReadLock();
@@ -358,36 +279,14 @@ public IEnumerable<LoadedACL> GetAllLoadedACLs()
358279

359280
#region InternalAPI
360281

361-
/// <summary>
362-
/// [Unsafe] Warning: only for use in nested threading functions. Requires care to manage access.
363-
/// Does not make any guarantees about the state of the ACL after the list has been returned.
364-
/// </summary>
365-
/// <returns></returns>
366282
[MethodImpl(MethodImplOptions.Synchronized | MethodImplOptions.NoInlining)]
367-
internal ImmutableList<LoadedACL> UnsafeGetAllLoadedACLs()
283+
ImmutableList<LoadedACL> IAssemblyManagementService.UnsafeGetAllLoadedACLs()
368284
{
369285
if (LoadedACLs.IsEmpty)
370286
return ImmutableList<LoadedACL>.Empty;
371287
return LoadedACLs.Select(kvp => kvp.Value).ToImmutableList();
372288
}
373-
374-
/// <summary>
375-
/// Used by content package and plugin management to stop unloading of a given ACL until all plugins have gracefully closed.
376-
/// </summary>
377289
public event System.Func<LoadedACL, bool> IsReadyToUnloadACL;
378-
379-
/// <summary>
380-
/// Compiles an assembly from supplied references and syntax trees into the specified AssemblyContextLoader.
381-
/// A new ACL will be created if the Guid supplied is Guid.Empty.
382-
/// </summary>
383-
/// <param name="compiledAssemblyName"></param>
384-
/// <param name="syntaxTree"></param>
385-
/// <param name="externalMetadataReferences"></param>
386-
/// <param name="compilationOptions"></param>
387-
/// <param name="friendlyName">A non-unique name for later reference. Optional, set to null if unused.</param>
388-
/// <param name="id">The guid of the assembly </param>
389-
/// <param name="externFileAssemblyRefs"></param>
390-
/// <returns></returns>
391290
public AssemblyLoadingSuccessState LoadAssemblyFromMemory([NotNull] string compiledAssemblyName,
392291
[NotNull] IEnumerable<SyntaxTree> syntaxTree,
393292
IEnumerable<MetadataReference> externalMetadataReferences,
@@ -440,31 +339,13 @@ public AssemblyLoadingSuccessState LoadAssemblyFromMemory([NotNull] string compi
440339

441340
return state;
442341
}
443-
444-
/// <summary>
445-
/// Switches the ACL with the given Guid to Template Mode, which disables assembly name resolution for any assemblies loaded in it.
446-
/// These ACLs are intended to be used to host Assemblies for information only and not for code execution.
447-
/// WARNING: This process is irreversible.
448-
/// </summary>
449-
/// <param name="guid">Guid of the ACL.</param>
450-
/// <returns>Whether or not an ACL was found with the given ID.</returns>
451342
public bool SetACLToTemplateMode(Guid guid)
452343
{
453344
if (!TryGetACL(guid, out var acl))
454345
return false;
455346
acl.Acl.IsTemplateMode = true;
456347
return true;
457348
}
458-
459-
/// <summary>
460-
/// Tries to load all assemblies at the supplied file paths list into the ACl with the given Guid.
461-
/// If the supplied Guid is Empty, then a new ACl will be created and the Guid will be assigned to it.
462-
/// </summary>
463-
/// <param name="filePaths">List of assemblies to try and load.</param>
464-
/// <param name="friendlyName">A non-unique name for later reference. Optional.</param>
465-
/// <param name="id">Guid of the ACL or Empty if none specified. Guid of ACL will be assigned to this var.</param>
466-
/// <returns>Operation success messages.</returns>
467-
/// <exception cref="ArgumentNullException"></exception>
468349
public AssemblyLoadingSuccessState LoadAssembliesFromLocations([NotNull] IEnumerable<string> filePaths,
469350
string friendlyName, ref Guid id)
470351
{
@@ -507,9 +388,7 @@ public AssemblyLoadingSuccessState LoadAssembliesFromLocations([NotNull] IEnumer
507388

508389
return AssemblyLoadingSuccessState.ACLLoadFailure;
509390
}
510-
511-
512-
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.Synchronized)]
391+
[MethodImpl(MethodImplOptions.NoInlining)]
513392
public bool TryBeginDispose()
514393
{
515394
OpsLockLoaded.EnterWriteLock();
@@ -563,8 +442,6 @@ public bool TryBeginDispose()
563442
OpsLockLoaded.ExitWriteLock();
564443
}
565444
}
566-
567-
568445
[MethodImpl(MethodImplOptions.NoInlining)]
569446
public bool FinalizeDispose()
570447
{
@@ -606,15 +483,7 @@ public bool FinalizeDispose()
606483

607484
return isUnloaded;
608485
}
609-
610-
/// <summary>
611-
/// Tries to retrieve the LoadedACL with the given ID or null if none is found.
612-
/// WARNING: External references to this ACL with long lifespans should be kept in a WeakReference
613-
/// to avoid causing unloading/disposal issues.
614-
/// </summary>
615-
/// <param name="id">GUID of the ACL.</param>
616-
/// <param name="acl">The found ACL or null if none was found.</param>
617-
/// <returns>Whether or not an ACL was found.</returns>
486+
618487
[MethodImpl(MethodImplOptions.NoInlining)]
619488
public bool TryGetACL(Guid id, out LoadedACL acl)
620489
{
@@ -865,6 +734,11 @@ internal void ClearTypesList()
865734
}
866735

867736
#endregion
737+
738+
public void Dispose()
739+
{
740+
TryBeginDispose();
741+
}
868742
}
869743

870744
public static class AssemblyExtensions

0 commit comments

Comments
 (0)