您最多选择25个主题
主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
92 行
3.3 KiB
92 行
3.3 KiB
using System;
|
|
using System.Collections.Generic;
|
|
|
|
namespace UnityEngine.Perception.Randomization.Randomizers
|
|
{
|
|
/// <summary>
|
|
/// Organizes RandomizerTags present in the scene
|
|
/// </summary>
|
|
public class RandomizerTagManager
|
|
{
|
|
/// <summary>
|
|
/// Returns the singleton RandomizerTagManager instance
|
|
/// </summary>
|
|
public static RandomizerTagManager singleton { get; } = new RandomizerTagManager();
|
|
|
|
Dictionary<Type, HashSet<Type>> m_TypeTree = new Dictionary<Type, HashSet<Type>>();
|
|
Dictionary<Type, LinkedHashSet<RandomizerTag>> m_TagMap = new Dictionary<Type, LinkedHashSet<RandomizerTag>>();
|
|
|
|
/// <summary>
|
|
/// Enumerates over all RandomizerTags of the given type present in the scene
|
|
/// </summary>
|
|
/// <typeparam name="T">The type of RandomizerTag to query for</typeparam>
|
|
/// <param name="returnSubclasses">Should this method retrieve all tags derived from the passed in tag also?</param>
|
|
/// <returns>RandomizerTags of the given type</returns>
|
|
public IEnumerable<T> Query<T>(bool returnSubclasses = false) where T : RandomizerTag
|
|
{
|
|
var queriedTagType = typeof(T);
|
|
if (!m_TagMap.ContainsKey(queriedTagType))
|
|
yield break;
|
|
|
|
if (returnSubclasses)
|
|
{
|
|
var typeStack = new Stack<Type>();
|
|
typeStack.Push(queriedTagType);
|
|
while (typeStack.Count > 0)
|
|
{
|
|
var tagType = typeStack.Pop();
|
|
foreach (var derivedType in m_TypeTree[tagType])
|
|
typeStack.Push(derivedType);
|
|
foreach (var tag in m_TagMap[tagType])
|
|
yield return (T)tag;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
foreach (var tag in m_TagMap[queriedTagType])
|
|
yield return (T)tag;
|
|
}
|
|
}
|
|
|
|
internal void AddTag<T>(T tag) where T : RandomizerTag
|
|
{
|
|
var tagType = tag.GetType();
|
|
AddTagTypeToTypeHierarchy(tagType);
|
|
m_TagMap[tagType].Add(tag);
|
|
}
|
|
|
|
void AddTagTypeToTypeHierarchy(Type tagType)
|
|
{
|
|
if (m_TypeTree.ContainsKey(tagType))
|
|
return;
|
|
|
|
m_TagMap.Add(tagType, new LinkedHashSet<RandomizerTag>());
|
|
m_TypeTree.Add(tagType, new HashSet<Type>());
|
|
|
|
var baseType = tagType.BaseType;
|
|
while (baseType != null && baseType != typeof(RandomizerTag))
|
|
{
|
|
if (!m_TypeTree.ContainsKey(baseType))
|
|
{
|
|
m_TagMap.Add(baseType, new LinkedHashSet<RandomizerTag>());
|
|
m_TypeTree[baseType] = new HashSet<Type> { tagType };
|
|
}
|
|
else
|
|
{
|
|
m_TypeTree[baseType].Add(tagType);
|
|
break;
|
|
}
|
|
|
|
tagType = baseType;
|
|
baseType = tagType.BaseType;
|
|
}
|
|
}
|
|
|
|
internal void RemoveTag<T>(T tag) where T : RandomizerTag
|
|
{
|
|
var tagType = tag.GetType();
|
|
if (m_TagMap.ContainsKey(tagType) && m_TagMap[tagType].Contains(tag))
|
|
m_TagMap[tagType].Remove(tag);
|
|
}
|
|
}
|
|
}
|