Unstable v0.19.5.0
This commit is contained in:
@@ -4,16 +4,20 @@ using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using Barotrauma.Threading;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
public class PrefabSelector<T> : IEnumerable<T> where T : notnull, Prefab
|
||||
{
|
||||
private readonly ReaderWriterLockSlim rwl = new ReaderWriterLockSlim();
|
||||
|
||||
public T? BasePrefab
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (overrides) { return basePrefabInternal; }
|
||||
using (new ReadLock(rwl)) { return basePrefabInternal; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,51 +25,70 @@ namespace Barotrauma
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (overrides) { return activePrefabInternal; }
|
||||
using (new ReadLock(rwl)) { return activePrefabInternal; }
|
||||
}
|
||||
}
|
||||
|
||||
public void Add(T prefab, bool isOverride)
|
||||
{
|
||||
lock (overrides) { AddInternal(prefab, isOverride); }
|
||||
using (new WriteLock(rwl)) { AddInternal(prefab, isOverride); }
|
||||
}
|
||||
|
||||
public void RemoveIfContains(T prefab)
|
||||
{
|
||||
lock (overrides) { RemoveIfContainsInternal(prefab); }
|
||||
using (new WriteLock(rwl)) { RemoveIfContainsInternal(prefab); }
|
||||
}
|
||||
|
||||
public void Remove(T prefab)
|
||||
{
|
||||
lock (overrides) { RemoveInternal(prefab); }
|
||||
using (new WriteLock(rwl)) { RemoveInternal(prefab); }
|
||||
}
|
||||
|
||||
public void RemoveByFile(ContentFile file, Action<T>? callback = null)
|
||||
{
|
||||
lock (overrides) { RemoveByFileInternal(file, callback); }
|
||||
var removed = new List<T>();
|
||||
using (new WriteLock(rwl))
|
||||
{
|
||||
for (int i = overrides.Count-1; i >= 0; i--)
|
||||
{
|
||||
var prefab = overrides[i];
|
||||
if (prefab.ContentFile == file)
|
||||
{
|
||||
RemoveInternal(prefab);
|
||||
removed.Add(prefab);
|
||||
}
|
||||
}
|
||||
|
||||
if (basePrefabInternal is { ContentFile: var baseFile } p && baseFile == file)
|
||||
{
|
||||
RemoveInternal(basePrefabInternal);
|
||||
removed.Add(p);
|
||||
}
|
||||
}
|
||||
if (callback != null) { removed.ForEach(callback); }
|
||||
}
|
||||
|
||||
public void Sort()
|
||||
{
|
||||
lock (overrides) { SortInternal(); }
|
||||
using (new WriteLock(rwl)) { SortInternal(); }
|
||||
}
|
||||
|
||||
public bool IsEmpty
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (overrides) { return isEmptyInternal; }
|
||||
using (new ReadLock(rwl)) { return isEmptyInternal; }
|
||||
}
|
||||
}
|
||||
|
||||
public bool Contains(T prefab)
|
||||
{
|
||||
lock (overrides) { return ContainsInternal(prefab); }
|
||||
using (new ReadLock(rwl)) { return ContainsInternal(prefab); }
|
||||
}
|
||||
|
||||
public bool IsOverride(T prefab)
|
||||
{
|
||||
lock (overrides) { return IsOverrideInternal(prefab); }
|
||||
using (new ReadLock(rwl)) { return IsOverrideInternal(prefab); }
|
||||
}
|
||||
|
||||
|
||||
@@ -73,7 +96,7 @@ namespace Barotrauma
|
||||
private T? basePrefabInternal;
|
||||
private readonly List<T> overrides = new List<T>();
|
||||
|
||||
private T? activePrefabInternal => overrides.Any() ? overrides.First() : basePrefabInternal;
|
||||
private T? activePrefabInternal => overrides.Count > 0 ? overrides.First() : basePrefabInternal;
|
||||
|
||||
private void AddInternal(T prefab, bool isOverride)
|
||||
{
|
||||
@@ -84,7 +107,7 @@ namespace Barotrauma
|
||||
}
|
||||
else
|
||||
{
|
||||
if (BasePrefab != null)
|
||||
if (basePrefabInternal != null)
|
||||
{
|
||||
string prefabName
|
||||
= prefab is MapEntityPrefab mapEntityPrefab
|
||||
@@ -92,7 +115,7 @@ namespace Barotrauma
|
||||
: $"\"{prefab.Identifier}\"";
|
||||
throw new InvalidOperationException(
|
||||
$"Failed to add the prefab {prefabName} ({prefab.GetType()}) from \"{prefab.ContentPackage?.Name ?? "[NULL]"}\" ({prefab.ContentPackage?.Dir ?? ""}): "
|
||||
+ $"a prefab with the same identifier from \"{ActivePrefab!.ContentPackage?.Name ?? "[NULL]"}\" ({ActivePrefab!.ContentPackage?.Dir ?? ""}) already exists; try overriding");
|
||||
+ $"a prefab with the same identifier from \"{activePrefabInternal!.ContentPackage?.Name ?? "[NULL]"}\" ({activePrefabInternal!.ContentPackage?.Dir ?? ""}) already exists; try overriding");
|
||||
}
|
||||
basePrefabInternal = prefab;
|
||||
}
|
||||
@@ -114,31 +137,12 @@ namespace Barotrauma
|
||||
SortInternal();
|
||||
}
|
||||
|
||||
private void RemoveByFileInternal(ContentFile file, Action<T>? callback)
|
||||
{
|
||||
for (int i = overrides.Count-1; i >= 0; i--)
|
||||
{
|
||||
var prefab = overrides[i];
|
||||
if (prefab.ContentFile == file)
|
||||
{
|
||||
RemoveInternal(prefab);
|
||||
callback?.Invoke(prefab);
|
||||
}
|
||||
}
|
||||
|
||||
if (basePrefabInternal is { ContentFile: var baseFile } p && baseFile == file)
|
||||
{
|
||||
RemoveInternal(basePrefabInternal);
|
||||
callback?.Invoke(p);
|
||||
}
|
||||
}
|
||||
|
||||
private void SortInternal()
|
||||
{
|
||||
overrides.Sort((p1, p2) => (p1.ContentPackage?.Index ?? int.MaxValue) - (p2.ContentPackage?.Index ?? int.MaxValue));
|
||||
}
|
||||
|
||||
private bool isEmptyInternal => basePrefabInternal is null && !overrides.Any();
|
||||
private bool isEmptyInternal => basePrefabInternal is null && overrides.Count == 0;
|
||||
|
||||
private bool ContainsInternal(T prefab) => basePrefabInternal == prefab || overrides.Contains(prefab);
|
||||
|
||||
@@ -153,7 +157,7 @@ namespace Barotrauma
|
||||
{
|
||||
T? basePrefab;
|
||||
ImmutableArray<T> overrideClone;
|
||||
lock (overrides)
|
||||
using (new ReadLock(rwl))
|
||||
{
|
||||
basePrefab = basePrefabInternal;
|
||||
overrideClone = overrides.ToImmutableArray();
|
||||
|
||||
Reference in New Issue
Block a user