Utity
This commit is contained in:
ALEXTANG
2023-04-01 13:22:36 +08:00
parent 090cf7433a
commit 7768727ab1
32 changed files with 3205 additions and 0 deletions

View File

@@ -0,0 +1,102 @@
using System;
using System.Collections.Generic;
namespace TEngine
{
public static partial class Utility
{
/// <summary>
/// 程序集相关的实用函数。
/// </summary>
public static class Assembly
{
private static readonly System.Reflection.Assembly[] s_Assemblies = null;
private static readonly Dictionary<string, Type> s_CachedTypes = new Dictionary<string, Type>(StringComparer.Ordinal);
static Assembly()
{
s_Assemblies = AppDomain.CurrentDomain.GetAssemblies();
}
/// <summary>
/// 获取已加载的程序集。
/// </summary>
/// <returns>已加载的程序集。</returns>
public static System.Reflection.Assembly[] GetAssemblies()
{
return s_Assemblies;
}
/// <summary>
/// 获取已加载的程序集中的所有类型。
/// </summary>
/// <returns>已加载的程序集中的所有类型。</returns>
public static Type[] GetTypes()
{
List<Type> results = new List<Type>();
foreach (System.Reflection.Assembly assembly in s_Assemblies)
{
results.AddRange(assembly.GetTypes());
}
return results.ToArray();
}
/// <summary>
/// 获取已加载的程序集中的所有类型。
/// </summary>
/// <param name="results">已加载的程序集中的所有类型。</param>
public static void GetTypes(List<Type> results)
{
if (results == null)
{
throw new GameFrameworkException("Results is invalid.");
}
results.Clear();
foreach (System.Reflection.Assembly assembly in s_Assemblies)
{
results.AddRange(assembly.GetTypes());
}
}
/// <summary>
/// 获取已加载的程序集中的指定类型。
/// </summary>
/// <param name="typeName">要获取的类型名。</param>
/// <returns>已加载的程序集中的指定类型。</returns>
public static Type GetType(string typeName)
{
if (string.IsNullOrEmpty(typeName))
{
throw new GameFrameworkException("Type name is invalid.");
}
Type type = null;
if (s_CachedTypes.TryGetValue(typeName, out type))
{
return type;
}
type = Type.GetType(typeName);
if (type != null)
{
s_CachedTypes.Add(typeName, type);
return type;
}
foreach (System.Reflection.Assembly assembly in s_Assemblies)
{
type = Type.GetType(Text.Format("{0}, {1}", typeName, assembly.FullName));
if (type != null)
{
s_CachedTypes.Add(typeName, type);
return type;
}
}
return null;
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7609018db739fe545ba5be5d32f7eb3c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,52 @@
using System.IO;
namespace TEngine
{
public static partial class Utility
{
public static partial class Compression
{
/// <summary>
/// 压缩解压缩辅助器接口。
/// </summary>
public interface ICompressionHelper
{
/// <summary>
/// 压缩数据。
/// </summary>
/// <param name="bytes">要压缩的数据的二进制流。</param>
/// <param name="offset">要压缩的数据的二进制流的偏移。</param>
/// <param name="length">要压缩的数据的二进制流的长度。</param>
/// <param name="compressedStream">压缩后的数据的二进制流。</param>
/// <returns>是否压缩数据成功。</returns>
bool Compress(byte[] bytes, int offset, int length, Stream compressedStream);
/// <summary>
/// 压缩数据。
/// </summary>
/// <param name="stream">要压缩的数据的二进制流。</param>
/// <param name="compressedStream">压缩后的数据的二进制流。</param>
/// <returns>是否压缩数据成功。</returns>
bool Compress(Stream stream, Stream compressedStream);
/// <summary>
/// 解压缩数据。
/// </summary>
/// <param name="bytes">要解压缩的数据的二进制流。</param>
/// <param name="offset">要解压缩的数据的二进制流的偏移。</param>
/// <param name="length">要解压缩的数据的二进制流的长度。</param>
/// <param name="decompressedStream">解压缩后的数据的二进制流。</param>
/// <returns>是否解压缩数据成功。</returns>
bool Decompress(byte[] bytes, int offset, int length, Stream decompressedStream);
/// <summary>
/// 解压缩数据。
/// </summary>
/// <param name="stream">要解压缩的数据的二进制流。</param>
/// <param name="decompressedStream">解压缩后的数据的二进制流。</param>
/// <returns>是否解压缩数据成功。</returns>
bool Decompress(Stream stream, Stream decompressedStream);
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3d82356f5e654704daa0769074b9e5a7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,337 @@
using System;
using System.IO;
namespace TEngine
{
public static partial class Utility
{
/// <summary>
/// 压缩解压缩相关的实用函数。
/// </summary>
public static partial class Compression
{
private static ICompressionHelper s_CompressionHelper = null;
/// <summary>
/// 设置压缩解压缩辅助器。
/// </summary>
/// <param name="compressionHelper">要设置的压缩解压缩辅助器。</param>
public static void SetCompressionHelper(ICompressionHelper compressionHelper)
{
s_CompressionHelper = compressionHelper;
}
/// <summary>
/// 压缩数据。
/// </summary>
/// <param name="bytes">要压缩的数据的二进制流。</param>
/// <returns>压缩后的数据的二进制流。</returns>
public static byte[] Compress(byte[] bytes)
{
if (bytes == null)
{
throw new GameFrameworkException("Bytes is invalid.");
}
return Compress(bytes, 0, bytes.Length);
}
/// <summary>
/// 压缩数据。
/// </summary>
/// <param name="bytes">要压缩的数据的二进制流。</param>
/// <param name="compressedStream">压缩后的数据的二进制流。</param>
/// <returns>是否压缩数据成功。</returns>
public static bool Compress(byte[] bytes, Stream compressedStream)
{
if (bytes == null)
{
throw new GameFrameworkException("Bytes is invalid.");
}
return Compress(bytes, 0, bytes.Length, compressedStream);
}
/// <summary>
/// 压缩数据。
/// </summary>
/// <param name="bytes">要压缩的数据的二进制流。</param>
/// <param name="offset">要压缩的数据的二进制流的偏移。</param>
/// <param name="length">要压缩的数据的二进制流的长度。</param>
/// <returns>压缩后的数据的二进制流。</returns>
public static byte[] Compress(byte[] bytes, int offset, int length)
{
using (MemoryStream compressedStream = new MemoryStream())
{
if (Compress(bytes, offset, length, compressedStream))
{
return compressedStream.ToArray();
}
else
{
return null;
}
}
}
/// <summary>
/// 压缩数据。
/// </summary>
/// <param name="bytes">要压缩的数据的二进制流。</param>
/// <param name="offset">要压缩的数据的二进制流的偏移。</param>
/// <param name="length">要压缩的数据的二进制流的长度。</param>
/// <param name="compressedStream">压缩后的数据的二进制流。</param>
/// <returns>是否压缩数据成功。</returns>
public static bool Compress(byte[] bytes, int offset, int length, Stream compressedStream)
{
if (s_CompressionHelper == null)
{
throw new GameFrameworkException("Compressed helper is invalid.");
}
if (bytes == null)
{
throw new GameFrameworkException("Bytes is invalid.");
}
if (offset < 0 || length < 0 || offset + length > bytes.Length)
{
throw new GameFrameworkException("Offset or length is invalid.");
}
if (compressedStream == null)
{
throw new GameFrameworkException("Compressed stream is invalid.");
}
try
{
return s_CompressionHelper.Compress(bytes, offset, length, compressedStream);
}
catch (Exception exception)
{
if (exception is GameFrameworkException)
{
throw;
}
throw new GameFrameworkException(Text.Format("Can not compress with exception '{0}'.", exception), exception);
}
}
/// <summary>
/// 压缩数据。
/// </summary>
/// <param name="stream">要压缩的数据的二进制流。</param>
/// <returns>压缩后的数据的二进制流。</returns>
public static byte[] Compress(Stream stream)
{
using (MemoryStream compressedStream = new MemoryStream())
{
if (Compress(stream, compressedStream))
{
return compressedStream.ToArray();
}
else
{
return null;
}
}
}
/// <summary>
/// 压缩数据。
/// </summary>
/// <param name="stream">要压缩的数据的二进制流。</param>
/// <param name="compressedStream">压缩后的数据的二进制流。</param>
/// <returns>是否压缩数据成功。</returns>
public static bool Compress(Stream stream, Stream compressedStream)
{
if (s_CompressionHelper == null)
{
throw new GameFrameworkException("Compressed helper is invalid.");
}
if (stream == null)
{
throw new GameFrameworkException("Stream is invalid.");
}
if (compressedStream == null)
{
throw new GameFrameworkException("Compressed stream is invalid.");
}
try
{
return s_CompressionHelper.Compress(stream, compressedStream);
}
catch (Exception exception)
{
if (exception is GameFrameworkException)
{
throw;
}
throw new GameFrameworkException(Text.Format("Can not compress with exception '{0}'.", exception), exception);
}
}
/// <summary>
/// 解压缩数据。
/// </summary>
/// <param name="bytes">要解压缩的数据的二进制流。</param>
/// <returns>解压缩后的数据的二进制流。</returns>
public static byte[] Decompress(byte[] bytes)
{
if (bytes == null)
{
throw new GameFrameworkException("Bytes is invalid.");
}
return Decompress(bytes, 0, bytes.Length);
}
/// <summary>
/// 解压缩数据。
/// </summary>
/// <param name="bytes">要解压缩的数据的二进制流。</param>
/// <param name="decompressedStream">解压缩后的数据的二进制流。</param>
/// <returns>是否解压缩数据成功。</returns>
public static bool Decompress(byte[] bytes, Stream decompressedStream)
{
if (bytes == null)
{
throw new GameFrameworkException("Bytes is invalid.");
}
return Decompress(bytes, 0, bytes.Length, decompressedStream);
}
/// <summary>
/// 解压缩数据。
/// </summary>
/// <param name="bytes">要解压缩的数据的二进制流。</param>
/// <param name="offset">要解压缩的数据的二进制流的偏移。</param>
/// <param name="length">要解压缩的数据的二进制流的长度。</param>
/// <returns>解压缩后的数据的二进制流。</returns>
public static byte[] Decompress(byte[] bytes, int offset, int length)
{
using (MemoryStream decompressedStream = new MemoryStream())
{
if (Decompress(bytes, offset, length, decompressedStream))
{
return decompressedStream.ToArray();
}
else
{
return null;
}
}
}
/// <summary>
/// 解压缩数据。
/// </summary>
/// <param name="bytes">要解压缩的数据的二进制流。</param>
/// <param name="offset">要解压缩的数据的二进制流的偏移。</param>
/// <param name="length">要解压缩的数据的二进制流的长度。</param>
/// <param name="decompressedStream">解压缩后的数据的二进制流。</param>
/// <returns>是否解压缩数据成功。</returns>
public static bool Decompress(byte[] bytes, int offset, int length, Stream decompressedStream)
{
if (s_CompressionHelper == null)
{
throw new GameFrameworkException("Compressed helper is invalid.");
}
if (bytes == null)
{
throw new GameFrameworkException("Bytes is invalid.");
}
if (offset < 0 || length < 0 || offset + length > bytes.Length)
{
throw new GameFrameworkException("Offset or length is invalid.");
}
if (decompressedStream == null)
{
throw new GameFrameworkException("Decompressed stream is invalid.");
}
try
{
return s_CompressionHelper.Decompress(bytes, offset, length, decompressedStream);
}
catch (Exception exception)
{
if (exception is GameFrameworkException)
{
throw;
}
throw new GameFrameworkException(Text.Format("Can not decompress with exception '{0}'.", exception), exception);
}
}
/// <summary>
/// 解压缩数据。
/// </summary>
/// <param name="stream">要解压缩的数据的二进制流。</param>
/// <returns>是否解压缩数据成功。</returns>
public static byte[] Decompress(Stream stream)
{
using (MemoryStream decompressedStream = new MemoryStream())
{
if (Decompress(stream, decompressedStream))
{
return decompressedStream.ToArray();
}
else
{
return null;
}
}
}
/// <summary>
/// 解压缩数据。
/// </summary>
/// <param name="stream">要解压缩的数据的二进制流。</param>
/// <param name="decompressedStream">解压缩后的数据的二进制流。</param>
/// <returns>是否解压缩数据成功。</returns>
public static bool Decompress(Stream stream, Stream decompressedStream)
{
if (s_CompressionHelper == null)
{
throw new GameFrameworkException("Compressed helper is invalid.");
}
if (stream == null)
{
throw new GameFrameworkException("Stream is invalid.");
}
if (decompressedStream == null)
{
throw new GameFrameworkException("Decompressed stream is invalid.");
}
try
{
return s_CompressionHelper.Decompress(stream, decompressedStream);
}
catch (Exception exception)
{
if (exception is GameFrameworkException)
{
throw;
}
throw new GameFrameworkException(Text.Format("Can not decompress with exception '{0}'.", exception), exception);
}
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f1ec2480f190a1e419297e6efd755541
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,841 @@
using System;
using System.Text;
namespace TEngine
{
public static partial class Utility
{
/// <summary>
/// 类型转换相关的实用函数。
/// </summary>
public static class Converter
{
private const float InchesToCentimeters = 2.54f; // 1 inch = 2.54 cm
private const float CentimetersToInches = 1f / InchesToCentimeters; // 1 cm = 0.3937 inches
/// <summary>
/// 获取数据在此计算机结构中存储时的字节顺序。
/// </summary>
public static bool IsLittleEndian
{
get
{
return BitConverter.IsLittleEndian;
}
}
/// <summary>
/// 获取或设置屏幕每英寸点数。
/// </summary>
public static float ScreenDpi
{
get;
set;
}
/// <summary>
/// 将像素转换为厘米。
/// </summary>
/// <param name="pixels">像素。</param>
/// <returns>厘米。</returns>
public static float GetCentimetersFromPixels(float pixels)
{
if (ScreenDpi <= 0)
{
throw new GameFrameworkException("You must set screen DPI first.");
}
return InchesToCentimeters * pixels / ScreenDpi;
}
/// <summary>
/// 将厘米转换为像素。
/// </summary>
/// <param name="centimeters">厘米。</param>
/// <returns>像素。</returns>
public static float GetPixelsFromCentimeters(float centimeters)
{
if (ScreenDpi <= 0)
{
throw new GameFrameworkException("You must set screen DPI first.");
}
return CentimetersToInches * centimeters * ScreenDpi;
}
/// <summary>
/// 将像素转换为英寸。
/// </summary>
/// <param name="pixels">像素。</param>
/// <returns>英寸。</returns>
public static float GetInchesFromPixels(float pixels)
{
if (ScreenDpi <= 0)
{
throw new GameFrameworkException("You must set screen DPI first.");
}
return pixels / ScreenDpi;
}
/// <summary>
/// 将英寸转换为像素。
/// </summary>
/// <param name="inches">英寸。</param>
/// <returns>像素。</returns>
public static float GetPixelsFromInches(float inches)
{
if (ScreenDpi <= 0)
{
throw new GameFrameworkException("You must set screen DPI first.");
}
return inches * ScreenDpi;
}
/// <summary>
/// 以字节数组的形式获取指定的布尔值。
/// </summary>
/// <param name="value">要转换的布尔值。</param>
/// <returns>用于存放结果的字节数组。</returns>
public static byte[] GetBytes(bool value)
{
byte[] buffer = new byte[1];
GetBytes(value, buffer, 0);
return buffer;
}
/// <summary>
/// 以字节数组的形式获取指定的布尔值。
/// </summary>
/// <param name="value">要转换的布尔值。</param>
/// <param name="buffer">用于存放结果的字节数组。</param>
public static void GetBytes(bool value, byte[] buffer)
{
GetBytes(value, buffer, 0);
}
/// <summary>
/// 以字节数组的形式获取指定的布尔值。
/// </summary>
/// <param name="value">要转换的布尔值。</param>
/// <param name="buffer">用于存放结果的字节数组。</param>
/// <param name="startIndex">buffer 内的起始位置。</param>
public static void GetBytes(bool value, byte[] buffer, int startIndex)
{
if (buffer == null)
{
throw new GameFrameworkException("Buffer is invalid.");
}
if (startIndex < 0 || startIndex + 1 > buffer.Length)
{
throw new GameFrameworkException("Start index is invalid.");
}
buffer[startIndex] = value ? (byte)1 : (byte)0;
}
/// <summary>
/// 返回由字节数组中首字节转换来的布尔值。
/// </summary>
/// <param name="value">字节数组。</param>
/// <returns>如果 value 中的首字节非零,则为 true否则为 false。</returns>
public static bool GetBoolean(byte[] value)
{
return BitConverter.ToBoolean(value, 0);
}
/// <summary>
/// 返回由字节数组中指定位置的一个字节转换来的布尔值。
/// </summary>
/// <param name="value">字节数组。</param>
/// <param name="startIndex">value 内的起始位置。</param>
/// <returns>如果 value 中指定位置的字节非零,则为 true否则为 false。</returns>
public static bool GetBoolean(byte[] value, int startIndex)
{
return BitConverter.ToBoolean(value, startIndex);
}
/// <summary>
/// 以字节数组的形式获取指定的 Unicode 字符值。
/// </summary>
/// <param name="value">要转换的字符。</param>
/// <returns>用于存放结果的字节数组。</returns>
public static byte[] GetBytes(char value)
{
byte[] buffer = new byte[2];
GetBytes((short)value, buffer, 0);
return buffer;
}
/// <summary>
/// 以字节数组的形式获取指定的 Unicode 字符值。
/// </summary>
/// <param name="value">要转换的字符。</param>
/// <param name="buffer">用于存放结果的字节数组。</param>
public static void GetBytes(char value, byte[] buffer)
{
GetBytes((short)value, buffer, 0);
}
/// <summary>
/// 以字节数组的形式获取指定的 Unicode 字符值。
/// </summary>
/// <param name="value">要转换的字符。</param>
/// <param name="buffer">用于存放结果的字节数组。</param>
/// <param name="startIndex">buffer 内的起始位置。</param>
public static void GetBytes(char value, byte[] buffer, int startIndex)
{
GetBytes((short)value, buffer, startIndex);
}
/// <summary>
/// 返回由字节数组中前两个字节转换来的 Unicode 字符。
/// </summary>
/// <param name="value">字节数组。</param>
/// <returns>由两个字节构成的字符。</returns>
public static char GetChar(byte[] value)
{
return BitConverter.ToChar(value, 0);
}
/// <summary>
/// 返回由字节数组中指定位置的两个字节转换来的 Unicode 字符。
/// </summary>
/// <param name="value">字节数组。</param>
/// <param name="startIndex">value 内的起始位置。</param>
/// <returns>由两个字节构成的字符。</returns>
public static char GetChar(byte[] value, int startIndex)
{
return BitConverter.ToChar(value, startIndex);
}
/// <summary>
/// 以字节数组的形式获取指定的 16 位有符号整数值。
/// </summary>
/// <param name="value">要转换的数字。</param>
/// <returns>用于存放结果的字节数组。</returns>
public static byte[] GetBytes(short value)
{
byte[] buffer = new byte[2];
GetBytes(value, buffer, 0);
return buffer;
}
/// <summary>
/// 以字节数组的形式获取指定的 16 位有符号整数值。
/// </summary>
/// <param name="value">要转换的数字。</param>
/// <param name="buffer">用于存放结果的字节数组。</param>
public static void GetBytes(short value, byte[] buffer)
{
GetBytes(value, buffer, 0);
}
/// <summary>
/// 以字节数组的形式获取指定的 16 位有符号整数值。
/// </summary>
/// <param name="value">要转换的数字。</param>
/// <param name="buffer">用于存放结果的字节数组。</param>
/// <param name="startIndex">buffer 内的起始位置。</param>
public static unsafe void GetBytes(short value, byte[] buffer, int startIndex)
{
if (buffer == null)
{
throw new GameFrameworkException("Buffer is invalid.");
}
if (startIndex < 0 || startIndex + 2 > buffer.Length)
{
throw new GameFrameworkException("Start index is invalid.");
}
fixed (byte* valueRef = buffer)
{
*(short*)(valueRef + startIndex) = value;
}
}
/// <summary>
/// 返回由字节数组中前两个字节转换来的 16 位有符号整数。
/// </summary>
/// <param name="value">字节数组。</param>
/// <returns>由两个字节构成的 16 位有符号整数。</returns>
public static short GetInt16(byte[] value)
{
return BitConverter.ToInt16(value, 0);
}
/// <summary>
/// 返回由字节数组中指定位置的两个字节转换来的 16 位有符号整数。
/// </summary>
/// <param name="value">字节数组。</param>
/// <param name="startIndex">value 内的起始位置。</param>
/// <returns>由两个字节构成的 16 位有符号整数。</returns>
public static short GetInt16(byte[] value, int startIndex)
{
return BitConverter.ToInt16(value, startIndex);
}
/// <summary>
/// 以字节数组的形式获取指定的 16 位无符号整数值。
/// </summary>
/// <param name="value">要转换的数字。</param>
/// <returns>用于存放结果的字节数组。</returns>
public static byte[] GetBytes(ushort value)
{
byte[] buffer = new byte[2];
GetBytes((short)value, buffer, 0);
return buffer;
}
/// <summary>
/// 以字节数组的形式获取指定的 16 位无符号整数值。
/// </summary>
/// <param name="value">要转换的数字。</param>
/// <param name="buffer">用于存放结果的字节数组。</param>
public static void GetBytes(ushort value, byte[] buffer)
{
GetBytes((short)value, buffer, 0);
}
/// <summary>
/// 以字节数组的形式获取指定的 16 位无符号整数值。
/// </summary>
/// <param name="value">要转换的数字。</param>
/// <param name="buffer">用于存放结果的字节数组。</param>
/// <param name="startIndex">buffer 内的起始位置。</param>
public static void GetBytes(ushort value, byte[] buffer, int startIndex)
{
GetBytes((short)value, buffer, startIndex);
}
/// <summary>
/// 返回由字节数组中前两个字节转换来的 16 位无符号整数。
/// </summary>
/// <param name="value">字节数组。</param>
/// <returns>由两个字节构成的 16 位无符号整数。</returns>
public static ushort GetUInt16(byte[] value)
{
return BitConverter.ToUInt16(value, 0);
}
/// <summary>
/// 返回由字节数组中指定位置的两个字节转换来的 16 位无符号整数。
/// </summary>
/// <param name="value">字节数组。</param>
/// <param name="startIndex">value 内的起始位置。</param>
/// <returns>由两个字节构成的 16 位无符号整数。</returns>
public static ushort GetUInt16(byte[] value, int startIndex)
{
return BitConverter.ToUInt16(value, startIndex);
}
/// <summary>
/// 以字节数组的形式获取指定的 32 位有符号整数值。
/// </summary>
/// <param name="value">要转换的数字。</param>
/// <returns>用于存放结果的字节数组。</returns>
public static byte[] GetBytes(int value)
{
byte[] buffer = new byte[4];
GetBytes(value, buffer, 0);
return buffer;
}
/// <summary>
/// 以字节数组的形式获取指定的 32 位有符号整数值。
/// </summary>
/// <param name="value">要转换的数字。</param>
/// <param name="buffer">用于存放结果的字节数组。</param>
public static void GetBytes(int value, byte[] buffer)
{
GetBytes(value, buffer, 0);
}
/// <summary>
/// 以字节数组的形式获取指定的 32 位有符号整数值。
/// </summary>
/// <param name="value">要转换的数字。</param>
/// <param name="buffer">用于存放结果的字节数组。</param>
/// <param name="startIndex">buffer 内的起始位置。</param>
public static unsafe void GetBytes(int value, byte[] buffer, int startIndex)
{
if (buffer == null)
{
throw new GameFrameworkException("Buffer is invalid.");
}
if (startIndex < 0 || startIndex + 4 > buffer.Length)
{
throw new GameFrameworkException("Start index is invalid.");
}
fixed (byte* valueRef = buffer)
{
*(int*)(valueRef + startIndex) = value;
}
}
/// <summary>
/// 返回由字节数组中前四个字节转换来的 32 位有符号整数。
/// </summary>
/// <param name="value">字节数组。</param>
/// <returns>由四个字节构成的 32 位有符号整数。</returns>
public static int GetInt32(byte[] value)
{
return BitConverter.ToInt32(value, 0);
}
/// <summary>
/// 返回由字节数组中指定位置的四个字节转换来的 32 位有符号整数。
/// </summary>
/// <param name="value">字节数组。</param>
/// <param name="startIndex">value 内的起始位置。</param>
/// <returns>由四个字节构成的 32 位有符号整数。</returns>
public static int GetInt32(byte[] value, int startIndex)
{
return BitConverter.ToInt32(value, startIndex);
}
/// <summary>
/// 以字节数组的形式获取指定的 32 位无符号整数值。
/// </summary>
/// <param name="value">要转换的数字。</param>
/// <returns>用于存放结果的字节数组。</returns>
public static byte[] GetBytes(uint value)
{
byte[] buffer = new byte[4];
GetBytes((int)value, buffer, 0);
return buffer;
}
/// <summary>
/// 以字节数组的形式获取指定的 32 位无符号整数值。
/// </summary>
/// <param name="value">要转换的数字。</param>
/// <param name="buffer">用于存放结果的字节数组。</param>
public static void GetBytes(uint value, byte[] buffer)
{
GetBytes((int)value, buffer, 0);
}
/// <summary>
/// 以字节数组的形式获取指定的 32 位无符号整数值。
/// </summary>
/// <param name="value">要转换的数字。</param>
/// <param name="buffer">用于存放结果的字节数组。</param>
/// <param name="startIndex">buffer 内的起始位置。</param>
public static void GetBytes(uint value, byte[] buffer, int startIndex)
{
GetBytes((int)value, buffer, startIndex);
}
/// <summary>
/// 返回由字节数组中前四个字节转换来的 32 位无符号整数。
/// </summary>
/// <param name="value">字节数组。</param>
/// <returns>由四个字节构成的 32 位无符号整数。</returns>
public static uint GetUInt32(byte[] value)
{
return BitConverter.ToUInt32(value, 0);
}
/// <summary>
/// 返回由字节数组中指定位置的四个字节转换来的 32 位无符号整数。
/// </summary>
/// <param name="value">字节数组。</param>
/// <param name="startIndex">value 内的起始位置。</param>
/// <returns>由四个字节构成的 32 位无符号整数。</returns>
public static uint GetUInt32(byte[] value, int startIndex)
{
return BitConverter.ToUInt32(value, startIndex);
}
/// <summary>
/// 以字节数组的形式获取指定的 64 位有符号整数值。
/// </summary>
/// <param name="value">要转换的数字。</param>
/// <returns>用于存放结果的字节数组。</returns>
public static byte[] GetBytes(long value)
{
byte[] buffer = new byte[8];
GetBytes(value, buffer, 0);
return buffer;
}
/// <summary>
/// 以字节数组的形式获取指定的 64 位有符号整数值。
/// </summary>
/// <param name="value">要转换的数字。</param>
/// <param name="buffer">用于存放结果的字节数组。</param>
public static void GetBytes(long value, byte[] buffer)
{
GetBytes(value, buffer, 0);
}
/// <summary>
/// 以字节数组的形式获取指定的 64 位有符号整数值。
/// </summary>
/// <param name="value">要转换的数字。</param>
/// <param name="buffer">用于存放结果的字节数组。</param>
/// <param name="startIndex">buffer 内的起始位置。</param>
public static unsafe void GetBytes(long value, byte[] buffer, int startIndex)
{
if (buffer == null)
{
throw new GameFrameworkException("Buffer is invalid.");
}
if (startIndex < 0 || startIndex + 8 > buffer.Length)
{
throw new GameFrameworkException("Start index is invalid.");
}
fixed (byte* valueRef = buffer)
{
*(long*)(valueRef + startIndex) = value;
}
}
/// <summary>
/// 返回由字节数组中前八个字节转换来的 64 位有符号整数。
/// </summary>
/// <param name="value">字节数组。</param>
/// <returns>由八个字节构成的 64 位有符号整数。</returns>
public static long GetInt64(byte[] value)
{
return BitConverter.ToInt64(value, 0);
}
/// <summary>
/// 返回由字节数组中指定位置的八个字节转换来的 64 位有符号整数。
/// </summary>
/// <param name="value">字节数组。</param>
/// <param name="startIndex">value 内的起始位置。</param>
/// <returns>由八个字节构成的 64 位有符号整数。</returns>
public static long GetInt64(byte[] value, int startIndex)
{
return BitConverter.ToInt64(value, startIndex);
}
/// <summary>
/// 以字节数组的形式获取指定的 64 位无符号整数值。
/// </summary>
/// <param name="value">要转换的数字。</param>
/// <returns>用于存放结果的字节数组。</returns>
public static byte[] GetBytes(ulong value)
{
byte[] buffer = new byte[8];
GetBytes((long)value, buffer, 0);
return buffer;
}
/// <summary>
/// 以字节数组的形式获取指定的 64 位无符号整数值。
/// </summary>
/// <param name="value">要转换的数字。</param>
/// <param name="buffer">用于存放结果的字节数组。</param>
public static void GetBytes(ulong value, byte[] buffer)
{
GetBytes((long)value, buffer, 0);
}
/// <summary>
/// 以字节数组的形式获取指定的 64 位无符号整数值。
/// </summary>
/// <param name="value">要转换的数字。</param>
/// <param name="buffer">用于存放结果的字节数组。</param>
/// <param name="startIndex">buffer 内的起始位置。</param>
public static void GetBytes(ulong value, byte[] buffer, int startIndex)
{
GetBytes((long)value, buffer, startIndex);
}
/// <summary>
/// 返回由字节数组中前八个字节转换来的 64 位无符号整数。
/// </summary>
/// <param name="value">字节数组。</param>
/// <returns>由八个字节构成的 64 位无符号整数。</returns>
public static ulong GetUInt64(byte[] value)
{
return BitConverter.ToUInt64(value, 0);
}
/// <summary>
/// 返回由字节数组中指定位置的八个字节转换来的 64 位无符号整数。
/// </summary>
/// <param name="value">字节数组。</param>
/// <param name="startIndex">value 内的起始位置。</param>
/// <returns>由八个字节构成的 64 位无符号整数。</returns>
public static ulong GetUInt64(byte[] value, int startIndex)
{
return BitConverter.ToUInt64(value, startIndex);
}
/// <summary>
/// 以字节数组的形式获取指定的单精度浮点值。
/// </summary>
/// <param name="value">要转换的数字。</param>
/// <returns>用于存放结果的字节数组。</returns>
public static unsafe byte[] GetBytes(float value)
{
byte[] buffer = new byte[4];
GetBytes(*(int*)&value, buffer, 0);
return buffer;
}
/// <summary>
/// 以字节数组的形式获取指定的单精度浮点值。
/// </summary>
/// <param name="value">要转换的数字。</param>
/// <param name="buffer">用于存放结果的字节数组。</param>
public static unsafe void GetBytes(float value, byte[] buffer)
{
GetBytes(*(int*)&value, buffer, 0);
}
/// <summary>
/// 以字节数组的形式获取指定的单精度浮点值。
/// </summary>
/// <param name="value">要转换的数字。</param>
/// <param name="buffer">用于存放结果的字节数组。</param>
/// <param name="startIndex">buffer 内的起始位置。</param>
public static unsafe void GetBytes(float value, byte[] buffer, int startIndex)
{
GetBytes(*(int*)&value, buffer, startIndex);
}
/// <summary>
/// 返回由字节数组中前四个字节转换来的单精度浮点数。
/// </summary>
/// <param name="value">字节数组。</param>
/// <returns>由四个字节构成的单精度浮点数。</returns>
public static float GetSingle(byte[] value)
{
return BitConverter.ToSingle(value, 0);
}
/// <summary>
/// 返回由字节数组中指定位置的四个字节转换来的单精度浮点数。
/// </summary>
/// <param name="value">字节数组。</param>
/// <param name="startIndex">value 内的起始位置。</param>
/// <returns>由四个字节构成的单精度浮点数。</returns>
public static float GetSingle(byte[] value, int startIndex)
{
return BitConverter.ToSingle(value, startIndex);
}
/// <summary>
/// 以字节数组的形式获取指定的双精度浮点值。
/// </summary>
/// <param name="value">要转换的数字。</param>
/// <returns>用于存放结果的字节数组。</returns>
public static unsafe byte[] GetBytes(double value)
{
byte[] buffer = new byte[8];
GetBytes(*(long*)&value, buffer, 0);
return buffer;
}
/// <summary>
/// 以字节数组的形式获取指定的双精度浮点值。
/// </summary>
/// <param name="value">要转换的数字。</param>
/// <param name="buffer">用于存放结果的字节数组。</param>
public static unsafe void GetBytes(double value, byte[] buffer)
{
GetBytes(*(long*)&value, buffer, 0);
}
/// <summary>
/// 以字节数组的形式获取指定的双精度浮点值。
/// </summary>
/// <param name="value">要转换的数字。</param>
/// <param name="buffer">用于存放结果的字节数组。</param>
/// <param name="startIndex">buffer 内的起始位置。</param>
public static unsafe void GetBytes(double value, byte[] buffer, int startIndex)
{
GetBytes(*(long*)&value, buffer, startIndex);
}
/// <summary>
/// 返回由字节数组中前八个字节转换来的双精度浮点数。
/// </summary>
/// <param name="value">字节数组。</param>
/// <returns>由八个字节构成的双精度浮点数。</returns>
public static double GetDouble(byte[] value)
{
return BitConverter.ToDouble(value, 0);
}
/// <summary>
/// 返回由字节数组中指定位置的八个字节转换来的双精度浮点数。
/// </summary>
/// <param name="value">字节数组。</param>
/// <param name="startIndex">value 内的起始位置。</param>
/// <returns>由八个字节构成的双精度浮点数。</returns>
public static double GetDouble(byte[] value, int startIndex)
{
return BitConverter.ToDouble(value, startIndex);
}
/// <summary>
/// 以字节数组的形式获取 UTF-8 编码的字符串。
/// </summary>
/// <param name="value">要转换的字符串。</param>
/// <returns>用于存放结果的字节数组。</returns>
public static byte[] GetBytes(string value)
{
return GetBytes(value, Encoding.UTF8);
}
/// <summary>
/// 以字节数组的形式获取 UTF-8 编码的字符串。
/// </summary>
/// <param name="value">要转换的字符串。</param>
/// <param name="buffer">用于存放结果的字节数组。</param>
/// <returns>buffer 内实际填充了多少字节。</returns>
public static int GetBytes(string value, byte[] buffer)
{
return GetBytes(value, Encoding.UTF8, buffer, 0);
}
/// <summary>
/// 以字节数组的形式获取 UTF-8 编码的字符串。
/// </summary>
/// <param name="value">要转换的字符串。</param>
/// <param name="buffer">用于存放结果的字节数组。</param>
/// <param name="startIndex">buffer 内的起始位置。</param>
/// <returns>buffer 内实际填充了多少字节。</returns>
public static int GetBytes(string value, byte[] buffer, int startIndex)
{
return GetBytes(value, Encoding.UTF8, buffer, startIndex);
}
/// <summary>
/// 以字节数组的形式获取指定编码的字符串。
/// </summary>
/// <param name="value">要转换的字符串。</param>
/// <param name="encoding">要使用的编码。</param>
/// <returns>用于存放结果的字节数组。</returns>
public static byte[] GetBytes(string value, Encoding encoding)
{
if (value == null)
{
throw new GameFrameworkException("Value is invalid.");
}
if (encoding == null)
{
throw new GameFrameworkException("Encoding is invalid.");
}
return encoding.GetBytes(value);
}
/// <summary>
/// 以字节数组的形式获取指定编码的字符串。
/// </summary>
/// <param name="value">要转换的字符串。</param>
/// <param name="encoding">要使用的编码。</param>
/// <param name="buffer">用于存放结果的字节数组。</param>
/// <returns>buffer 内实际填充了多少字节。</returns>
public static int GetBytes(string value, Encoding encoding, byte[] buffer)
{
return GetBytes(value, encoding, buffer, 0);
}
/// <summary>
/// 以字节数组的形式获取指定编码的字符串。
/// </summary>
/// <param name="value">要转换的字符串。</param>
/// <param name="encoding">要使用的编码。</param>
/// <param name="buffer">用于存放结果的字节数组。</param>
/// <param name="startIndex">buffer 内的起始位置。</param>
/// <returns>buffer 内实际填充了多少字节。</returns>
public static int GetBytes(string value, Encoding encoding, byte[] buffer, int startIndex)
{
if (value == null)
{
throw new GameFrameworkException("Value is invalid.");
}
if (encoding == null)
{
throw new GameFrameworkException("Encoding is invalid.");
}
return encoding.GetBytes(value, 0, value.Length, buffer, startIndex);
}
/// <summary>
/// 返回由字节数组使用 UTF-8 编码转换成的字符串。
/// </summary>
/// <param name="value">字节数组。</param>
/// <returns>转换后的字符串。</returns>
public static string GetString(byte[] value)
{
return GetString(value, Encoding.UTF8);
}
/// <summary>
/// 返回由字节数组使用指定编码转换成的字符串。
/// </summary>
/// <param name="value">字节数组。</param>
/// <param name="encoding">要使用的编码。</param>
/// <returns>转换后的字符串。</returns>
public static string GetString(byte[] value, Encoding encoding)
{
if (value == null)
{
throw new GameFrameworkException("Value is invalid.");
}
if (encoding == null)
{
throw new GameFrameworkException("Encoding is invalid.");
}
return encoding.GetString(value);
}
/// <summary>
/// 返回由字节数组使用 UTF-8 编码转换成的字符串。
/// </summary>
/// <param name="value">字节数组。</param>
/// <param name="startIndex">value 内的起始位置。</param>
/// <param name="length">长度。</param>
/// <returns>转换后的字符串。</returns>
public static string GetString(byte[] value, int startIndex, int length)
{
return GetString(value, startIndex, length, Encoding.UTF8);
}
/// <summary>
/// 返回由字节数组使用指定编码转换成的字符串。
/// </summary>
/// <param name="value">字节数组。</param>
/// <param name="startIndex">value 内的起始位置。</param>
/// <param name="length">长度。</param>
/// <param name="encoding">要使用的编码。</param>
/// <returns>转换后的字符串。</returns>
public static string GetString(byte[] value, int startIndex, int length, Encoding encoding)
{
if (value == null)
{
throw new GameFrameworkException("Value is invalid.");
}
if (encoding == null)
{
throw new GameFrameworkException("Encoding is invalid.");
}
return encoding.GetString(value, startIndex, length);
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7362a66e3741e8440bcc831815b4426c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,127 @@
using System;
namespace TEngine
{
public static partial class Utility
{
/// <summary>
/// 加密解密相关的实用函数。
/// </summary>
public static class Encryption
{
internal const int QuickEncryptLength = 220;
/// <summary>
/// 将 bytes 使用 code 做异或运算的快速版本。
/// </summary>
/// <param name="bytes">原始二进制流。</param>
/// <param name="code">异或二进制流。</param>
/// <returns>异或后的二进制流。</returns>
public static byte[] GetQuickXorBytes(byte[] bytes, byte[] code)
{
return GetXorBytes(bytes, 0, QuickEncryptLength, code);
}
/// <summary>
/// 将 bytes 使用 code 做异或运算的快速版本。此方法将复用并改写传入的 bytes 作为返回值,而不额外分配内存空间。
/// </summary>
/// <param name="bytes">原始及异或后的二进制流。</param>
/// <param name="code">异或二进制流。</param>
public static void GetQuickSelfXorBytes(byte[] bytes, byte[] code)
{
GetSelfXorBytes(bytes, 0, QuickEncryptLength, code);
}
/// <summary>
/// 将 bytes 使用 code 做异或运算。
/// </summary>
/// <param name="bytes">原始二进制流。</param>
/// <param name="code">异或二进制流。</param>
/// <returns>异或后的二进制流。</returns>
public static byte[] GetXorBytes(byte[] bytes, byte[] code)
{
if (bytes == null)
{
return null;
}
return GetXorBytes(bytes, 0, bytes.Length, code);
}
/// <summary>
/// 将 bytes 使用 code 做异或运算。此方法将复用并改写传入的 bytes 作为返回值,而不额外分配内存空间。
/// </summary>
/// <param name="bytes">原始及异或后的二进制流。</param>
/// <param name="code">异或二进制流。</param>
public static void GetSelfXorBytes(byte[] bytes, byte[] code)
{
if (bytes == null)
{
return;
}
GetSelfXorBytes(bytes, 0, bytes.Length, code);
}
/// <summary>
/// 将 bytes 使用 code 做异或运算。
/// </summary>
/// <param name="bytes">原始二进制流。</param>
/// <param name="startIndex">异或计算的开始位置。</param>
/// <param name="length">异或计算长度,若小于 0则计算整个二进制流。</param>
/// <param name="code">异或二进制流。</param>
/// <returns>异或后的二进制流。</returns>
public static byte[] GetXorBytes(byte[] bytes, int startIndex, int length, byte[] code)
{
if (bytes == null)
{
return null;
}
int bytesLength = bytes.Length;
byte[] results = new byte[bytesLength];
Array.Copy(bytes, 0, results, 0, bytesLength);
GetSelfXorBytes(results, startIndex, length, code);
return results;
}
/// <summary>
/// 将 bytes 使用 code 做异或运算。此方法将复用并改写传入的 bytes 作为返回值,而不额外分配内存空间。
/// </summary>
/// <param name="bytes">原始及异或后的二进制流。</param>
/// <param name="startIndex">异或计算的开始位置。</param>
/// <param name="length">异或计算长度。</param>
/// <param name="code">异或二进制流。</param>
public static void GetSelfXorBytes(byte[] bytes, int startIndex, int length, byte[] code)
{
if (bytes == null)
{
return;
}
if (code == null)
{
throw new GameFrameworkException("Code is invalid.");
}
int codeLength = code.Length;
if (codeLength <= 0)
{
throw new GameFrameworkException("Code length is invalid.");
}
if (startIndex < 0 || length < 0 || startIndex + length > bytes.Length)
{
throw new GameFrameworkException("Start index or length is invalid.");
}
int codeIndex = startIndex % codeLength;
for (int i = startIndex; i < length; i++)
{
bytes[i] ^= code[codeIndex++];
codeIndex %= codeLength;
}
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a279fdc81b03f4847a1b1a209af2a68e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,232 @@
using System;
using System.IO;
using System.Text;
using UnityEditor;
using UnityEngine;
namespace TEngine
{
/// <summary>
/// Unity平台路径类型。
/// </summary>
public enum UnityPlatformPathType : int
{
dataPath = 0,
streamingAssetsPath,
persistentDataPath,
temporaryCachePath,
}
public static partial class Utility
{
/// <summary>
/// 文件相关的实用函数。
/// </summary>
public static class File
{
public static bool CreateFile(string filePath, bool isCreateDir = true)
{
if (!System.IO.File.Exists(filePath))
{
string dir = System.IO.Path.GetDirectoryName(filePath);
if (!Directory.Exists(dir))
{
if (isCreateDir)
{
Directory.CreateDirectory(dir);
}
else
{
Log.Error("文件夹不存在 Path=" + dir);
return false;
}
}
System.IO.File.Create(filePath);
}
return true;
}
public static bool CreateFile(string filePath, string info, bool isCreateDir = true)
{
StreamWriter sw;
FileInfo t = new FileInfo(filePath);
if (!t.Exists)
{
string dir = System.IO.Path.GetDirectoryName(filePath);
if (!Directory.Exists(dir))
{
if (isCreateDir)
{
Directory.CreateDirectory(dir);
}
else
{
#if UNITY_EDITOR
EditorUtility.DisplayDialog("Tips", "文件夹不存在", "CANCEL");
#endif
Log.Error("文件夹不存在 Path=" + dir);
return false;
}
}
sw = t.CreateText();
}
else
{
sw = t.AppendText();
}
sw.WriteLine(info);
sw.Close();
sw.Dispose();
return true;
}
public static string GetPersistentDataPlatformPath(string filePath)
{
filePath =
#if UNITY_ANDROID && !UNITY_EDITOR
Application.dataPath + "!assets" + "/" + filePath;
#else
Application.streamingAssetsPath + "/" + filePath;
#endif
return filePath;
}
public static string GetPath(string path)
{
return path.Replace("\\", "/");
}
public static string Md5ByPathName(string pathName)
{
try
{
FileStream file = new FileStream(pathName, FileMode.Open);
System.Security.Cryptography.MD5 md5 = new System.Security.Cryptography.MD5CryptoServiceProvider();
byte[] retVal = md5.ComputeHash(file);
file.Close();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < retVal.Length; i++)
{
sb.Append(retVal[i].ToString("x2"));
}
return sb.ToString();
}
catch (Exception ex)
{
Log.Error("to md5 fail,error:" + ex.Message);
return "Error";
}
}
public static string GetLengthString(long length)
{
if (length < 1024)
{
return $"{length.ToString()} Bytes";
}
if (length < 1024 * 1024)
{
return $"{(length / 1024f):F2} KB";
}
return length < 1024 * 1024 * 1024 ? $"{(length / 1024f / 1024f):F2} MB" : $"{(length / 1024f / 1024f / 1024f):F2} GB";
}
public static string GetByteLengthString(long byteLength)
{
if (byteLength < 1024L) // 2 ^ 10
{
return Utility.Text.Format("{0} Bytes", byteLength.ToString());
}
if (byteLength < 1048576L) // 2 ^ 20
{
return Utility.Text.Format("{0} KB", (byteLength / 1024f).ToString("F2"));
}
if (byteLength < 1073741824L) // 2 ^ 30
{
return Utility.Text.Format("{0} MB", (byteLength / 1048576f).ToString("F2"));
}
if (byteLength < 1099511627776L) // 2 ^ 40
{
return Utility.Text.Format("{0} GB", (byteLength / 1073741824f).ToString("F2"));
}
if (byteLength < 1125899906842624L) // 2 ^ 50
{
return Utility.Text.Format("{0} TB", (byteLength / 1099511627776f).ToString("F2"));
}
if (byteLength < 1152921504606846976L) // 2 ^ 60
{
return Utility.Text.Format("{0} PB", (byteLength / 1125899906842624f).ToString("F2"));
}
return Utility.Text.Format("{0} EB", (byteLength / 1152921504606846976f).ToString("F2"));
}
public static string BinToUtf8(byte[] total)
{
byte[] result = total;
if (total[0] == 0xef && total[1] == 0xbb && total[2] == 0xbf)
{
// utf8文件的前三个字节为特殊占位符要跳过
result = new byte[total.Length - 3];
System.Array.Copy(total, 3, result, 0, total.Length - 3);
}
string utf8string = System.Text.Encoding.UTF8.GetString(result);
return utf8string;
}
/// <summary>
/// 数据格式转换
/// </summary>
/// <param name="data">数据</param>
/// <returns></returns>
public static string FormatData(long data)
{
string result = "";
if (data < 0)
data = 0;
if (data > 1024 * 1024)
{
result = ((int)(data / (1024 * 1024))).ToString() + "MB";
}
else if (data > 1024)
{
result = ((int)(data / 1024)).ToString() + "KB";
}
else
{
result = data + "B";
}
return result;
}
/// <summary>
/// 获取文件大小
/// </summary>
/// <param name="path">文件路径</param>
/// <returns></returns>
public static long GetFileSize(string path)
{
using (FileStream file = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
return file.Length;
}
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6d1483cbdd562774a95cb697ed574e43
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,134 @@
using System;
using System.Collections.Generic;
using System.IO;
namespace TEngine
{
public static partial class Utility
{
/// <summary>
/// Folder 相关的实用函数。
/// </summary>
public static partial class Folder
{
/// <summary>
/// 清理文件夹。
/// </summary>
/// <param name="path">文件夹路径。</param>
/// <returns>操作成功。</returns>
public static bool ClearFolder(string path)
{
try
{
var di = new DirectoryInfo(path);
if (!di.Exists)
{
return false;
}
foreach (var file in di.GetFiles())
{
file.Delete();
}
foreach (var dir in di.GetDirectories())
{
dir.Delete(true);
}
return true;
}
catch (Exception e)
{
throw new GameFrameworkException($"ClearFolder invalid:{e.Message}");
}
}
/// <summary>
/// 拷贝文件到根目录。
/// </summary>
/// <param name="sourceRootPath">源文件目录。</param>
/// <param name="destRootPath">目标文件目录。</param>
/// <param name="searchOption">查找选项。</param>
/// <returns>操作成功。</returns>
public static bool CopyFilesToRootPath(string sourceRootPath, string destRootPath, SearchOption searchOption = SearchOption.AllDirectories)
{
string[] fileNames = Directory.GetFiles(sourceRootPath, "*", searchOption);
foreach (string fileName in fileNames)
{
string destFileName = System.IO.Path.Combine(destRootPath, fileName.Substring(sourceRootPath.Length));
FileInfo destFileInfo = new FileInfo(destFileName);
if (destFileInfo.Directory != null && !destFileInfo.Directory.Exists)
{
destFileInfo.Directory.Create();
}
System.IO.File.Copy(fileName, destFileName, true);
}
return true;
}
/// <summary>
/// 拷贝文件夹。
/// </summary>
/// <param name="srcPath">需要被拷贝的文件夹路径。</param>
/// <param name="tarPath">拷贝目标路径。</param>
public static bool CopyFolder(string srcPath, string tarPath)
{
if (!Directory.Exists(srcPath))
{
return false;
}
if (!Directory.Exists(tarPath))
{
Directory.CreateDirectory(tarPath);
}
//获得源文件下所有文件
List<string> files = new List<string>(Directory.GetFiles(srcPath));
files.ForEach(f =>
{
string destFile = System.IO.Path.Combine(tarPath, System.IO.Path.GetFileName(f));
System.IO.File.Copy(f, destFile, true); //覆盖模式
});
//获得源文件下所有目录文件
List<string> folders = new List<string>(Directory.GetDirectories(srcPath));
folders.ForEach(f =>
{
string destDir = System.IO.Path.Combine(tarPath, System.IO.Path.GetFileName(f));
CopyFolder(f, destDir); //递归实现子文件夹拷贝
});
return true;
}
/// <summary>
/// 拷贝文件。
/// </summary>
/// <param name="sourceRootPath">源文件目录。</param>
/// <param name="destRootPath">目标文件目录。</param>
/// <param name="searchOption">搜索选项。</param>
/// <returns>操作成功。</returns>
public static bool CopyFiles(string sourceRootPath, string destRootPath, SearchOption searchOption = SearchOption.AllDirectories)
{
string[] fileNames = Directory.GetFiles(sourceRootPath, "*", searchOption);
foreach (string fileName in fileNames)
{
FileInfo sourceFileInfo = new FileInfo(fileName);
string destFileName = System.IO.Path.Combine(destRootPath, sourceFileInfo.Name);
FileInfo destFileInfo = new FileInfo(destFileName);
if (destFileInfo.Directory != null && !destFileInfo.Directory.Exists)
{
destFileInfo.Directory.Create();
}
System.IO.File.Copy(fileName, destFileName, true);
}
return true;
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 30d9951d450df9647a77c814ea8f68f6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,39 @@
using System;
namespace TEngine
{
public static partial class Utility
{
public static partial class Json
{
/// <summary>
/// JSON 辅助器接口。
/// </summary>
public interface IJsonHelper
{
/// <summary>
/// 将对象序列化为 JSON 字符串。
/// </summary>
/// <param name="obj">要序列化的对象。</param>
/// <returns>序列化后的 JSON 字符串。</returns>
string ToJson(object obj);
/// <summary>
/// 将 JSON 字符串反序列化为对象。
/// </summary>
/// <typeparam name="T">对象类型。</typeparam>
/// <param name="json">要反序列化的 JSON 字符串。</param>
/// <returns>反序列化后的对象。</returns>
T ToObject<T>(string json);
/// <summary>
/// 将 JSON 字符串反序列化为对象。
/// </summary>
/// <param name="objectType">对象类型。</param>
/// <param name="json">要反序列化的 JSON 字符串。</param>
/// <returns>反序列化后的对象。</returns>
object ToObject(Type objectType, string json);
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 54fba14fdfb53ab4f9edcd7eb3a9bc4c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,112 @@
using System;
namespace TEngine
{
public static partial class Utility
{
/// <summary>
/// JSON 相关的实用函数。
/// </summary>
public static partial class Json
{
private static IJsonHelper s_JsonHelper = null;
/// <summary>
/// 设置 JSON 辅助器。
/// </summary>
/// <param name="jsonHelper">要设置的 JSON 辅助器。</param>
public static void SetJsonHelper(IJsonHelper jsonHelper)
{
s_JsonHelper = jsonHelper;
}
/// <summary>
/// 将对象序列化为 JSON 字符串。
/// </summary>
/// <param name="obj">要序列化的对象。</param>
/// <returns>序列化后的 JSON 字符串。</returns>
public static string ToJson(object obj)
{
if (s_JsonHelper == null)
{
throw new GameFrameworkException("JSON helper is invalid.");
}
try
{
return s_JsonHelper.ToJson(obj);
}
catch (Exception exception)
{
if (exception is GameFrameworkException)
{
throw;
}
throw new GameFrameworkException(Text.Format("Can not convert to JSON with exception '{0}'.", exception), exception);
}
}
/// <summary>
/// 将 JSON 字符串反序列化为对象。
/// </summary>
/// <typeparam name="T">对象类型。</typeparam>
/// <param name="json">要反序列化的 JSON 字符串。</param>
/// <returns>反序列化后的对象。</returns>
public static T ToObject<T>(string json)
{
if (s_JsonHelper == null)
{
throw new GameFrameworkException("JSON helper is invalid.");
}
try
{
return s_JsonHelper.ToObject<T>(json);
}
catch (Exception exception)
{
if (exception is GameFrameworkException)
{
throw;
}
throw new GameFrameworkException(Text.Format("Can not convert to object with exception '{0}'.", exception), exception);
}
}
/// <summary>
/// 将 JSON 字符串反序列化为对象。
/// </summary>
/// <param name="objectType">对象类型。</param>
/// <param name="json">要反序列化的 JSON 字符串。</param>
/// <returns>反序列化后的对象。</returns>
public static object ToObject(Type objectType, string json)
{
if (s_JsonHelper == null)
{
throw new GameFrameworkException("JSON helper is invalid.");
}
if (objectType == null)
{
throw new GameFrameworkException("Object type is invalid.");
}
try
{
return s_JsonHelper.ToObject(objectType, json);
}
catch (Exception exception)
{
if (exception is GameFrameworkException)
{
throw;
}
throw new GameFrameworkException(Text.Format("Can not convert to object with exception '{0}'.", exception), exception);
}
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4ee7fcac5a1ebab449eba2456434d3e6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,233 @@
using System;
namespace TEngine
{
public static partial class Utility
{
/// <summary>
/// Marshal 相关的实用函数。
/// </summary>
public static class Marshal
{
private const int BlockSize = 1024 * 4;
private static IntPtr s_CachedHGlobalPtr = IntPtr.Zero;
private static int s_CachedHGlobalSize = 0;
/// <summary>
/// 获取缓存的从进程的非托管内存中分配的内存的大小。
/// </summary>
public static int CachedHGlobalSize
{
get
{
return s_CachedHGlobalSize;
}
}
/// <summary>
/// 确保从进程的非托管内存中分配足够大小的内存并缓存。
/// </summary>
/// <param name="ensureSize">要确保从进程的非托管内存中分配内存的大小。</param>
public static void EnsureCachedHGlobalSize(int ensureSize)
{
if (ensureSize < 0)
{
throw new GameFrameworkException("Ensure size is invalid.");
}
if (s_CachedHGlobalPtr == IntPtr.Zero || s_CachedHGlobalSize < ensureSize)
{
FreeCachedHGlobal();
int size = (ensureSize - 1 + BlockSize) / BlockSize * BlockSize;
s_CachedHGlobalPtr = System.Runtime.InteropServices.Marshal.AllocHGlobal(size);
s_CachedHGlobalSize = size;
}
}
/// <summary>
/// 释放缓存的从进程的非托管内存中分配的内存。
/// </summary>
public static void FreeCachedHGlobal()
{
if (s_CachedHGlobalPtr != IntPtr.Zero)
{
System.Runtime.InteropServices.Marshal.FreeHGlobal(s_CachedHGlobalPtr);
s_CachedHGlobalPtr = IntPtr.Zero;
s_CachedHGlobalSize = 0;
}
}
/// <summary>
/// 将数据从对象转换为二进制流。
/// </summary>
/// <typeparam name="T">要转换的对象的类型。</typeparam>
/// <param name="structure">要转换的对象。</param>
/// <returns>存储转换结果的二进制流。</returns>
public static byte[] StructureToBytes<T>(T structure)
{
return StructureToBytes(structure, System.Runtime.InteropServices.Marshal.SizeOf(typeof(T)));
}
/// <summary>
/// 将数据从对象转换为二进制流。
/// </summary>
/// <typeparam name="T">要转换的对象的类型。</typeparam>
/// <param name="structure">要转换的对象。</param>
/// <param name="structureSize">要转换的对象的大小。</param>
/// <returns>存储转换结果的二进制流。</returns>
internal static byte[] StructureToBytes<T>(T structure, int structureSize)
{
if (structureSize < 0)
{
throw new GameFrameworkException("Structure size is invalid.");
}
EnsureCachedHGlobalSize(structureSize);
System.Runtime.InteropServices.Marshal.StructureToPtr(structure, s_CachedHGlobalPtr, true);
byte[] result = new byte[structureSize];
System.Runtime.InteropServices.Marshal.Copy(s_CachedHGlobalPtr, result, 0, structureSize);
return result;
}
/// <summary>
/// 将数据从对象转换为二进制流。
/// </summary>
/// <typeparam name="T">要转换的对象的类型。</typeparam>
/// <param name="structure">要转换的对象。</param>
/// <param name="result">存储转换结果的二进制流。</param>
public static void StructureToBytes<T>(T structure, byte[] result)
{
StructureToBytes(structure, System.Runtime.InteropServices.Marshal.SizeOf(typeof(T)), result, 0);
}
/// <summary>
/// 将数据从对象转换为二进制流。
/// </summary>
/// <typeparam name="T">要转换的对象的类型。</typeparam>
/// <param name="structure">要转换的对象。</param>
/// <param name="structureSize">要转换的对象的大小。</param>
/// <param name="result">存储转换结果的二进制流。</param>
internal static void StructureToBytes<T>(T structure, int structureSize, byte[] result)
{
StructureToBytes(structure, structureSize, result, 0);
}
/// <summary>
/// 将数据从对象转换为二进制流。
/// </summary>
/// <typeparam name="T">要转换的对象的类型。</typeparam>
/// <param name="structure">要转换的对象。</param>
/// <param name="result">存储转换结果的二进制流。</param>
/// <param name="startIndex">写入存储转换结果的二进制流的起始位置。</param>
public static void StructureToBytes<T>(T structure, byte[] result, int startIndex)
{
StructureToBytes(structure, System.Runtime.InteropServices.Marshal.SizeOf(typeof(T)), result, startIndex);
}
/// <summary>
/// 将数据从对象转换为二进制流。
/// </summary>
/// <typeparam name="T">要转换的对象的类型。</typeparam>
/// <param name="structure">要转换的对象。</param>
/// <param name="structureSize">要转换的对象的大小。</param>
/// <param name="result">存储转换结果的二进制流。</param>
/// <param name="startIndex">写入存储转换结果的二进制流的起始位置。</param>
internal static void StructureToBytes<T>(T structure, int structureSize, byte[] result, int startIndex)
{
if (structureSize < 0)
{
throw new GameFrameworkException("Structure size is invalid.");
}
if (result == null)
{
throw new GameFrameworkException("Result is invalid.");
}
if (startIndex < 0)
{
throw new GameFrameworkException("Start index is invalid.");
}
if (startIndex + structureSize > result.Length)
{
throw new GameFrameworkException("Result length is not enough.");
}
EnsureCachedHGlobalSize(structureSize);
System.Runtime.InteropServices.Marshal.StructureToPtr(structure, s_CachedHGlobalPtr, true);
System.Runtime.InteropServices.Marshal.Copy(s_CachedHGlobalPtr, result, startIndex, structureSize);
}
/// <summary>
/// 将数据从二进制流转换为对象。
/// </summary>
/// <typeparam name="T">要转换的对象的类型。</typeparam>
/// <param name="buffer">要转换的二进制流。</param>
/// <returns>存储转换结果的对象。</returns>
public static T BytesToStructure<T>(byte[] buffer)
{
return BytesToStructure<T>(System.Runtime.InteropServices.Marshal.SizeOf(typeof(T)), buffer, 0);
}
/// <summary>
/// 将数据从二进制流转换为对象。
/// </summary>
/// <typeparam name="T">要转换的对象的类型。</typeparam>
/// <param name="buffer">要转换的二进制流。</param>
/// <param name="startIndex">读取要转换的二进制流的起始位置。</param>
/// <returns>存储转换结果的对象。</returns>
public static T BytesToStructure<T>(byte[] buffer, int startIndex)
{
return BytesToStructure<T>(System.Runtime.InteropServices.Marshal.SizeOf(typeof(T)), buffer, startIndex);
}
/// <summary>
/// 将数据从二进制流转换为对象。
/// </summary>
/// <typeparam name="T">要转换的对象的类型。</typeparam>
/// <param name="structureSize">要转换的对象的大小。</param>
/// <param name="buffer">要转换的二进制流。</param>
/// <returns>存储转换结果的对象。</returns>
internal static T BytesToStructure<T>(int structureSize, byte[] buffer)
{
return BytesToStructure<T>(structureSize, buffer, 0);
}
/// <summary>
/// 将数据从二进制流转换为对象。
/// </summary>
/// <typeparam name="T">要转换的对象的类型。</typeparam>
/// <param name="structureSize">要转换的对象的大小。</param>
/// <param name="buffer">要转换的二进制流。</param>
/// <param name="startIndex">读取要转换的二进制流的起始位置。</param>
/// <returns>存储转换结果的对象。</returns>
internal static T BytesToStructure<T>(int structureSize, byte[] buffer, int startIndex)
{
if (structureSize < 0)
{
throw new GameFrameworkException("Structure size is invalid.");
}
if (buffer == null)
{
throw new GameFrameworkException("Buffer is invalid.");
}
if (startIndex < 0)
{
throw new GameFrameworkException("Start index is invalid.");
}
if (startIndex + structureSize > buffer.Length)
{
throw new GameFrameworkException("Buffer length is not enough.");
}
EnsureCachedHGlobalSize(structureSize);
System.Runtime.InteropServices.Marshal.Copy(buffer, startIndex, s_CachedHGlobalPtr, structureSize);
return (T)System.Runtime.InteropServices.Marshal.PtrToStructure(s_CachedHGlobalPtr, typeof(T));
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e4eaf023a908b6847bc7c1b16e025fcd
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,93 @@
using System.IO;
namespace TEngine
{
public static partial class Utility
{
/// <summary>
/// 路径相关的实用函数。
/// </summary>
public static class Path
{
/// <summary>
/// 获取规范的路径。
/// </summary>
/// <param name="path">要规范的路径。</param>
/// <returns>规范的路径。</returns>
public static string GetRegularPath(string path)
{
if (path == null)
{
return null;
}
return path.Replace('\\', '/');
}
/// <summary>
/// 获取远程格式的路径带有file:// 或 http:// 前缀)。
/// </summary>
/// <param name="path">原始路径。</param>
/// <returns>远程格式路径。</returns>
public static string GetRemotePath(string path)
{
string regularPath = GetRegularPath(path);
if (regularPath == null)
{
return null;
}
return regularPath.Contains("://") ? regularPath : ("file:///" + regularPath).Replace("file:////", "file:///");
}
/// <summary>
/// 移除空文件夹。
/// </summary>
/// <param name="directoryName">要处理的文件夹名称。</param>
/// <returns>是否移除空文件夹成功。</returns>
public static bool RemoveEmptyDirectory(string directoryName)
{
if (string.IsNullOrEmpty(directoryName))
{
throw new GameFrameworkException("Directory name is invalid.");
}
try
{
if (!Directory.Exists(directoryName))
{
return false;
}
// 不使用 SearchOption.AllDirectories以便于在可能产生异常的环境下删除尽可能多的目录
string[] subDirectoryNames = Directory.GetDirectories(directoryName, "*");
int subDirectoryCount = subDirectoryNames.Length;
foreach (string subDirectoryName in subDirectoryNames)
{
if (RemoveEmptyDirectory(subDirectoryName))
{
subDirectoryCount--;
}
}
if (subDirectoryCount > 0)
{
return false;
}
if (Directory.GetFiles(directoryName, "*").Length > 0)
{
return false;
}
Directory.Delete(directoryName);
return true;
}
catch
{
return false;
}
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ffffdb31a0e4d6e49a95d47aa1976e94
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,72 @@
using System;
namespace TEngine
{
public static partial class Utility
{
/// <summary>
/// 随机相关的实用函数。
/// </summary>
public static class Random
{
private static System.Random s_Random = new System.Random((int)DateTime.UtcNow.Ticks);
/// <summary>
/// 设置随机数种子。
/// </summary>
/// <param name="seed">随机数种子。</param>
public static void SetSeed(int seed)
{
s_Random = new System.Random(seed);
}
/// <summary>
/// 返回非负随机数。
/// </summary>
/// <returns>大于等于零且小于 System.Int32.MaxValue 的 32 位带符号整数。</returns>
public static int GetRandom()
{
return s_Random.Next();
}
/// <summary>
/// 返回一个小于所指定最大值的非负随机数。
/// </summary>
/// <param name="maxValue">要生成的随机数的上界随机数不能取该上界值。maxValue 必须大于等于零。</param>
/// <returns>大于等于零且小于 maxValue 的 32 位带符号整数,即:返回值的范围通常包括零但不包括 maxValue。不过如果 maxValue 等于零,则返回 maxValue。</returns>
public static int GetRandom(int maxValue)
{
return s_Random.Next(maxValue);
}
/// <summary>
/// 返回一个指定范围内的随机数。
/// </summary>
/// <param name="minValue">返回的随机数的下界(随机数可取该下界值)。</param>
/// <param name="maxValue">返回的随机数的上界随机数不能取该上界值。maxValue 必须大于等于 minValue。</param>
/// <returns>一个大于等于 minValue 且小于 maxValue 的 32 位带符号整数,即:返回的值范围包括 minValue 但不包括 maxValue。如果 minValue 等于 maxValue则返回 minValue。</returns>
public static int GetRandom(int minValue, int maxValue)
{
return s_Random.Next(minValue, maxValue);
}
/// <summary>
/// 返回一个介于 0.0 和 1.0 之间的随机数。
/// </summary>
/// <returns>大于等于 0.0 并且小于 1.0 的双精度浮点数。</returns>
public static double GetRandomDouble()
{
return s_Random.NextDouble();
}
/// <summary>
/// 用随机数填充指定字节数组的元素。
/// </summary>
/// <param name="buffer">包含随机数的字节数组。</param>
public static void GetRandomBytes(byte[] buffer)
{
s_Random.NextBytes(buffer);
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d141c00a7ebf38141b1661ed1acb48f1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,391 @@
using System;
using System.Collections;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Internal;
using Object = UnityEngine.Object;
namespace TEngine
{
public static partial class Utility
{
/// <summary>
/// Unity相关的实用函数。
/// </summary>
public static partial class Unity
{
private static GameObject _entity;
private static MainBehaviour _behaviour;
#region Coroutine
public static Coroutine StartCoroutine(string methodName)
{
if (string.IsNullOrEmpty(methodName))
{
return null;
}
_MakeEntity();
return _behaviour.StartCoroutine(methodName);
}
public static Coroutine StartCoroutine(IEnumerator routine)
{
if (routine == null)
{
return null;
}
_MakeEntity();
return _behaviour.StartCoroutine(routine);
}
public static Coroutine StartCoroutine(string methodName, [DefaultValue("null")] object value)
{
if (string.IsNullOrEmpty(methodName))
{
return null;
}
_MakeEntity();
return _behaviour.StartCoroutine(methodName, value);
}
public static void StopCoroutine(string methodName)
{
if (string.IsNullOrEmpty(methodName))
{
return;
}
if (_entity != null)
{
_behaviour.StopCoroutine(methodName);
}
}
public static void StopCoroutine(IEnumerator routine)
{
if (routine == null)
{
return;
}
if (_entity != null)
{
_behaviour.StopCoroutine(routine);
}
}
public static void StopCoroutine(Coroutine routine)
{
if (routine == null)
return;
if (_entity != null)
{
_behaviour.StopCoroutine(routine);
routine = null;
}
}
public static void StopAllCoroutines()
{
if (_entity != null)
{
_behaviour.StopAllCoroutines();
}
}
#endregion
#region UnityUpdate/FixedUpdate/LateUpdate
/// <summary>
/// 为给外部提供的 添加帧更新事件。
/// </summary>
/// <param name="fun"></param>
public static void AddUpdateListener(UnityAction fun)
{
_MakeEntity();
_behaviour.AddUpdateListener(fun);
}
/// <summary>
/// 为给外部提供的 添加物理帧更新事件。
/// </summary>
/// <param name="fun"></param>
public static void AddFixedUpdateListener(UnityAction fun)
{
_MakeEntity();
_behaviour.AddFixedUpdateListener(fun);
}
/// <summary>
/// 为给外部提供的 添加Late帧更新事件。
/// </summary>
/// <param name="fun"></param>
public static void AddLateUpdateListener(UnityAction fun)
{
_MakeEntity();
_behaviour.AddLateUpdateListener(fun);
}
/// <summary>
/// 移除帧更新事件。
/// </summary>
/// <param name="fun"></param>
public static void RemoveUpdateListener(UnityAction fun)
{
_MakeEntity();
_behaviour.RemoveUpdateListener(fun);
}
/// <summary>
/// 移除物理帧更新事件。
/// </summary>
/// <param name="fun"></param>
public static void RemoveFixedUpdateListener(UnityAction fun)
{
_MakeEntity();
_behaviour.RemoveFixedUpdateListener(fun);
}
/// <summary>
/// 移除Late帧更新事件。
/// </summary>
/// <param name="fun"></param>
public static void RemoveLateUpdateListener(UnityAction fun)
{
_MakeEntity();
_behaviour.RemoveLateUpdateListener(fun);
}
#endregion
#region Unity Events
/// <summary>
/// 为给外部提供的Destroy注册事件。
/// </summary>
/// <param name="fun"></param>
public static void AddDestroyListener(UnityAction fun)
{
_MakeEntity();
_behaviour.AddDestroyListener(fun);
}
/// <summary>
/// 为给外部提供的Destroy反注册事件。
/// </summary>
/// <param name="fun"></param>
public static void RemoveDestroyListener(UnityAction fun)
{
_MakeEntity();
_behaviour.RemoveDestroyListener(fun);
}
/// <summary>
/// 为给外部提供的OnDrawGizmos注册事件。
/// </summary>
/// <param name="fun"></param>
public static void AddOnDrawGizmosListener(UnityAction fun)
{
_MakeEntity();
_behaviour.RemoveDestroyListener(fun);
}
/// <summary>
/// 为给外部提供的OnDrawGizmos反注册事件。
/// </summary>
/// <param name="fun"></param>
public static void RemoveOnDrawGizmosListener(UnityAction fun)
{
_MakeEntity();
_behaviour.RemoveDestroyListener(fun);
}
/// <summary>
/// 为给外部提供的OnApplicationPause注册事件。
/// </summary>
/// <param name="fun"></param>
public static void AddOnApplicationPauseListener(UnityAction<bool> fun)
{
_MakeEntity();
_behaviour.AddOnApplicationPauseListener(fun);
}
/// <summary>
/// 为给外部提供的OnApplicationPause反注册事件。
/// </summary>
/// <param name="fun"></param>
public static void RemoveOnApplicationPauseListener(UnityAction<bool> fun)
{
_MakeEntity();
_behaviour.AddOnApplicationPauseListener(fun);
}
#endregion
/// <summary>
/// 释放Behaviour生命周期。
/// </summary>
public static void Release()
{
_MakeEntity();
_behaviour.Release();
}
private static void _MakeEntity()
{
if (_entity != null)
{
return;
}
_entity = new GameObject("__MonoUtility__")
{
hideFlags = HideFlags.HideAndDontSave
};
_entity.SetActive(true);
#if UNITY_EDITOR
if (Application.isPlaying)
#endif
{
Object.DontDestroyOnLoad(_entity);
}
UnityEngine.Assertions.Assert.IsFalse(_behaviour);
_behaviour = _entity.AddComponent<MainBehaviour>();
}
private class MainBehaviour : MonoBehaviour
{
private event UnityAction updateEvent;
private event UnityAction fixedUpdateEvent;
private event UnityAction lateUpdateEvent;
private event UnityAction destroyEvent;
private event UnityAction onDrawGizmosEvent;
private event UnityAction<bool> onApplicationPause;
void Update()
{
if (updateEvent != null)
{
updateEvent();
}
}
void FixedUpdate()
{
if (fixedUpdateEvent != null)
{
fixedUpdateEvent();
}
}
void LateUpdate()
{
if (lateUpdateEvent != null)
{
lateUpdateEvent();
}
}
private void OnDestroy()
{
if (destroyEvent != null)
{
destroyEvent();
}
}
private void OnDrawGizmos()
{
if (onDrawGizmosEvent != null)
{
onDrawGizmosEvent();
}
}
private void OnApplicationPause(bool pauseStatus)
{
if (onApplicationPause != null)
{
onApplicationPause(pauseStatus);
}
}
public void AddLateUpdateListener(UnityAction fun)
{
lateUpdateEvent += fun;
}
public void RemoveLateUpdateListener(UnityAction fun)
{
lateUpdateEvent -= fun;
}
public void AddFixedUpdateListener(UnityAction fun)
{
fixedUpdateEvent += fun;
}
public void RemoveFixedUpdateListener(UnityAction fun)
{
fixedUpdateEvent -= fun;
}
public void AddUpdateListener(UnityAction fun)
{
updateEvent += fun;
}
public void RemoveUpdateListener(UnityAction fun)
{
updateEvent -= fun;
}
public void AddDestroyListener(UnityAction fun)
{
destroyEvent += fun;
}
public void RemoveDestroyListener(UnityAction fun)
{
destroyEvent -= fun;
}
public void AddOnDrawGizmosListener(UnityAction fun)
{
onDrawGizmosEvent += fun;
}
public void RemoveOnDrawGizmosListener(UnityAction fun)
{
onDrawGizmosEvent -= fun;
}
public void AddOnApplicationPauseListener(UnityAction<bool> fun)
{
onApplicationPause += fun;
}
public void RemoveOnApplicationPauseListener(UnityAction<bool> fun)
{
onApplicationPause -= fun;
}
public void Release()
{
updateEvent = null;
fixedUpdateEvent = null;
lateUpdateEvent = null;
onDrawGizmosEvent = null;
destroyEvent = null;
onApplicationPause = null;
}
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1b5e063f21f5cba4d85471c343c33271
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,87 @@
namespace TEngine
{
public static partial class Utility
{
public static partial class Verifier
{
/// <summary>
/// CRC32 算法。
/// </summary>
private sealed class Crc32
{
private const int TableLength = 256;
private const uint DefaultPolynomial = 0xedb88320;
private const uint DefaultSeed = 0xffffffff;
private readonly uint m_Seed;
private readonly uint[] m_Table;
private uint m_Hash;
public Crc32()
: this(DefaultPolynomial, DefaultSeed)
{
}
public Crc32(uint polynomial, uint seed)
{
m_Seed = seed;
m_Table = InitializeTable(polynomial);
m_Hash = seed;
}
public void Initialize()
{
m_Hash = m_Seed;
}
public void HashCore(byte[] bytes, int offset, int length)
{
m_Hash = CalculateHash(m_Table, m_Hash, bytes, offset, length);
}
public uint HashFinal()
{
return ~m_Hash;
}
private static uint CalculateHash(uint[] table, uint value, byte[] bytes, int offset, int length)
{
int last = offset + length;
for (int i = offset; i < last; i++)
{
unchecked
{
value = (value >> 8) ^ table[bytes[i] ^ value & 0xff];
}
}
return value;
}
private static uint[] InitializeTable(uint polynomial)
{
uint[] table = new uint[TableLength];
for (int i = 0; i < TableLength; i++)
{
uint entry = (uint)i;
for (int j = 0; j < 8; j++)
{
if ((entry & 1) == 1)
{
entry = (entry >> 1) ^ polynomial;
}
else
{
entry >>= 1;
}
}
table[i] = entry;
}
return table;
}
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9a7d0ce566dde9749b214b5ae065ac3d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,188 @@
using System;
using System.IO;
namespace TEngine
{
public static partial class Utility
{
/// <summary>
/// 校验相关的实用函数。
/// </summary>
public static partial class Verifier
{
private const int CachedBytesLength = 0x1000;
private static readonly byte[] s_CachedBytes = new byte[CachedBytesLength];
private static readonly Crc32 s_Algorithm = new Crc32();
/// <summary>
/// 计算二进制流的 CRC32。
/// </summary>
/// <param name="bytes">指定的二进制流。</param>
/// <returns>计算后的 CRC32。</returns>
public static int GetCrc32(byte[] bytes)
{
if (bytes == null)
{
throw new GameFrameworkException("Bytes is invalid.");
}
return GetCrc32(bytes, 0, bytes.Length);
}
/// <summary>
/// 计算二进制流的 CRC32。
/// </summary>
/// <param name="bytes">指定的二进制流。</param>
/// <param name="offset">二进制流的偏移。</param>
/// <param name="length">二进制流的长度。</param>
/// <returns>计算后的 CRC32。</returns>
public static int GetCrc32(byte[] bytes, int offset, int length)
{
if (bytes == null)
{
throw new GameFrameworkException("Bytes is invalid.");
}
if (offset < 0 || length < 0 || offset + length > bytes.Length)
{
throw new GameFrameworkException("Offset or length is invalid.");
}
s_Algorithm.HashCore(bytes, offset, length);
int result = (int)s_Algorithm.HashFinal();
s_Algorithm.Initialize();
return result;
}
/// <summary>
/// 计算二进制流的 CRC32。
/// </summary>
/// <param name="stream">指定的二进制流。</param>
/// <returns>计算后的 CRC32。</returns>
public static int GetCrc32(Stream stream)
{
if (stream == null)
{
throw new GameFrameworkException("Stream is invalid.");
}
while (true)
{
int bytesRead = stream.Read(s_CachedBytes, 0, CachedBytesLength);
if (bytesRead > 0)
{
s_Algorithm.HashCore(s_CachedBytes, 0, bytesRead);
}
else
{
break;
}
}
int result = (int)s_Algorithm.HashFinal();
s_Algorithm.Initialize();
Array.Clear(s_CachedBytes, 0, CachedBytesLength);
return result;
}
/// <summary>
/// 获取 CRC32 数值的二进制数组。
/// </summary>
/// <param name="crc32">CRC32 数值。</param>
/// <returns>CRC32 数值的二进制数组。</returns>
public static byte[] GetCrc32Bytes(int crc32)
{
return new byte[] { (byte)((crc32 >> 24) & 0xff), (byte)((crc32 >> 16) & 0xff), (byte)((crc32 >> 8) & 0xff), (byte)(crc32 & 0xff) };
}
/// <summary>
/// 获取 CRC32 数值的二进制数组。
/// </summary>
/// <param name="crc32">CRC32 数值。</param>
/// <param name="bytes">要存放结果的数组。</param>
public static void GetCrc32Bytes(int crc32, byte[] bytes)
{
GetCrc32Bytes(crc32, bytes, 0);
}
/// <summary>
/// 获取 CRC32 数值的二进制数组。
/// </summary>
/// <param name="crc32">CRC32 数值。</param>
/// <param name="bytes">要存放结果的数组。</param>
/// <param name="offset">CRC32 数值的二进制数组在结果数组内的起始位置。</param>
public static void GetCrc32Bytes(int crc32, byte[] bytes, int offset)
{
if (bytes == null)
{
throw new GameFrameworkException("Result is invalid.");
}
if (offset < 0 || offset + 4 > bytes.Length)
{
throw new GameFrameworkException("Offset or length is invalid.");
}
bytes[offset] = (byte)((crc32 >> 24) & 0xff);
bytes[offset + 1] = (byte)((crc32 >> 16) & 0xff);
bytes[offset + 2] = (byte)((crc32 >> 8) & 0xff);
bytes[offset + 3] = (byte)(crc32 & 0xff);
}
internal static int GetCrc32(Stream stream, byte[] code, int length)
{
if (stream == null)
{
throw new GameFrameworkException("Stream is invalid.");
}
if (code == null)
{
throw new GameFrameworkException("Code is invalid.");
}
int codeLength = code.Length;
if (codeLength <= 0)
{
throw new GameFrameworkException("Code length is invalid.");
}
int bytesLength = (int)stream.Length;
if (length < 0 || length > bytesLength)
{
length = bytesLength;
}
int codeIndex = 0;
while (true)
{
int bytesRead = stream.Read(s_CachedBytes, 0, CachedBytesLength);
if (bytesRead > 0)
{
if (length > 0)
{
for (int i = 0; i < bytesRead && i < length; i++)
{
s_CachedBytes[i] ^= code[codeIndex++];
codeIndex %= codeLength;
}
length -= bytesRead;
}
s_Algorithm.HashCore(s_CachedBytes, 0, bytesRead);
}
else
{
break;
}
}
int result = (int)s_Algorithm.HashFinal();
s_Algorithm.Initialize();
Array.Clear(s_CachedBytes, 0, CachedBytesLength);
return result;
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 968c23f2e5a22ec4f884c9932c8fa90b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: