diff --git a/Assets/UniGLTF/Runtime/Utils/CachedEnum/CachedEnum.cs b/Assets/UniGLTF/Runtime/Utils/CachedEnum/CachedEnum.cs
index 7bf4bd131..8704dc0d0 100644
--- a/Assets/UniGLTF/Runtime/Utils/CachedEnum/CachedEnum.cs
+++ b/Assets/UniGLTF/Runtime/Utils/CachedEnum/CachedEnum.cs
@@ -2,11 +2,22 @@
namespace UniGLTF.Utils
{
+ ///
+ /// CachedEnumType に対するインターフェース。
+ /// 非 Generic class
+ ///
public static class CachedEnum
{
public static T Parse(string name, bool ignoreCase = false) where T : struct, Enum
{
- return CachedEnumType.Parse(name, ignoreCase);
+ if (ignoreCase)
+ {
+ return CachedEnumType.IgnoreCaseMap[name];
+ }
+ else
+ {
+ return CachedEnumType.Map[name];
+ }
}
public static T TryParseOrDefault(string name, bool ignoreCase = false, T defaultValue = default)
@@ -16,7 +27,7 @@ namespace UniGLTF.Utils
{
return Parse(name, ignoreCase: ignoreCase);
}
- catch
+ catch (System.Collections.Generic.KeyNotFoundException)
{
return defaultValue;
}
diff --git a/Assets/UniGLTF/Runtime/Utils/CachedEnum/CachedEnumType.cs b/Assets/UniGLTF/Runtime/Utils/CachedEnum/CachedEnumType.cs
index 8133d2a8e..dc297b3f8 100644
--- a/Assets/UniGLTF/Runtime/Utils/CachedEnum/CachedEnumType.cs
+++ b/Assets/UniGLTF/Runtime/Utils/CachedEnum/CachedEnumType.cs
@@ -3,41 +3,37 @@ using System.Collections.Generic;
namespace UniGLTF.Utils
{
+ ///
+ /// enum T に対する static type caching 。
+ ///
+ /// CachedEnumType.Values
+ /// CachedEnumType.Map
+ /// CachedEnumType.IgnoreCaseMap
+ ///
+ /// がスレッドセーフに(キャッシュされた)同じ値を返す。
+ ///
internal static class CachedEnumType where T : struct, Enum
{
- private static readonly Dictionary _values = new Dictionary();
- private static readonly Dictionary _ignoreCaseValues = new Dictionary(StringComparer.OrdinalIgnoreCase);
- private static T[] _allValues;
+ public readonly static Dictionary Map = CreateStringEnumMap(false);
+ public readonly static Dictionary IgnoreCaseMap = CreateStringEnumMap(true);
+ public readonly static T[] Values = (T[])Enum.GetValues(typeof(T));
- public static T[] Values
+ private static Dictionary CreateStringEnumMap(bool ignoreCase)
{
- get
+ var dict = ignoreCase
+ ? new Dictionary(StringComparer.OrdinalIgnoreCase)
+ : new Dictionary()
+ ;
+
+ // ここで Values を使うと
+ // System.TypeInitializationException
+ // が起きる。
+ // static 変数初期化中に別の static 変数を参照すると未初期化がありえるぽい(初期化順?)
+ foreach (T value in Enum.GetValues(typeof(T)))
{
- if (_allValues == null)
- {
- _allValues = Enum.GetValues(typeof(T)) as T[];
- }
-
- return _allValues;
+ dict.Add(value.ToString(), value);
}
- }
-
- public static T Parse(string name, bool ignoreCase)
- {
- var caches = ignoreCase ? _ignoreCaseValues : _values;
-
- if (caches.TryGetValue(name, out var ignoreCaseValue))
- {
- return ignoreCaseValue;
- }
-
- if (Enum.TryParse(name, ignoreCase, out var result))
- {
- caches.Add(name, result);
- return result;
- }
-
- throw new ArgumentException(name);
+ return dict;
}
}
-}
\ No newline at end of file
+}
diff --git a/Assets/UniGLTF/Tests/UniGLTF/CacheEnumTest.cs b/Assets/UniGLTF/Tests/UniGLTF/CacheEnumTest.cs
index e14ee7919..2018c00ee 100644
--- a/Assets/UniGLTF/Tests/UniGLTF/CacheEnumTest.cs
+++ b/Assets/UniGLTF/Tests/UniGLTF/CacheEnumTest.cs
@@ -1,4 +1,5 @@
-using NUnit.Framework;
+using System.Linq;
+using NUnit.Framework;
using UniGLTF.Utils;
using UnityEngine;
@@ -12,6 +13,7 @@ namespace UniGLTF
{
Assert.AreEqual(default(HumanBodyBones), CachedEnum.TryParseOrDefault("xxx"));
Assert.AreEqual(HumanBodyBones.UpperChest, CachedEnum.TryParseOrDefault("upperchest", true));
+ Assert.AreEqual(CachedEnum.GetValues().First(x => x == HumanBodyBones.Hips), HumanBodyBones.Hips);
}
}
}