//-----------------------------------------------------------------------
//
// Copyright (c) 2018 Sirenix IVS
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
//-----------------------------------------------------------------------
namespace VRC.Udon.Serialization.OdinSerializer.Utilities
{
using System;
using System.Collections.Generic;
///
/// Not yet documented.
///
[Serializable]
public class DoubleLookupDictionary : Dictionary>
{
private readonly IEqualityComparer secondKeyComparer;
public DoubleLookupDictionary()
{
this.secondKeyComparer = EqualityComparer.Default;
}
public DoubleLookupDictionary(IEqualityComparer firstKeyComparer, IEqualityComparer secondKeyComparer)
: base(firstKeyComparer)
{
this.secondKeyComparer = secondKeyComparer;
}
///
/// Not yet documented.
///
public new Dictionary this[TFirstKey firstKey]
{
get
{
Dictionary innerDict;
if (!this.TryGetValue(firstKey, out innerDict))
{
innerDict = new Dictionary(this.secondKeyComparer);
this.Add(firstKey, innerDict);
}
return innerDict;
}
}
///
/// Not yet documented.
///
public int InnerCount(TFirstKey firstKey)
{
Dictionary innerDict;
if (this.TryGetValue(firstKey, out innerDict))
{
return innerDict.Count;
}
return 0;
}
///
/// Not yet documented.
///
public int TotalInnerCount()
{
int count = 0;
if (this.Count > 0)
{
foreach (var innerDict in this.Values)
{
count += innerDict.Count;
}
}
return count;
}
///
/// Not yet documented.
///
public bool ContainsKeys(TFirstKey firstKey, TSecondKey secondKey)
{
Dictionary innerDict;
return this.TryGetValue(firstKey, out innerDict) && innerDict.ContainsKey(secondKey);
}
///
/// Not yet documented.
///
public bool TryGetInnerValue(TFirstKey firstKey, TSecondKey secondKey, out TValue value)
{
Dictionary innerDict;
if (this.TryGetValue(firstKey, out innerDict) && innerDict.TryGetValue(secondKey, out value))
{
return true;
}
value = default(TValue);
return false;
}
///
/// Not yet documented.
///
public TValue AddInner(TFirstKey firstKey, TSecondKey secondKey, TValue value)
{
if (this.ContainsKeys(firstKey, secondKey))
{
throw new ArgumentException("An element with the same keys already exists in the " + this.GetType().GetNiceName() + ".");
}
return this[firstKey][secondKey] = value;
}
///
/// Not yet documented.
///
public bool RemoveInner(TFirstKey firstKey, TSecondKey secondKey)
{
Dictionary innerDict;
if (this.TryGetValue(firstKey, out innerDict))
{
bool removed = innerDict.Remove(secondKey);
if (innerDict.Count == 0)
{
this.Remove(firstKey);
}
return removed;
}
return false;
}
///
/// Not yet documented.
///
public void RemoveWhere(Func predicate)
{
List toRemoveBufferFirstKey = new List();
List toRemoveBufferSecondKey = new List();
foreach (var outerDictionary in this.GFIterator())
{
foreach (var innerKeyPair in outerDictionary.Value.GFIterator())
{
if (predicate(innerKeyPair.Value))
{
toRemoveBufferFirstKey.Add(outerDictionary.Key);
toRemoveBufferSecondKey.Add(innerKeyPair.Key);
}
}
}
for (int i = 0; i < toRemoveBufferFirstKey.Count; i++)
{
this.RemoveInner(toRemoveBufferFirstKey[i], toRemoveBufferSecondKey[i]);
}
}
}
}