14
14
// ReSharper disable EventNeverSubscribedTo.Global
15
15
// ReSharper disable InconsistentNaming
16
16
17
- namespace Barotrauma ;
17
+ namespace Barotrauma . LuaCs . Services ;
18
18
19
19
/***
20
20
* 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;
25
25
/// Provides functionality for the loading, unloading and management of plugins implementing IAssemblyPlugin.
26
26
/// All plugins are loaded into their own AssemblyLoadContext along with their dependencies.
27
27
/// </summary>
28
- public class AssemblyManager
28
+ public class AssemblyManager : IAssemblyManagementService
29
29
{
30
30
#region ExternalAPI
31
-
32
- /// <summary>
33
- /// Called when an assembly is loaded.
34
- /// </summary>
31
+
35
32
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>
41
33
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>
46
34
public event Action < string , Exception > OnException ;
47
-
48
- /// <summary>
49
- /// For unloading issue debugging. Called whenever MemoryFileAssemblyContextLoader [load context] is unloaded.
50
- /// </summary>
51
35
public event Action < Guid > OnACLUnload ;
52
-
53
-
54
- /// <summary>
55
- /// [DEBUG ONLY]
56
- /// Returns a list of the current unloading ACLs.
57
- /// </summary>
58
36
public ImmutableList < WeakReference < MemoryFileAssemblyContextLoader > > StillUnloadingACLs
59
37
{
60
38
get
@@ -70,12 +48,6 @@ public ImmutableList<WeakReference<MemoryFileAssemblyContextLoader>> StillUnload
70
48
}
71
49
}
72
50
}
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>
79
51
public bool IsCurrentlyUnloading
80
52
{
81
53
get
@@ -95,21 +67,6 @@ public bool IsCurrentlyUnloading
95
67
}
96
68
}
97
69
}
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>
113
70
public IEnumerable < Type > GetSubTypesInLoadedAssemblies < T > ( bool rebuildList )
114
71
{
115
72
Type targetType = typeof ( T ) ;
@@ -165,14 +122,6 @@ public IEnumerable<Type> GetSubTypesInLoadedAssemblies<T>(bool rebuildList)
165
122
OpsLockLoaded . ExitReadLock ( ) ;
166
123
}
167
124
}
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>
176
125
public bool TryGetSubTypesFromACL < T > ( Guid id , out IEnumerable < Type > types )
177
126
{
178
127
Type targetType = typeof ( T ) ;
@@ -188,13 +137,6 @@ public bool TryGetSubTypesFromACL<T>(Guid id, out IEnumerable<Type> types)
188
137
types = null ;
189
138
return false ;
190
139
}
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>
198
140
public bool TryGetSubTypesFromACL ( Guid id , out IEnumerable < Type > types )
199
141
{
200
142
if ( TryGetACL ( id , out var acl ) )
@@ -206,14 +148,6 @@ public bool TryGetSubTypesFromACL(Guid id, out IEnumerable<Type> types)
206
148
types = null ;
207
149
return false ;
208
150
}
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>
217
151
public IEnumerable < Type > GetTypesByName ( string typeName )
218
152
{
219
153
List < Type > types = new ( ) ;
@@ -299,12 +233,6 @@ void TypesListHelper()
299
233
}
300
234
}
301
235
}
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>
308
236
public IEnumerable < Type > GetAllTypesInLoadedAssemblies ( )
309
237
{
310
238
OpsLockLoaded . EnterReadLock ( ) ;
@@ -325,13 +253,6 @@ public IEnumerable<Type> GetAllTypesInLoadedAssemblies()
325
253
OpsLockLoaded . ExitReadLock ( ) ;
326
254
}
327
255
}
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>
335
256
public IEnumerable < LoadedACL > GetAllLoadedACLs ( )
336
257
{
337
258
OpsLockLoaded . EnterReadLock ( ) ;
@@ -358,36 +279,14 @@ public IEnumerable<LoadedACL> GetAllLoadedACLs()
358
279
359
280
#region InternalAPI
360
281
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>
366
282
[ MethodImpl ( MethodImplOptions . Synchronized | MethodImplOptions . NoInlining ) ]
367
- internal ImmutableList < LoadedACL > UnsafeGetAllLoadedACLs ( )
283
+ ImmutableList < LoadedACL > IAssemblyManagementService . UnsafeGetAllLoadedACLs ( )
368
284
{
369
285
if ( LoadedACLs . IsEmpty )
370
286
return ImmutableList < LoadedACL > . Empty ;
371
287
return LoadedACLs . Select ( kvp => kvp . Value ) . ToImmutableList ( ) ;
372
288
}
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>
377
289
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>
391
290
public AssemblyLoadingSuccessState LoadAssemblyFromMemory ( [ NotNull ] string compiledAssemblyName ,
392
291
[ NotNull ] IEnumerable < SyntaxTree > syntaxTree ,
393
292
IEnumerable < MetadataReference > externalMetadataReferences ,
@@ -440,31 +339,13 @@ public AssemblyLoadingSuccessState LoadAssemblyFromMemory([NotNull] string compi
440
339
441
340
return state ;
442
341
}
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>
451
342
public bool SetACLToTemplateMode ( Guid guid )
452
343
{
453
344
if ( ! TryGetACL ( guid , out var acl ) )
454
345
return false ;
455
346
acl . Acl . IsTemplateMode = true ;
456
347
return true ;
457
348
}
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>
468
349
public AssemblyLoadingSuccessState LoadAssembliesFromLocations ( [ NotNull ] IEnumerable < string > filePaths ,
469
350
string friendlyName , ref Guid id )
470
351
{
@@ -507,9 +388,7 @@ public AssemblyLoadingSuccessState LoadAssembliesFromLocations([NotNull] IEnumer
507
388
508
389
return AssemblyLoadingSuccessState . ACLLoadFailure ;
509
390
}
510
-
511
-
512
- [ MethodImpl ( MethodImplOptions . NoInlining | MethodImplOptions . Synchronized ) ]
391
+ [ MethodImpl ( MethodImplOptions . NoInlining ) ]
513
392
public bool TryBeginDispose ( )
514
393
{
515
394
OpsLockLoaded . EnterWriteLock ( ) ;
@@ -563,8 +442,6 @@ public bool TryBeginDispose()
563
442
OpsLockLoaded . ExitWriteLock ( ) ;
564
443
}
565
444
}
566
-
567
-
568
445
[ MethodImpl ( MethodImplOptions . NoInlining ) ]
569
446
public bool FinalizeDispose ( )
570
447
{
@@ -606,15 +483,7 @@ public bool FinalizeDispose()
606
483
607
484
return isUnloaded ;
608
485
}
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
+
618
487
[ MethodImpl ( MethodImplOptions . NoInlining ) ]
619
488
public bool TryGetACL ( Guid id , out LoadedACL acl )
620
489
{
@@ -865,6 +734,11 @@ internal void ClearTypesList()
865
734
}
866
735
867
736
#endregion
737
+
738
+ public void Dispose ( )
739
+ {
740
+ TryBeginDispose ( ) ;
741
+ }
868
742
}
869
743
870
744
public static class AssemblyExtensions
0 commit comments