//! \file GameRes.cs
//! \date Mon Jun 30 20:12:13 2014
//! \brief game resources browser.
//
// copy-pasted from some post on the stackoverflow.
//
using System;
using System.Collections.Generic;
namespace GameRes.Collections
{
///
/// Extension to the normal Dictionary. This class can store more than one value for every key.
/// It keeps a HashSet for every Key value. Calling Add with the same Key and multiple values
/// will store each value under the same Key in the Dictionary. Obtaining the values for a Key
/// will return the HashSet with the Values of the Key.
///
/// The type of the key.
/// The type of the value.
public class MultiValueDictionary : Dictionary> //, IEnumerable>, System.Collections.IEnumerable
{
///
/// Initializes a new instance of the class.
///
public MultiValueDictionary() : base()
{
}
///
/// Adds the specified value under the specified key
///
/// The key.
/// The value.
public void Add(TKey key, TValue value)
{
HashSet container = null;
if(!this.TryGetValue(key, out container))
{
container = new HashSet();
base.Add(key, container);
}
container.Add(value);
}
///
/// Removes the specified value for the specified key. It will leave the key in the dictionary.
///
/// The key.
/// The value.
public void Remove(TKey key, TValue value)
{
HashSet container = null;
if(this.TryGetValue(key, out container))
{
container.Remove(value);
if(container.Count <= 0)
{
this.Remove(key);
}
}
}
///
/// Gets the values for the key specified. This method is useful if you want to avoid an
/// exception for key value retrieval and you can't use TryGetValue (e.g. in lambdas)
///
/// The key.
/// if set to true and the key isn't found, an empty hashset is
/// returned, otherwise, if the key isn't found, null is returned
///
/// This method will return null (or an empty set if returnEmptySet is true) if the key
/// wasn't found, or the values if key was found.
///
public HashSet GetValues(TKey key, bool returnEmptySet)
{
HashSet toReturn = null;
if (!base.TryGetValue(key, out toReturn) && returnEmptySet)
{
toReturn = new HashSet();
}
return toReturn;
}
/*
// hides Dictionary.GetEnumerator()
new public IEnumerator> GetEnumerator()
{
Enumerator e = new Enumerator();
e.key_enumerator = base.GetEnumerator();
e.current_pair = new KeyValuePair();
if (e.key_enumerator.MoveNext())
e.value_enumerator = e.key_enumerator.Current.Value.GetEnumerator();
else
e.value_enumerator = null;
return e;
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return (System.Collections.IEnumerator)GetEnumerator();
}
[SerializableAttribute]
new public struct Enumerator : IEnumerator>, IDisposable, System.Collections.IEnumerator
{
public Dictionary>.Enumerator key_enumerator;
public HashSet.Enumerator? value_enumerator;
public KeyValuePair current_pair;
public KeyValuePair Current { get { return current_pair; } }
object System.Collections.IEnumerator.Current { get { return Current; } }
void IDisposable.Dispose() { }
void System.Collections.IEnumerator.Reset()
{
}
private void SetCurrent ()
{
current_pair = new KeyValuePair(key_enumerator.Current.Key, value_enumerator.Value.Current);
Console.WriteLine("Enumerator.SetCurrent ({0} => {1})", current_pair.Key, current_pair.Value);
}
private void ResetCurrent ()
{
current_pair = new KeyValuePair(default(TKey), default(TValue));
}
public bool MoveNext ()
{
if (null == value_enumerator)
{
ResetCurrent();
return false;
}
if (value_enumerator.Value.MoveNext())
{
SetCurrent();
return true;
}
if (!key_enumerator.MoveNext())
{
value_enumerator = null;
ResetCurrent();
return false;
}
value_enumerator = key_enumerator.Current.Value.GetEnumerator();
if (value_enumerator.Value.MoveNext())
{
SetCurrent();
return true;
}
else
{
current_pair = new KeyValuePair(key_enumerator.Current.Key, default(TValue));
return false;
}
}
}
*/
}
}