Initial Commit
This commit is contained in:
@@ -0,0 +1,433 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using Zenject;
|
||||
|
||||
namespace ModestTree
|
||||
{
|
||||
public static class Assert
|
||||
{
|
||||
#if ZEN_STRIP_ASSERTS_IN_BUILDS
|
||||
[Conditional("UNITY_EDITOR")]
|
||||
#endif
|
||||
public static void That(bool condition)
|
||||
{
|
||||
if (!condition)
|
||||
{
|
||||
throw CreateException("Assert hit!");
|
||||
}
|
||||
}
|
||||
|
||||
#if ZEN_STRIP_ASSERTS_IN_BUILDS
|
||||
[Conditional("UNITY_EDITOR")]
|
||||
#endif
|
||||
public static void IsNotEmpty(string str)
|
||||
{
|
||||
if (String.IsNullOrEmpty(str))
|
||||
{
|
||||
throw CreateException("Unexpected null or empty string");
|
||||
}
|
||||
}
|
||||
|
||||
#if ZEN_STRIP_ASSERTS_IN_BUILDS
|
||||
[Conditional("UNITY_EDITOR")]
|
||||
#endif
|
||||
// This is better because IsEmpty with IEnumerable causes a memory alloc
|
||||
public static void IsEmpty<T>(IList<T> list)
|
||||
{
|
||||
if (list.Count != 0)
|
||||
{
|
||||
throw CreateException(
|
||||
"Expected collection to be empty but instead found '{0}' elements", list.Count);
|
||||
}
|
||||
}
|
||||
|
||||
#if ZEN_STRIP_ASSERTS_IN_BUILDS
|
||||
[Conditional("UNITY_EDITOR")]
|
||||
#endif
|
||||
public static void IsEmpty<T>(IEnumerable<T> sequence)
|
||||
{
|
||||
if (!sequence.IsEmpty())
|
||||
{
|
||||
throw CreateException("Expected collection to be empty but instead found '{0}' elements",
|
||||
sequence.Count());
|
||||
}
|
||||
}
|
||||
|
||||
#if ZEN_STRIP_ASSERTS_IN_BUILDS
|
||||
[Conditional("UNITY_EDITOR")]
|
||||
#endif
|
||||
public static void IsType<T>(object obj)
|
||||
{
|
||||
IsType<T>(obj, "");
|
||||
}
|
||||
|
||||
#if ZEN_STRIP_ASSERTS_IN_BUILDS
|
||||
[Conditional("UNITY_EDITOR")]
|
||||
#endif
|
||||
public static void IsType<T>(object obj, string message)
|
||||
{
|
||||
if (!(obj is T))
|
||||
{
|
||||
throw CreateException("Assert Hit! {0}\nWrong type found. Expected '{1}' (left) but found '{2}' (right). ", message, typeof(T).PrettyName(), obj.GetType().PrettyName());
|
||||
}
|
||||
}
|
||||
|
||||
#if ZEN_STRIP_ASSERTS_IN_BUILDS
|
||||
[Conditional("UNITY_EDITOR")]
|
||||
#endif
|
||||
public static void DerivesFrom<T>(Type type)
|
||||
{
|
||||
if (!type.DerivesFrom<T>())
|
||||
{
|
||||
throw CreateException("Expected type '{0}' to derive from '{1}'", type.Name, typeof(T).Name);
|
||||
}
|
||||
}
|
||||
|
||||
#if ZEN_STRIP_ASSERTS_IN_BUILDS
|
||||
[Conditional("UNITY_EDITOR")]
|
||||
#endif
|
||||
public static void DerivesFromOrEqual<T>(Type type)
|
||||
{
|
||||
if (!type.DerivesFromOrEqual<T>())
|
||||
{
|
||||
throw CreateException("Expected type '{0}' to derive from or be equal to '{1}'", type.Name, typeof(T).Name);
|
||||
}
|
||||
}
|
||||
|
||||
#if ZEN_STRIP_ASSERTS_IN_BUILDS
|
||||
[Conditional("UNITY_EDITOR")]
|
||||
#endif
|
||||
public static void DerivesFrom(Type childType, Type parentType)
|
||||
{
|
||||
if (!childType.DerivesFrom(parentType))
|
||||
{
|
||||
throw CreateException("Expected type '{0}' to derive from '{1}'", childType.Name, parentType.Name);
|
||||
}
|
||||
}
|
||||
|
||||
#if ZEN_STRIP_ASSERTS_IN_BUILDS
|
||||
[Conditional("UNITY_EDITOR")]
|
||||
#endif
|
||||
public static void DerivesFromOrEqual(Type childType, Type parentType)
|
||||
{
|
||||
if (!childType.DerivesFromOrEqual(parentType))
|
||||
{
|
||||
throw CreateException("Expected type '{0}' to derive from or be equal to '{1}'", childType.Name, parentType.Name);
|
||||
}
|
||||
}
|
||||
|
||||
// Use AssertEquals to get better error output (with values)
|
||||
#if ZEN_STRIP_ASSERTS_IN_BUILDS
|
||||
[Conditional("UNITY_EDITOR")]
|
||||
#endif
|
||||
public static void IsEqual(object left, object right)
|
||||
{
|
||||
IsEqual(left, right, "");
|
||||
}
|
||||
|
||||
// Use AssertEquals to get better error output (with values)
|
||||
#if ZEN_STRIP_ASSERTS_IN_BUILDS
|
||||
[Conditional("UNITY_EDITOR")]
|
||||
#endif
|
||||
public static void IsEqual(object left, object right, Func<string> messageGenerator)
|
||||
{
|
||||
if (!object.Equals(left, right))
|
||||
{
|
||||
left = left ?? "<NULL>";
|
||||
right = right ?? "<NULL>";
|
||||
throw CreateException("Assert Hit! {0}. Expected '{1}' (left) but found '{2}' (right). ", messageGenerator(), left, right);
|
||||
}
|
||||
}
|
||||
|
||||
#if ZEN_STRIP_ASSERTS_IN_BUILDS
|
||||
[Conditional("UNITY_EDITOR")]
|
||||
#endif
|
||||
public static void IsApproximately(float left, float right, float epsilon = 0.00001f)
|
||||
{
|
||||
bool isEqual = Math.Abs(left - right) < epsilon;
|
||||
|
||||
if (!isEqual)
|
||||
{
|
||||
throw CreateException("Assert Hit! Expected '{0}' (left) but found '{1}' (right). ", left, right);
|
||||
}
|
||||
}
|
||||
|
||||
// Use AssertEquals to get better error output (with values)
|
||||
#if ZEN_STRIP_ASSERTS_IN_BUILDS
|
||||
[Conditional("UNITY_EDITOR")]
|
||||
#endif
|
||||
public static void IsEqual(object left, object right, string message)
|
||||
{
|
||||
if (!object.Equals(left, right))
|
||||
{
|
||||
left = left ?? "<NULL>";
|
||||
right = right ?? "<NULL>";
|
||||
throw CreateException("Assert Hit! {0}\nExpected '{1}' (left) but found '{2}' (right). ", message, left, right);
|
||||
}
|
||||
}
|
||||
|
||||
// Use Assert.IsNotEqual to get better error output (with values)
|
||||
#if ZEN_STRIP_ASSERTS_IN_BUILDS
|
||||
[Conditional("UNITY_EDITOR")]
|
||||
#endif
|
||||
public static void IsNotEqual(object left, object right)
|
||||
{
|
||||
IsNotEqual(left, right, "");
|
||||
}
|
||||
|
||||
// Use Assert.IsNotEqual to get better error output (with values)
|
||||
#if ZEN_STRIP_ASSERTS_IN_BUILDS
|
||||
[Conditional("UNITY_EDITOR")]
|
||||
#endif
|
||||
public static void IsNotEqual(object left, object right, Func<string> messageGenerator)
|
||||
{
|
||||
if(object.Equals(left, right))
|
||||
{
|
||||
left = left ?? "<NULL>";
|
||||
right = right ?? "<NULL>";
|
||||
throw CreateException("Assert Hit! {0}. Expected '{1}' (left) to differ from '{2}' (right). ", messageGenerator(), left, right);
|
||||
}
|
||||
}
|
||||
|
||||
#if ZEN_STRIP_ASSERTS_IN_BUILDS
|
||||
[Conditional("UNITY_EDITOR")]
|
||||
#endif
|
||||
public static void IsNull(object val)
|
||||
{
|
||||
if (val != null)
|
||||
{
|
||||
throw CreateException(
|
||||
"Assert Hit! Expected null pointer but instead found '{0}'", val);
|
||||
}
|
||||
}
|
||||
|
||||
#if ZEN_STRIP_ASSERTS_IN_BUILDS
|
||||
[Conditional("UNITY_EDITOR")]
|
||||
#endif
|
||||
public static void IsNull(object val, string message)
|
||||
{
|
||||
if (val != null)
|
||||
{
|
||||
throw CreateException(
|
||||
"Assert Hit! {0}", message);
|
||||
}
|
||||
}
|
||||
|
||||
// We don't use params here to avoid the memory alloc
|
||||
#if ZEN_STRIP_ASSERTS_IN_BUILDS
|
||||
[Conditional("UNITY_EDITOR")]
|
||||
#endif
|
||||
public static void IsNull(object val, string message, object p1)
|
||||
{
|
||||
if (val != null)
|
||||
{
|
||||
throw CreateException(
|
||||
"Assert Hit! {0}", message.Fmt(p1));
|
||||
}
|
||||
}
|
||||
|
||||
#if ZEN_STRIP_ASSERTS_IN_BUILDS
|
||||
[Conditional("UNITY_EDITOR")]
|
||||
#endif
|
||||
public static void IsNotNull(object val)
|
||||
{
|
||||
if (val == null)
|
||||
{
|
||||
throw CreateException("Assert Hit! Found null pointer when value was expected");
|
||||
}
|
||||
}
|
||||
|
||||
#if ZEN_STRIP_ASSERTS_IN_BUILDS
|
||||
[Conditional("UNITY_EDITOR")]
|
||||
#endif
|
||||
public static void IsNotNull(object val, string message)
|
||||
{
|
||||
if (val == null)
|
||||
{
|
||||
throw CreateException("Assert Hit! {0}", message);
|
||||
}
|
||||
}
|
||||
|
||||
// We don't use params here to avoid the memory alloc
|
||||
#if ZEN_STRIP_ASSERTS_IN_BUILDS
|
||||
[Conditional("UNITY_EDITOR")]
|
||||
#endif
|
||||
public static void IsNotNull(object val, string message, object p1)
|
||||
{
|
||||
if (val == null)
|
||||
{
|
||||
throw CreateException("Assert Hit! {0}", message.Fmt(p1));
|
||||
}
|
||||
}
|
||||
|
||||
// We don't use params here to avoid the memory alloc
|
||||
#if ZEN_STRIP_ASSERTS_IN_BUILDS
|
||||
[Conditional("UNITY_EDITOR")]
|
||||
#endif
|
||||
public static void IsNotNull(object val, string message, object p1, object p2)
|
||||
{
|
||||
if (val == null)
|
||||
{
|
||||
throw CreateException("Assert Hit! {0}", message.Fmt(p1, p2));
|
||||
}
|
||||
}
|
||||
|
||||
#if ZEN_STRIP_ASSERTS_IN_BUILDS
|
||||
[Conditional("UNITY_EDITOR")]
|
||||
#endif
|
||||
public static void IsNotEmpty<T>(IEnumerable<T> val, string message = "")
|
||||
{
|
||||
if (!val.Any())
|
||||
{
|
||||
throw CreateException("Assert Hit! Expected empty collection but found {0} values. {1}", val.Count(), message);
|
||||
}
|
||||
}
|
||||
|
||||
// Use Assert.IsNotEqual to get better error output (with values)
|
||||
#if ZEN_STRIP_ASSERTS_IN_BUILDS
|
||||
[Conditional("UNITY_EDITOR")]
|
||||
#endif
|
||||
public static void IsNotEqual(object left, object right, string message)
|
||||
{
|
||||
if (object.Equals(left, right))
|
||||
{
|
||||
left = left ?? "<NULL>";
|
||||
right = right ?? "<NULL>";
|
||||
throw CreateException("Assert Hit! {0}. Unexpected value found '{1}'. ", message, left);
|
||||
}
|
||||
}
|
||||
|
||||
#if ZEN_STRIP_ASSERTS_IN_BUILDS
|
||||
[Conditional("UNITY_EDITOR")]
|
||||
#endif
|
||||
public static void Warn(bool condition)
|
||||
{
|
||||
if (!condition)
|
||||
{
|
||||
ModestTree.Log.Warn("Warning! See call stack");
|
||||
}
|
||||
}
|
||||
|
||||
#if ZEN_STRIP_ASSERTS_IN_BUILDS
|
||||
[Conditional("UNITY_EDITOR")]
|
||||
#endif
|
||||
public static void Warn(bool condition, Func<string> messageGenerator)
|
||||
{
|
||||
if (!condition)
|
||||
{
|
||||
ModestTree.Log.Warn("Warning Assert hit! " + messageGenerator());
|
||||
}
|
||||
}
|
||||
|
||||
#if ZEN_STRIP_ASSERTS_IN_BUILDS
|
||||
[Conditional("UNITY_EDITOR")]
|
||||
#endif
|
||||
public static void That(
|
||||
bool condition, string message)
|
||||
{
|
||||
if (!condition)
|
||||
{
|
||||
throw CreateException("Assert hit! " + message);
|
||||
}
|
||||
}
|
||||
|
||||
// We don't use params here to avoid the memory alloc
|
||||
#if ZEN_STRIP_ASSERTS_IN_BUILDS
|
||||
[Conditional("UNITY_EDITOR")]
|
||||
#endif
|
||||
public static void That(
|
||||
bool condition, string message, object p1)
|
||||
{
|
||||
if (!condition)
|
||||
{
|
||||
throw CreateException("Assert hit! " + message.Fmt(p1));
|
||||
}
|
||||
}
|
||||
|
||||
// We don't use params here to avoid the memory alloc
|
||||
#if ZEN_STRIP_ASSERTS_IN_BUILDS
|
||||
[Conditional("UNITY_EDITOR")]
|
||||
#endif
|
||||
public static void That(
|
||||
bool condition, string message, object p1, object p2)
|
||||
{
|
||||
if (!condition)
|
||||
{
|
||||
throw CreateException("Assert hit! " + message.Fmt(p1, p2));
|
||||
}
|
||||
}
|
||||
|
||||
// We don't use params here to avoid the memory alloc
|
||||
#if ZEN_STRIP_ASSERTS_IN_BUILDS
|
||||
[Conditional("UNITY_EDITOR")]
|
||||
#endif
|
||||
public static void That(
|
||||
bool condition, string message, object p1, object p2, object p3)
|
||||
{
|
||||
if (!condition)
|
||||
{
|
||||
throw CreateException("Assert hit! " + message.Fmt(p1, p2, p3));
|
||||
}
|
||||
}
|
||||
|
||||
#if ZEN_STRIP_ASSERTS_IN_BUILDS
|
||||
[Conditional("UNITY_EDITOR")]
|
||||
#endif
|
||||
public static void Warn(bool condition, string message)
|
||||
{
|
||||
if (!condition)
|
||||
{
|
||||
ModestTree.Log.Warn("Warning Assert hit! " + message);
|
||||
}
|
||||
}
|
||||
|
||||
#if ZEN_STRIP_ASSERTS_IN_BUILDS
|
||||
[Conditional("UNITY_EDITOR")]
|
||||
#endif
|
||||
public static void Throws(Action action)
|
||||
{
|
||||
Throws<Exception>(action);
|
||||
}
|
||||
|
||||
#if ZEN_STRIP_ASSERTS_IN_BUILDS
|
||||
[Conditional("UNITY_EDITOR")]
|
||||
#endif
|
||||
public static void Throws<TException>(Action action)
|
||||
where TException : Exception
|
||||
{
|
||||
try
|
||||
{
|
||||
action();
|
||||
}
|
||||
catch (TException)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
throw CreateException(
|
||||
"Expected to receive exception of type '{0}' but nothing was thrown", typeof(TException).Name);
|
||||
}
|
||||
|
||||
public static ZenjectException CreateException()
|
||||
{
|
||||
return new ZenjectException("Assert hit!");
|
||||
}
|
||||
|
||||
public static ZenjectException CreateException(string message)
|
||||
{
|
||||
return new ZenjectException(message);
|
||||
}
|
||||
|
||||
public static ZenjectException CreateException(string message, params object[] parameters)
|
||||
{
|
||||
return new ZenjectException(message.Fmt(parameters));
|
||||
}
|
||||
|
||||
public static ZenjectException CreateException(Exception innerException, string message, params object[] parameters)
|
||||
{
|
||||
return new ZenjectException(message.Fmt(parameters), innerException);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2968c9f42475ea146aec3ced9cbd99ad
|
||||
timeCreated: 1427464253
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,24 @@
|
||||
#if !NET_4_6
|
||||
|
||||
namespace ModestTree.Util
|
||||
{
|
||||
// C# 3.5 only defines Func and Action to a maximum of 4 generic parameters
|
||||
// Note that if you are using .NET framework > 3.5 you will have to comment these out to avoid ambiguous errors
|
||||
public delegate TResult Func<T1, T2, T3, T4, T5, TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5);
|
||||
public delegate TResult Func<T1, T2, T3, T4, T5, T6, TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6);
|
||||
public delegate TResult Func<T1, T2, T3, T4, T5, T6, T7, TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7);
|
||||
public delegate TResult Func<T1, T2, T3, T4, T5, T6, T7, T8, TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8);
|
||||
public delegate TResult Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9);
|
||||
public delegate TResult Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10);
|
||||
public delegate TResult Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11);
|
||||
|
||||
public delegate void Action<T1, T2, T3, T4, T5>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5);
|
||||
public delegate void Action<T1, T2, T3, T4, T5, T6>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6);
|
||||
public delegate void Action<T1, T2, T3, T4, T5, T6, T7>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7);
|
||||
public delegate void Action<T1, T2, T3, T4, T5, T6, T7, T8>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8);
|
||||
public delegate void Action<T1, T2, T3, T4, T5, T6, T7, T8, T9>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9);
|
||||
public delegate void Action<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10);
|
||||
public delegate void Action<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cf53ad544fd972d4eb4716fb02fb5e9e
|
||||
timeCreated: 1491195389
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,83 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Collections;
|
||||
using ModestTree.Util;
|
||||
|
||||
namespace ModestTree
|
||||
{
|
||||
public static class LinqExtensions
|
||||
{
|
||||
public static IEnumerable<T> Yield<T>(this T item)
|
||||
{
|
||||
yield return item;
|
||||
}
|
||||
|
||||
// Return the first item when the list is of length one and otherwise returns default
|
||||
public static TSource OnlyOrDefault<TSource>(this IEnumerable<TSource> source)
|
||||
{
|
||||
Assert.IsNotNull(source);
|
||||
|
||||
if (source.Count() > 1)
|
||||
{
|
||||
return default(TSource);
|
||||
}
|
||||
|
||||
return source.FirstOrDefault();
|
||||
}
|
||||
|
||||
// These are more efficient than Count() in cases where the size of the collection is not known
|
||||
public static bool HasAtLeast<T>(this IEnumerable<T> enumerable, int amount)
|
||||
{
|
||||
return enumerable.Take(amount).Count() == amount;
|
||||
}
|
||||
|
||||
public static bool HasMoreThan<T>(this IEnumerable<T> enumerable, int amount)
|
||||
{
|
||||
return enumerable.HasAtLeast(amount+1);
|
||||
}
|
||||
|
||||
public static bool HasLessThan<T>(this IEnumerable<T> enumerable, int amount)
|
||||
{
|
||||
return enumerable.HasAtMost(amount-1);
|
||||
}
|
||||
|
||||
public static bool HasAtMost<T>(this IEnumerable<T> enumerable, int amount)
|
||||
{
|
||||
return enumerable.Take(amount + 1).Count() <= amount;
|
||||
}
|
||||
|
||||
public static bool IsEmpty<T>(this IEnumerable<T> enumerable)
|
||||
{
|
||||
return !enumerable.Any();
|
||||
}
|
||||
|
||||
public static IEnumerable<T> GetDuplicates<T>(this IEnumerable<T> list)
|
||||
{
|
||||
return list.GroupBy(x => x).Where(x => x.Skip(1).Any()).Select(x => x.Key);
|
||||
}
|
||||
|
||||
public static IEnumerable<T> Except<T>(this IEnumerable<T> list, T item)
|
||||
{
|
||||
return list.Except(item.Yield());
|
||||
}
|
||||
|
||||
// LINQ already has a method called "Contains" that does the same thing as this
|
||||
// BUT it fails to work with Mono 3.5 in some cases.
|
||||
// For example the following prints False, True in Mono 3.5 instead of True, True like it should:
|
||||
//
|
||||
// IEnumerable<string> args = new string[]
|
||||
// {
|
||||
// "",
|
||||
// null,
|
||||
// };
|
||||
|
||||
// Log.Info(args.ContainsItem(null));
|
||||
// Log.Info(args.Where(x => x == null).Any());
|
||||
public static bool ContainsItem<T>(this IEnumerable<T> list, T value)
|
||||
{
|
||||
// Use object.Equals to support null values
|
||||
return list.Where(x => object.Equals(x, value)).Any();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 68fac2f8aa1edec4b9ef45794638a59c
|
||||
timeCreated: 1427464292
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,84 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace ModestTree
|
||||
{
|
||||
// Simple wrapper around unity's logging system
|
||||
public static class Log
|
||||
{
|
||||
// Strip out debug logs outside of unity
|
||||
[Conditional("UNITY_EDITOR")]
|
||||
public static void Debug(string message, params object[] args)
|
||||
{
|
||||
#if NOT_UNITY3D
|
||||
//Console.WriteLine(message.Fmt(args));
|
||||
#else
|
||||
//UnityEngine.Debug.Log(message.Fmt(args));
|
||||
#endif
|
||||
}
|
||||
|
||||
/////////////
|
||||
|
||||
public static void Info(string message, params object[] args)
|
||||
{
|
||||
#if NOT_UNITY3D
|
||||
Console.WriteLine(message.Fmt(args));
|
||||
#else
|
||||
UnityEngine.Debug.Log(message.Fmt(args));
|
||||
#endif
|
||||
}
|
||||
|
||||
/////////////
|
||||
|
||||
public static void Warn(string message, params object[] args)
|
||||
{
|
||||
#if NOT_UNITY3D
|
||||
Console.WriteLine(message.Fmt(args));
|
||||
#else
|
||||
UnityEngine.Debug.LogWarning(message.Fmt(args));
|
||||
#endif
|
||||
}
|
||||
|
||||
/////////////
|
||||
|
||||
public static void Trace(string message, params object[] args)
|
||||
{
|
||||
#if NOT_UNITY3D
|
||||
Console.WriteLine(message.Fmt(args));
|
||||
#else
|
||||
UnityEngine.Debug.Log(message.Fmt(args));
|
||||
#endif
|
||||
}
|
||||
|
||||
/////////////
|
||||
|
||||
public static void ErrorException(Exception e)
|
||||
{
|
||||
#if NOT_UNITY3D
|
||||
Console.WriteLine(e.ToString());
|
||||
#else
|
||||
UnityEngine.Debug.LogException(e);
|
||||
#endif
|
||||
}
|
||||
|
||||
public static void ErrorException(string message, Exception e)
|
||||
{
|
||||
#if NOT_UNITY3D
|
||||
Console.WriteLine(message);
|
||||
#else
|
||||
UnityEngine.Debug.LogError(message);
|
||||
UnityEngine.Debug.LogException(e);
|
||||
#endif
|
||||
}
|
||||
|
||||
public static void Error(string message, params object[] args)
|
||||
{
|
||||
#if NOT_UNITY3D
|
||||
Console.WriteLine(message.Fmt(args));
|
||||
#else
|
||||
UnityEngine.Debug.LogError(message.Fmt(args));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 622a24d4c6769414495ea1786bfee872
|
||||
timeCreated: 1427464253
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,96 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace ModestTree
|
||||
{
|
||||
public static class MiscExtensions
|
||||
{
|
||||
// We'd prefer to use the name Format here but that conflicts with
|
||||
// the existing string.Format method
|
||||
public static string Fmt(this string s, params object[] args)
|
||||
{
|
||||
// Do in-place change to avoid the memory alloc
|
||||
// This should be fine because the params is always used instead of directly
|
||||
// passing an array
|
||||
for (int i = 0; i < args.Length; i++)
|
||||
{
|
||||
var arg = args[i];
|
||||
|
||||
if (arg == null)
|
||||
{
|
||||
// This is much more understandable than just the empty string
|
||||
args[i] = "NULL";
|
||||
}
|
||||
else if (arg is Type)
|
||||
{
|
||||
// This often reads much better sometimes
|
||||
args[i] = ((Type)arg).PrettyName();
|
||||
}
|
||||
}
|
||||
|
||||
return String.Format(s, args);
|
||||
}
|
||||
|
||||
public static int IndexOf<T>(this IList<T> list, T item)
|
||||
{
|
||||
for (int i = 0; i < list.Count; i++)
|
||||
{
|
||||
if (object.Equals(list[i], item))
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static string Join(this IEnumerable<string> values, string separator)
|
||||
{
|
||||
return string.Join(separator, values.ToArray());
|
||||
}
|
||||
|
||||
// When using C# 4.6, for some reason the normal AddRange causes some allocations
|
||||
// https://issuetracker.unity3d.com/issues/dot-net-4-dot-6-unexpected-gc-allocations-in-list-dot-addrange
|
||||
public static void AllocFreeAddRange<T>(this IList<T> list, IList<T> items)
|
||||
{
|
||||
for (int i = 0; i < items.Count; i++)
|
||||
{
|
||||
list.Add(items[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// Most of the time when you call remove you always intend on removing something
|
||||
// so assert in that case
|
||||
public static void RemoveWithConfirm<T>(this IList<T> list, T item)
|
||||
{
|
||||
bool removed = list.Remove(item);
|
||||
Assert.That(removed);
|
||||
}
|
||||
|
||||
public static void RemoveWithConfirm<T>(this LinkedList<T> list, T item)
|
||||
{
|
||||
bool removed = list.Remove(item);
|
||||
Assert.That(removed);
|
||||
}
|
||||
|
||||
public static void RemoveWithConfirm<TKey, TVal>(this IDictionary<TKey, TVal> dictionary, TKey key)
|
||||
{
|
||||
bool removed = dictionary.Remove(key);
|
||||
Assert.That(removed);
|
||||
}
|
||||
|
||||
public static void RemoveWithConfirm<T>(this HashSet<T> set, T item)
|
||||
{
|
||||
bool removed = set.Remove(item);
|
||||
Assert.That(removed);
|
||||
}
|
||||
|
||||
public static TVal GetValueAndRemove<TKey, TVal>(this IDictionary<TKey, TVal> dictionary, TKey key)
|
||||
{
|
||||
TVal val = dictionary[key];
|
||||
dictionary.RemoveWithConfirm(key);
|
||||
return val;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: da4e9bf39c1ac464d84d2f743a25f8d1
|
||||
timeCreated: 1427464359
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,9 @@
|
||||
using System;
|
||||
|
||||
namespace ModestTree.Util
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.All, AllowMultiple = false)]
|
||||
public class PreserveAttribute : Attribute
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: de17d24691e2bfd458a9d10cb1d49098
|
||||
timeCreated: 1453682156
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,391 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
|
||||
namespace ModestTree
|
||||
{
|
||||
public static class TypeExtensions
|
||||
{
|
||||
static readonly Dictionary<Type, bool> _isClosedGenericType = new Dictionary<Type, bool>();
|
||||
static readonly Dictionary<Type, bool> _isOpenGenericType = new Dictionary<Type, bool>();
|
||||
static readonly Dictionary<Type, bool> _isValueType = new Dictionary<Type, bool>();
|
||||
static readonly Dictionary<Type, Type[]> _interfaces = new Dictionary<Type, Type[]>();
|
||||
|
||||
public static bool DerivesFrom<T>(this Type a)
|
||||
{
|
||||
return DerivesFrom(a, typeof(T));
|
||||
}
|
||||
|
||||
// This seems easier to think about than IsAssignableFrom
|
||||
public static bool DerivesFrom(this Type a, Type b)
|
||||
{
|
||||
return b != a && a.DerivesFromOrEqual(b);
|
||||
}
|
||||
|
||||
public static bool DerivesFromOrEqual<T>(this Type a)
|
||||
{
|
||||
return DerivesFromOrEqual(a, typeof(T));
|
||||
}
|
||||
|
||||
public static bool DerivesFromOrEqual(this Type a, Type b)
|
||||
{
|
||||
#if UNITY_WSA && ENABLE_DOTNET && !UNITY_EDITOR
|
||||
return b == a || b.GetTypeInfo().IsAssignableFrom(a.GetTypeInfo());
|
||||
#else
|
||||
return b == a || b.IsAssignableFrom(a);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !(UNITY_WSA && ENABLE_DOTNET)
|
||||
// TODO: Is it possible to do this on WSA?
|
||||
public static bool IsAssignableToGenericType(Type givenType, Type genericType)
|
||||
{
|
||||
var interfaceTypes = givenType.Interfaces();
|
||||
|
||||
foreach (var it in interfaceTypes)
|
||||
{
|
||||
if (it.IsGenericType && it.GetGenericTypeDefinition() == genericType)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (givenType.IsGenericType && givenType.GetGenericTypeDefinition() == genericType)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
Type baseType = givenType.BaseType;
|
||||
|
||||
if (baseType == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return IsAssignableToGenericType(baseType, genericType);
|
||||
}
|
||||
#endif
|
||||
|
||||
public static bool IsEnum(this Type type)
|
||||
{
|
||||
#if UNITY_WSA && ENABLE_DOTNET && !UNITY_EDITOR
|
||||
return type.GetTypeInfo().IsEnum;
|
||||
#else
|
||||
return type.IsEnum;
|
||||
#endif
|
||||
}
|
||||
|
||||
public static bool IsValueType(this Type type)
|
||||
{
|
||||
bool result;
|
||||
if (!_isValueType.TryGetValue(type, out result))
|
||||
{
|
||||
#if UNITY_WSA && ENABLE_DOTNET && !UNITY_EDITOR
|
||||
result = type.GetTypeInfo().IsValueType;
|
||||
#else
|
||||
result = type.IsValueType;
|
||||
#endif
|
||||
_isValueType[type] = result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static MethodInfo[] DeclaredInstanceMethods(this Type type)
|
||||
{
|
||||
#if UNITY_WSA && ENABLE_DOTNET && !UNITY_EDITOR
|
||||
return type.GetRuntimeMethods()
|
||||
.Where(x => x.DeclaringType == type).ToArray();
|
||||
#else
|
||||
return type.GetMethods(
|
||||
BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly);
|
||||
#endif
|
||||
}
|
||||
|
||||
public static PropertyInfo[] DeclaredInstanceProperties(this Type type)
|
||||
{
|
||||
#if UNITY_WSA && ENABLE_DOTNET && !UNITY_EDITOR
|
||||
// There doesn't appear to be an IsStatic member on PropertyInfo
|
||||
return type.GetRuntimeProperties()
|
||||
.Where(x => x.DeclaringType == type).ToArray();
|
||||
#else
|
||||
return type.GetProperties(
|
||||
BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly);
|
||||
#endif
|
||||
}
|
||||
|
||||
public static FieldInfo[] DeclaredInstanceFields(this Type type)
|
||||
{
|
||||
#if UNITY_WSA && ENABLE_DOTNET && !UNITY_EDITOR
|
||||
return type.GetRuntimeFields()
|
||||
.Where(x => x.DeclaringType == type && !x.IsStatic).ToArray();
|
||||
#else
|
||||
return type.GetFields(
|
||||
BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if UNITY_WSA && ENABLE_DOTNET && !UNITY_EDITOR
|
||||
public static bool IsAssignableFrom(this Type a, Type b)
|
||||
{
|
||||
return a.GetTypeInfo().IsAssignableFrom(b.GetTypeInfo());
|
||||
}
|
||||
#endif
|
||||
|
||||
public static Type BaseType(this Type type)
|
||||
{
|
||||
#if UNITY_WSA && ENABLE_DOTNET && !UNITY_EDITOR
|
||||
return type.GetTypeInfo().BaseType;
|
||||
#else
|
||||
return type.BaseType;
|
||||
#endif
|
||||
}
|
||||
|
||||
public static bool IsGenericType(this Type type)
|
||||
{
|
||||
#if UNITY_WSA && ENABLE_DOTNET && !UNITY_EDITOR
|
||||
return type.GetTypeInfo().IsGenericType;
|
||||
#else
|
||||
return type.IsGenericType;
|
||||
#endif
|
||||
}
|
||||
public static bool IsGenericTypeDefinition(this Type type)
|
||||
{
|
||||
#if UNITY_WSA && ENABLE_DOTNET && !UNITY_EDITOR
|
||||
return type.GetTypeInfo().IsGenericTypeDefinition;
|
||||
#else
|
||||
return type.IsGenericTypeDefinition;
|
||||
#endif
|
||||
}
|
||||
|
||||
public static bool IsPrimitive(this Type type)
|
||||
{
|
||||
#if UNITY_WSA && ENABLE_DOTNET && !UNITY_EDITOR
|
||||
return type.GetTypeInfo().IsPrimitive;
|
||||
#else
|
||||
return type.IsPrimitive;
|
||||
#endif
|
||||
}
|
||||
|
||||
public static bool IsInterface(this Type type)
|
||||
{
|
||||
#if UNITY_WSA && ENABLE_DOTNET && !UNITY_EDITOR
|
||||
return type.GetTypeInfo().IsInterface;
|
||||
#else
|
||||
return type.IsInterface;
|
||||
#endif
|
||||
}
|
||||
|
||||
public static bool ContainsGenericParameters(this Type type)
|
||||
{
|
||||
#if UNITY_WSA && ENABLE_DOTNET && !UNITY_EDITOR
|
||||
return type.GetTypeInfo().ContainsGenericParameters;
|
||||
#else
|
||||
return type.ContainsGenericParameters;
|
||||
#endif
|
||||
}
|
||||
|
||||
public static bool IsAbstract(this Type type)
|
||||
{
|
||||
#if UNITY_WSA && ENABLE_DOTNET && !UNITY_EDITOR
|
||||
return type.GetTypeInfo().IsAbstract;
|
||||
#else
|
||||
return type.IsAbstract;
|
||||
#endif
|
||||
}
|
||||
|
||||
public static bool IsSealed(this Type type)
|
||||
{
|
||||
#if UNITY_WSA && ENABLE_DOTNET && !UNITY_EDITOR
|
||||
return type.GetTypeInfo().IsSealed;
|
||||
#else
|
||||
return type.IsSealed;
|
||||
#endif
|
||||
}
|
||||
|
||||
public static MethodInfo Method(this Delegate del)
|
||||
{
|
||||
#if UNITY_WSA && ENABLE_DOTNET && !UNITY_EDITOR
|
||||
return del.GetMethodInfo();
|
||||
#else
|
||||
return del.Method;
|
||||
#endif
|
||||
}
|
||||
|
||||
public static Type[] GenericArguments(this Type type)
|
||||
{
|
||||
#if UNITY_WSA && ENABLE_DOTNET && !UNITY_EDITOR
|
||||
return type.GetTypeInfo().GenericTypeArguments;
|
||||
#else
|
||||
return type.GetGenericArguments();
|
||||
#endif
|
||||
}
|
||||
|
||||
public static Type[] Interfaces(this Type type)
|
||||
{
|
||||
Type[] result;
|
||||
if (!_interfaces.TryGetValue(type, out result))
|
||||
{
|
||||
#if UNITY_WSA && ENABLE_DOTNET && !UNITY_EDITOR
|
||||
result = type.GetTypeInfo().ImplementedInterfaces.ToArray();
|
||||
#else
|
||||
result = type.GetInterfaces();
|
||||
#endif
|
||||
_interfaces.Add(type, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static ConstructorInfo[] Constructors(this Type type)
|
||||
{
|
||||
#if UNITY_WSA && ENABLE_DOTNET && !UNITY_EDITOR
|
||||
return type.GetTypeInfo().DeclaredConstructors.ToArray();
|
||||
#else
|
||||
return type.GetConstructors(
|
||||
BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
#endif
|
||||
}
|
||||
|
||||
public static object GetDefaultValue(this Type type)
|
||||
{
|
||||
#if ENABLE_IL2CPP
|
||||
// Workaround for IL2CPP returning default(T) for Activator.CreateInstance(typeof(T?))
|
||||
if (type.IsGenericType() && type.GetGenericTypeDefinition() == typeof(Nullable<>))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (type.IsValueType())
|
||||
{
|
||||
return Activator.CreateInstance(type);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static bool IsClosedGenericType(this Type type)
|
||||
{
|
||||
bool result;
|
||||
if (!_isClosedGenericType.TryGetValue(type, out result))
|
||||
{
|
||||
result = type.IsGenericType() && type != type.GetGenericTypeDefinition();
|
||||
_isClosedGenericType[type] = result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static IEnumerable<Type> GetParentTypes(this Type type)
|
||||
{
|
||||
if (type == null || type.BaseType() == null || type == typeof(object) || type.BaseType() == typeof(object))
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
|
||||
yield return type.BaseType();
|
||||
|
||||
foreach (var ancestor in type.BaseType().GetParentTypes())
|
||||
{
|
||||
yield return ancestor;
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsOpenGenericType(this Type type)
|
||||
{
|
||||
bool result;
|
||||
if (!_isOpenGenericType.TryGetValue(type, out result))
|
||||
{
|
||||
result = type.IsGenericType() && type == type.GetGenericTypeDefinition();
|
||||
_isOpenGenericType[type] = result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static T GetAttribute<T>(this MemberInfo provider)
|
||||
where T : Attribute
|
||||
{
|
||||
return provider.AllAttributes<T>().Single();
|
||||
}
|
||||
|
||||
public static T TryGetAttribute<T>(this MemberInfo provider)
|
||||
where T : Attribute
|
||||
{
|
||||
return provider.AllAttributes<T>().OnlyOrDefault();
|
||||
}
|
||||
|
||||
public static bool HasAttribute(
|
||||
this MemberInfo provider, params Type[] attributeTypes)
|
||||
{
|
||||
return provider.AllAttributes(attributeTypes).Any();
|
||||
}
|
||||
|
||||
public static bool HasAttribute<T>(this MemberInfo provider)
|
||||
where T : Attribute
|
||||
{
|
||||
return provider.AllAttributes(typeof(T)).Any();
|
||||
}
|
||||
|
||||
public static IEnumerable<T> AllAttributes<T>(
|
||||
this MemberInfo provider)
|
||||
where T : Attribute
|
||||
{
|
||||
return provider.AllAttributes(typeof(T)).Cast<T>();
|
||||
}
|
||||
|
||||
public static IEnumerable<Attribute> AllAttributes(
|
||||
this MemberInfo provider, params Type[] attributeTypes)
|
||||
{
|
||||
Attribute[] allAttributes;
|
||||
#if NETFX_CORE
|
||||
allAttributes = provider.GetCustomAttributes<Attribute>(true).ToArray();
|
||||
#else
|
||||
allAttributes = System.Attribute.GetCustomAttributes(provider, typeof(Attribute), true);
|
||||
#endif
|
||||
if (attributeTypes.Length == 0)
|
||||
{
|
||||
return allAttributes;
|
||||
}
|
||||
|
||||
return allAttributes.Where(a => attributeTypes.Any(x => a.GetType().DerivesFromOrEqual(x)));
|
||||
}
|
||||
|
||||
// We could avoid this duplication here by using ICustomAttributeProvider but this class
|
||||
// does not exist on the WP8 platform
|
||||
public static bool HasAttribute(
|
||||
this ParameterInfo provider, params Type[] attributeTypes)
|
||||
{
|
||||
return provider.AllAttributes(attributeTypes).Any();
|
||||
}
|
||||
|
||||
public static bool HasAttribute<T>(this ParameterInfo provider)
|
||||
where T : Attribute
|
||||
{
|
||||
return provider.AllAttributes(typeof(T)).Any();
|
||||
}
|
||||
|
||||
public static IEnumerable<T> AllAttributes<T>(
|
||||
this ParameterInfo provider)
|
||||
where T : Attribute
|
||||
{
|
||||
return provider.AllAttributes(typeof(T)).Cast<T>();
|
||||
}
|
||||
|
||||
public static IEnumerable<Attribute> AllAttributes(
|
||||
this ParameterInfo provider, params Type[] attributeTypes)
|
||||
{
|
||||
Attribute[] allAttributes;
|
||||
#if NETFX_CORE
|
||||
allAttributes = provider.GetCustomAttributes<Attribute>(true).ToArray();
|
||||
#else
|
||||
allAttributes = System.Attribute.GetCustomAttributes(provider, typeof(Attribute), true);
|
||||
#endif
|
||||
if (attributeTypes.Length == 0)
|
||||
{
|
||||
return allAttributes;
|
||||
}
|
||||
|
||||
return allAttributes.Where(a => attributeTypes.Any(x => a.GetType().DerivesFromOrEqual(x)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2697c251f47f2bc40b32922c5a796f65
|
||||
timeCreated: 1427464253
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,112 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
|
||||
namespace ModestTree
|
||||
{
|
||||
public static class TypeStringFormatter
|
||||
{
|
||||
static readonly Dictionary<Type, string> _prettyNameCache = new Dictionary<Type, string>();
|
||||
|
||||
public static string PrettyName(this Type type)
|
||||
{
|
||||
string prettyName;
|
||||
|
||||
if (!_prettyNameCache.TryGetValue(type, out prettyName))
|
||||
{
|
||||
prettyName = PrettyNameInternal(type);
|
||||
_prettyNameCache.Add(type, prettyName);
|
||||
}
|
||||
|
||||
return prettyName;
|
||||
}
|
||||
|
||||
static string PrettyNameInternal(Type type)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
|
||||
if (type.IsNested)
|
||||
{
|
||||
sb.Append(type.DeclaringType.PrettyName());
|
||||
sb.Append(".");
|
||||
}
|
||||
|
||||
if (type.IsArray)
|
||||
{
|
||||
sb.Append(type.GetElementType().PrettyName());
|
||||
sb.Append("[]");
|
||||
}
|
||||
else
|
||||
{
|
||||
var name = GetCSharpTypeName(type.Name);
|
||||
|
||||
if (type.IsGenericType())
|
||||
{
|
||||
var quoteIndex = name.IndexOf('`');
|
||||
|
||||
if (quoteIndex != -1)
|
||||
{
|
||||
sb.Append(name.Substring(0, name.IndexOf('`')));
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.Append(name);
|
||||
}
|
||||
|
||||
sb.Append("<");
|
||||
|
||||
if (type.IsGenericTypeDefinition())
|
||||
{
|
||||
var numArgs = type.GenericArguments().Count();
|
||||
|
||||
if (numArgs > 0)
|
||||
{
|
||||
sb.Append(new String(',', numArgs - 1));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.Append(string.Join(", ", type.GenericArguments().Select(t => t.PrettyName()).ToArray()));
|
||||
}
|
||||
|
||||
sb.Append(">");
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.Append(name);
|
||||
}
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
static string GetCSharpTypeName(string typeName)
|
||||
{
|
||||
switch (typeName)
|
||||
{
|
||||
case "String":
|
||||
case "Object":
|
||||
case "Void":
|
||||
case "Byte":
|
||||
case "Double":
|
||||
case "Decimal":
|
||||
return typeName.ToLower();
|
||||
case "Int16":
|
||||
return "short";
|
||||
case "Int32":
|
||||
return "int";
|
||||
case "Int64":
|
||||
return "long";
|
||||
case "Single":
|
||||
return "float";
|
||||
case "Boolean":
|
||||
return "bool";
|
||||
default:
|
||||
return typeName;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 94a0a9a58e17e3d438c169678c9795f7
|
||||
timeCreated: 1538018650
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,190 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace ModestTree.Util
|
||||
{
|
||||
public class ValuePair<T1, T2>
|
||||
{
|
||||
public readonly T1 First;
|
||||
public readonly T2 Second;
|
||||
|
||||
public ValuePair()
|
||||
{
|
||||
First = default(T1);
|
||||
Second = default(T2);
|
||||
}
|
||||
|
||||
public ValuePair(T1 first, T2 second)
|
||||
{
|
||||
First = first;
|
||||
Second = second;
|
||||
}
|
||||
|
||||
public override bool Equals(Object obj)
|
||||
{
|
||||
var that = obj as ValuePair<T1, T2>;
|
||||
|
||||
if (that == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return Equals(that);
|
||||
}
|
||||
|
||||
public bool Equals(ValuePair<T1, T2> that)
|
||||
{
|
||||
if (that == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return object.Equals(First, that.First) && object.Equals(Second, that.Second);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked // Overflow is fine, just wrap
|
||||
{
|
||||
int hash = 17;
|
||||
hash = hash * 29 + (First == null ? 0 : First.GetHashCode());
|
||||
hash = hash * 29 + (Second == null ? 0 : Second.GetHashCode());
|
||||
return hash;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class ValuePair<T1, T2, T3>
|
||||
{
|
||||
public readonly T1 First;
|
||||
public readonly T2 Second;
|
||||
public readonly T3 Third;
|
||||
|
||||
public ValuePair()
|
||||
{
|
||||
First = default(T1);
|
||||
Second = default(T2);
|
||||
Third = default(T3);
|
||||
}
|
||||
|
||||
public ValuePair(T1 first, T2 second, T3 third)
|
||||
{
|
||||
First = first;
|
||||
Second = second;
|
||||
Third = third;
|
||||
}
|
||||
|
||||
public override bool Equals(Object obj)
|
||||
{
|
||||
var that = obj as ValuePair<T1, T2, T3>;
|
||||
|
||||
if (that == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return Equals(that);
|
||||
}
|
||||
|
||||
public bool Equals(ValuePair<T1, T2, T3> that)
|
||||
{
|
||||
if (that == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return object.Equals(First, that.First) && object.Equals(Second, that.Second) && object.Equals(Third, that.Third);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked // Overflow is fine, just wrap
|
||||
{
|
||||
int hash = 17;
|
||||
hash = hash * 29 + (First == null ? 0 : First.GetHashCode());
|
||||
hash = hash * 29 + (Second == null ? 0 : Second.GetHashCode());
|
||||
hash = hash * 29 + (Third == null ? 0 : Third.GetHashCode());
|
||||
return hash;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class ValuePair<T1, T2, T3, T4>
|
||||
{
|
||||
public readonly T1 First;
|
||||
public readonly T2 Second;
|
||||
public readonly T3 Third;
|
||||
public readonly T4 Fourth;
|
||||
|
||||
public ValuePair()
|
||||
{
|
||||
First = default(T1);
|
||||
Second = default(T2);
|
||||
Third = default(T3);
|
||||
Fourth = default(T4);
|
||||
}
|
||||
|
||||
public ValuePair(T1 first, T2 second, T3 third, T4 fourth)
|
||||
{
|
||||
First = first;
|
||||
Second = second;
|
||||
Third = third;
|
||||
Fourth = fourth;
|
||||
}
|
||||
|
||||
public override bool Equals(Object obj)
|
||||
{
|
||||
var that = obj as ValuePair<T1, T2, T3, T4>;
|
||||
|
||||
if (that == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return Equals(that);
|
||||
}
|
||||
|
||||
public bool Equals(ValuePair<T1, T2, T3, T4> that)
|
||||
{
|
||||
if (that == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return object.Equals(First, that.First) && object.Equals(Second, that.Second)
|
||||
&& object.Equals(Third, that.Third) && object.Equals(Fourth, that.Fourth);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked // Overflow is fine, just wrap
|
||||
{
|
||||
int hash = 17;
|
||||
hash = hash * 29 + (First == null ? 0 : First.GetHashCode());
|
||||
hash = hash * 29 + (Second == null ? 0 : Second.GetHashCode());
|
||||
hash = hash * 29 + (Third == null ? 0 : Third.GetHashCode());
|
||||
hash = hash * 29 + (Fourth == null ? 0 : Fourth.GetHashCode());
|
||||
return hash;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class ValuePair
|
||||
{
|
||||
public static ValuePair<T1, T2> New<T1, T2>(T1 first, T2 second)
|
||||
{
|
||||
return new ValuePair<T1, T2>(first, second);
|
||||
}
|
||||
|
||||
public static ValuePair<T1, T2, T3> New<T1, T2, T3>(T1 first, T2 second, T3 third)
|
||||
{
|
||||
return new ValuePair<T1, T2, T3>(first, second, third);
|
||||
}
|
||||
|
||||
public static ValuePair<T1, T2, T3, T4> New<T1, T2, T3, T4>(T1 first, T2 second, T3 third, T4 fourth)
|
||||
{
|
||||
return new ValuePair<T1, T2, T3, T4>(first, second, third, fourth);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a3c968adce0a9a24e949dc4eedb496e8
|
||||
timeCreated: 1478449513
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user