Expand on MetaDictionary to use separate dictionaries.

This commit is contained in:
Ottermandias 2024-06-08 16:06:37 +02:00
parent d7b60206d7
commit 94fdd848b7
15 changed files with 257 additions and 36 deletions

View file

@ -1,19 +1,237 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Penumbra.GameData.Structs;
using Penumbra.Util;
using ImcEntry = Penumbra.GameData.Structs.ImcEntry;
namespace Penumbra.Meta.Manipulations;
[JsonConverter(typeof(Converter))]
public sealed class MetaDictionary : HashSet<MetaManipulation>
public sealed class MetaDictionary : IEnumerable<MetaManipulation>
{
public MetaDictionary()
{ }
private readonly Dictionary<ImcIdentifier, ImcEntry> _imc = [];
private readonly Dictionary<EqpIdentifier, EqpEntry> _eqp = [];
private readonly Dictionary<EqdpIdentifier, EqdpEntry> _eqdp = [];
private readonly Dictionary<EstIdentifier, EstEntry> _est = [];
private readonly Dictionary<RspIdentifier, RspEntry> _rsp = [];
private readonly Dictionary<GmpIdentifier, GmpEntry> _gmp = [];
private readonly HashSet<GlobalEqpManipulation> _globalEqp = [];
public MetaDictionary(int capacity)
: base(capacity)
{ }
public int Count { get; private set; }
public void Clear()
{
_imc.Clear();
_eqp.Clear();
_eqdp.Clear();
_est.Clear();
_rsp.Clear();
_gmp.Clear();
_globalEqp.Clear();
}
public IEnumerator<MetaManipulation> GetEnumerator()
=> _imc.Select(kvp => new MetaManipulation(new ImcManipulation(kvp.Key, kvp.Value)))
.Concat(_eqp.Select(kvp => new MetaManipulation(new EqpManipulation(kvp.Key, kvp.Value))))
.Concat(_eqdp.Select(kvp => new MetaManipulation(new EqdpManipulation(kvp.Key, kvp.Value))))
.Concat(_est.Select(kvp => new MetaManipulation(new EstManipulation(kvp.Key, kvp.Value))))
.Concat(_rsp.Select(kvp => new MetaManipulation(new RspManipulation(kvp.Key, kvp.Value))))
.Concat(_gmp.Select(kvp => new MetaManipulation(new GmpManipulation(kvp.Key, kvp.Value))))
.Concat(_globalEqp.Select(manip => new MetaManipulation(manip))).GetEnumerator();
IEnumerator IEnumerable.GetEnumerator()
=> GetEnumerator();
public bool Add(MetaManipulation manip)
{
var ret = manip.ManipulationType switch
{
MetaManipulation.Type.Imc => _imc.TryAdd(manip.Imc.Identifier, manip.Imc.Entry),
MetaManipulation.Type.Eqdp => _eqdp.TryAdd(manip.Eqdp.Identifier, manip.Eqdp.Entry),
MetaManipulation.Type.Eqp => _eqp.TryAdd(manip.Eqp.Identifier, manip.Eqp.Entry),
MetaManipulation.Type.Est => _est.TryAdd(manip.Est.Identifier, manip.Est.Entry),
MetaManipulation.Type.Gmp => _gmp.TryAdd(manip.Gmp.Identifier, manip.Gmp.Entry),
MetaManipulation.Type.Rsp => _rsp.TryAdd(manip.Rsp.Identifier, manip.Rsp.Entry),
MetaManipulation.Type.GlobalEqp => _globalEqp.Add(manip.GlobalEqp),
_ => false,
};
if (ret)
++Count;
return ret;
}
public bool TryAdd(ImcIdentifier identifier, ImcEntry entry)
{
if (!_imc.TryAdd(identifier, entry))
return false;
++Count;
return true;
}
public bool TryAdd(EqpIdentifier identifier, EqpEntry entry)
{
if (!_eqp.TryAdd(identifier, entry))
return false;
++Count;
return true;
}
public bool TryAdd(EqdpIdentifier identifier, EqdpEntry entry)
{
if (!_eqdp.TryAdd(identifier, entry))
return false;
++Count;
return true;
}
public bool TryAdd(EstIdentifier identifier, EstEntry entry)
{
if (!_est.TryAdd(identifier, entry))
return false;
++Count;
return true;
}
public bool TryAdd(GmpIdentifier identifier, GmpEntry entry)
{
if (!_gmp.TryAdd(identifier, entry))
return false;
++Count;
return true;
}
public bool TryAdd(RspIdentifier identifier, RspEntry entry)
{
if (!_rsp.TryAdd(identifier, entry))
return false;
++Count;
return true;
}
public bool TryAdd(GlobalEqpManipulation identifier)
{
if (!_globalEqp.Add(identifier))
return false;
++Count;
return true;
}
public bool Remove(MetaManipulation manip)
{
var ret = manip.ManipulationType switch
{
MetaManipulation.Type.Imc => _imc.Remove(manip.Imc.Identifier),
MetaManipulation.Type.Eqdp => _eqdp.Remove(manip.Eqdp.Identifier),
MetaManipulation.Type.Eqp => _eqp.Remove(manip.Eqp.Identifier),
MetaManipulation.Type.Est => _est.Remove(manip.Est.Identifier),
MetaManipulation.Type.Gmp => _gmp.Remove(manip.Gmp.Identifier),
MetaManipulation.Type.Rsp => _rsp.Remove(manip.Rsp.Identifier),
MetaManipulation.Type.GlobalEqp => _globalEqp.Remove(manip.GlobalEqp),
_ => false,
};
if (ret)
--Count;
return ret;
}
public void UnionWith(IEnumerable<MetaManipulation> manips)
{
foreach (var manip in manips)
Add(manip);
}
public bool TryGetValue(MetaManipulation identifier, out MetaManipulation oldValue)
{
switch (identifier.ManipulationType)
{
case MetaManipulation.Type.Imc:
if (_imc.TryGetValue(identifier.Imc.Identifier, out var oldImc))
{
oldValue = new MetaManipulation(new ImcManipulation(identifier.Imc.Identifier, oldImc));
return true;
}
break;
case MetaManipulation.Type.Eqdp:
if (_eqp.TryGetValue(identifier.Eqp.Identifier, out var oldEqdp))
{
oldValue = new MetaManipulation(new EqpManipulation(identifier.Eqp.Identifier, oldEqdp));
return true;
}
break;
case MetaManipulation.Type.Eqp:
if (_eqdp.TryGetValue(identifier.Eqdp.Identifier, out var oldEqp))
{
oldValue = new MetaManipulation(new EqdpManipulation(identifier.Eqdp.Identifier, oldEqp));
return true;
}
break;
case MetaManipulation.Type.Est:
if (_est.TryGetValue(identifier.Est.Identifier, out var oldEst))
{
oldValue = new MetaManipulation(new EstManipulation(identifier.Est.Identifier, oldEst));
return true;
}
break;
case MetaManipulation.Type.Gmp:
if (_gmp.TryGetValue(identifier.Gmp.Identifier, out var oldGmp))
{
oldValue = new MetaManipulation(new GmpManipulation(identifier.Gmp.Identifier, oldGmp));
return true;
}
break;
case MetaManipulation.Type.Rsp:
if (_rsp.TryGetValue(identifier.Rsp.Identifier, out var oldRsp))
{
oldValue = new MetaManipulation(new RspManipulation(identifier.Rsp.Identifier, oldRsp));
return true;
}
break;
case MetaManipulation.Type.GlobalEqp:
if (_globalEqp.TryGetValue(identifier.GlobalEqp, out var oldGlobalEqp))
{
oldValue = new MetaManipulation(oldGlobalEqp);
return true;
}
break;
}
oldValue = default;
return false;
}
public void SetTo(MetaDictionary other)
{
_imc.SetTo(other._imc);
_eqp.SetTo(other._eqp);
_eqdp.SetTo(other._eqdp);
_est.SetTo(other._est);
_rsp.SetTo(other._rsp);
_gmp.SetTo(other._gmp);
_globalEqp.SetTo(other._globalEqp);
Count = _imc.Count + _eqp.Count + _eqdp.Count + _est.Count + _rsp.Count + _gmp.Count + _globalEqp.Count;
}
public MetaDictionary Clone()
{
var ret = new MetaDictionary();
ret.SetTo(this);
return ret;
}
private class Converter : JsonConverter<MetaDictionary>
{
@ -67,7 +285,7 @@ public sealed class MetaDictionary : HashSet<MetaManipulation>
var identifier = ImcIdentifier.FromJson(manip);
var entry = manip["Entry"]?.ToObject<ImcEntry>();
if (identifier.HasValue && entry.HasValue)
dict.Add(new MetaManipulation(new ImcManipulation(identifier.Value, entry.Value)));
dict.TryAdd(identifier.Value, entry.Value);
else
Penumbra.Log.Warning("Invalid IMC Manipulation encountered.");
break;
@ -77,7 +295,7 @@ public sealed class MetaDictionary : HashSet<MetaManipulation>
var identifier = EqdpIdentifier.FromJson(manip);
var entry = (EqdpEntry?)manip["Entry"]?.ToObject<ushort>();
if (identifier.HasValue && entry.HasValue)
dict.Add(new MetaManipulation(new EqdpManipulation(identifier.Value, entry.Value)));
dict.TryAdd(identifier.Value, entry.Value);
else
Penumbra.Log.Warning("Invalid EQDP Manipulation encountered.");
break;
@ -87,7 +305,7 @@ public sealed class MetaDictionary : HashSet<MetaManipulation>
var identifier = EqpIdentifier.FromJson(manip);
var entry = (EqpEntry?)manip["Entry"]?.ToObject<ulong>();
if (identifier.HasValue && entry.HasValue)
dict.Add(new MetaManipulation(new EqpManipulation(identifier.Value, entry.Value)));
dict.TryAdd(identifier.Value, entry.Value);
else
Penumbra.Log.Warning("Invalid EQP Manipulation encountered.");
break;
@ -97,7 +315,7 @@ public sealed class MetaDictionary : HashSet<MetaManipulation>
var identifier = EstIdentifier.FromJson(manip);
var entry = manip["Entry"]?.ToObject<EstEntry>();
if (identifier.HasValue && entry.HasValue)
dict.Add(new MetaManipulation(new EstManipulation(identifier.Value, entry.Value)));
dict.TryAdd(identifier.Value, entry.Value);
else
Penumbra.Log.Warning("Invalid EST Manipulation encountered.");
break;
@ -107,7 +325,7 @@ public sealed class MetaDictionary : HashSet<MetaManipulation>
var identifier = GmpIdentifier.FromJson(manip);
var entry = manip["Entry"]?.ToObject<GmpEntry>();
if (identifier.HasValue && entry.HasValue)
dict.Add(new MetaManipulation(new GmpManipulation(identifier.Value, entry.Value)));
dict.TryAdd(identifier.Value, entry.Value);
else
Penumbra.Log.Warning("Invalid GMP Manipulation encountered.");
break;
@ -117,7 +335,7 @@ public sealed class MetaDictionary : HashSet<MetaManipulation>
var identifier = RspIdentifier.FromJson(manip);
var entry = manip["Entry"]?.ToObject<RspEntry>();
if (identifier.HasValue && entry.HasValue)
dict.Add(new MetaManipulation(new RspManipulation(identifier.Value, entry.Value)));
dict.TryAdd(identifier.Value, entry.Value);
else
Penumbra.Log.Warning("Invalid RSP Manipulation encountered.");
break;
@ -126,7 +344,7 @@ public sealed class MetaDictionary : HashSet<MetaManipulation>
{
var identifier = GlobalEqpManipulation.FromJson(manip);
if (identifier.HasValue)
dict.Add(new MetaManipulation(identifier.Value));
dict.TryAdd(identifier.Value);
else
Penumbra.Log.Warning("Invalid Global EQP Manipulation encountered.");
break;