Compare commits

...

29 Commits

Author SHA1 Message Date
fd68071416 修复一些遗漏 2025-12-16 17:54:29 +08:00
a530eba460 优化参数传递 2025-12-15 17:45:36 +08:00
32f0038e34 新增类型友好的名称打印 2025-12-15 11:36:06 +08:00
c12d4a3754 开始增加二进制序列化器 2025-12-12 17:45:25 +08:00
a3483f23d8 更新迭代器函数 2025-12-11 18:02:49 +08:00
3db8bde1c2 新增Avoid拆分协程 2025-12-09 18:00:47 +08:00
223df3fb91 新增性能容器 2025-12-05 16:25:40 +08:00
8e419a3257 退化File中读取二进制的功能用于修复bug 2025-12-03 14:35:12 +08:00
48965decbb 修复ActionStepCoroutineWrapper中的错误调用顺序 2025-12-02 16:54:58 +08:00
172b2af3ea 尝试一些优化 2025-12-02 14:24:00 +08:00
5cc1d2aabc 修复UnityEditor.Build的引用错误 2025-11-30 02:26:15 +08:00
0b562b7f65 新增宏的6000支持 2025-11-29 00:42:41 +08:00
ccb51f26c3 去除确认无效的内容 2025-11-28 17:40:42 +08:00
b6439492df 6000兼容 2025-11-28 10:23:52 +08:00
0b563f393b 修复File中合成路径的错误 2025-11-25 17:03:13 +08:00
fced17765c 修复一些内容 2025-11-25 11:59:44 +08:00
1afdb95231 准备更新BP 2025-11-20 17:29:16 +08:00
18442ae51c EP 实验性框架 2025-11-20 16:17:10 +08:00
bf81df9581 新增实验框架 2025-11-14 17:14:08 +08:00
6d72129bae 新增实验框架 2025-11-14 17:13:10 +08:00
1a28eb62a8 从ellan/GameFramework中合并新的工具 2025-11-13 16:39:25 +08:00
b6d2f38e72 修复ToolFile中保存的错误 2025-11-12 09:54:47 +08:00
64e0bf2282 修复异步中没有yield return的错误 2025-10-18 02:47:55 +08:00
41d502b239 异步更新 2025-10-13 19:47:39 +08:00
6271171ab4 Save 2025-10-10 01:00:53 +08:00
7906203f84 开放ES3JsonReader构造函数供Interaction直接使用 2025-10-09 20:00:42 +08:00
dfa00340f5 EP Interaction 2025-10-09 14:15:28 +08:00
9b9264a6cc 修复了ConventValue中Parse的错误 2025-10-08 21:43:14 +08:00
3c962267ab 新增PropertyListItem强制刷新 2025-10-06 16:08:27 +08:00
57 changed files with 5524 additions and 250 deletions

View File

@@ -108,15 +108,17 @@ MonoBehaviour:
m_lineSpacingMax: 0
m_paragraphSpacing: 0
m_charWidthMaxAdj: 0
m_enableWordWrapping: 1
m_TextWrappingMode: 1
m_wordWrappingRatios: 0.4
m_overflowMode: 0
m_linkedTextComponent: {fileID: 0}
parentLinkedComponent: {fileID: 0}
m_enableKerning: 1
m_ActiveFontFeatures: 00000000
m_enableExtraPadding: 0
checkPaddingRequired: 0
m_isRichText: 1
m_EmojiFallbackSupport: 1
m_parseCtrlCharacters: 1
m_isOrthographic: 1
m_isCullingEnabled: 0
@@ -376,15 +378,17 @@ MonoBehaviour:
m_lineSpacingMax: 0
m_paragraphSpacing: 0
m_charWidthMaxAdj: 0
m_enableWordWrapping: 1
m_TextWrappingMode: 1
m_wordWrappingRatios: 0.4
m_overflowMode: 0
m_linkedTextComponent: {fileID: 0}
parentLinkedComponent: {fileID: 0}
m_enableKerning: 1
m_ActiveFontFeatures: 00000000
m_enableExtraPadding: 0
checkPaddingRequired: 0
m_isRichText: 1
m_EmojiFallbackSupport: 1
m_parseCtrlCharacters: 1
m_isOrthographic: 1
m_isCullingEnabled: 0

View File

@@ -108,15 +108,17 @@ MonoBehaviour:
m_lineSpacingMax: 0
m_paragraphSpacing: 0
m_charWidthMaxAdj: 0
m_enableWordWrapping: 1
m_TextWrappingMode: 1
m_wordWrappingRatios: 0.4
m_overflowMode: 0
m_linkedTextComponent: {fileID: 0}
parentLinkedComponent: {fileID: 0}
m_enableKerning: 1
m_ActiveFontFeatures: 00000000
m_enableExtraPadding: 0
checkPaddingRequired: 0
m_isRichText: 1
m_EmojiFallbackSupport: 1
m_parseCtrlCharacters: 1
m_isOrthographic: 1
m_isCullingEnabled: 0
@@ -523,15 +525,17 @@ MonoBehaviour:
m_lineSpacingMax: 0
m_paragraphSpacing: 0
m_charWidthMaxAdj: 0
m_enableWordWrapping: 1
m_TextWrappingMode: 1
m_wordWrappingRatios: 0.4
m_overflowMode: 0
m_linkedTextComponent: {fileID: 0}
parentLinkedComponent: {fileID: 0}
m_enableKerning: 1
m_ActiveFontFeatures: 00000000
m_enableExtraPadding: 0
checkPaddingRequired: 0
m_isRichText: 1
m_EmojiFallbackSupport: 1
m_parseCtrlCharacters: 1
m_isOrthographic: 1
m_isCullingEnabled: 0
@@ -941,6 +945,10 @@ PrefabInstance:
propertyPath: m_sharedMaterial
value:
objectReference: {fileID: -6641050763205051922, guid: 4abb91c83e9e6214992ef15922294c0c, type: 2}
- target: {fileID: 6279050909353911363, guid: 4e6810693c07dfb4399ed0c7c7a3ce39, type: 3}
propertyPath: m_TextWrappingMode
value: 0
objectReference: {fileID: 0}
- target: {fileID: 6279050909353911363, guid: 4e6810693c07dfb4399ed0c7c7a3ce39, type: 3}
propertyPath: m_enableWordWrapping
value: 0

View File

@@ -634,6 +634,10 @@ PrefabInstance:
propertyPath: m_RaycastTarget
value: 0
objectReference: {fileID: 0}
- target: {fileID: 6279050909353911363, guid: 4e6810693c07dfb4399ed0c7c7a3ce39, type: 3}
propertyPath: m_TextWrappingMode
value: 0
objectReference: {fileID: 0}
- target: {fileID: 6279050909353911363, guid: 4e6810693c07dfb4399ed0c7c7a3ce39, type: 3}
propertyPath: m_enableWordWrapping
value: 0

View File

@@ -3295,6 +3295,10 @@ PrefabInstance:
propertyPath: m_RaycastTarget
value: 0
objectReference: {fileID: 0}
- target: {fileID: 6279050909353911363, guid: 4e6810693c07dfb4399ed0c7c7a3ce39, type: 3}
propertyPath: m_TextWrappingMode
value: 0
objectReference: {fileID: 0}
- target: {fileID: 6279050909353911363, guid: 4e6810693c07dfb4399ed0c7c7a3ce39, type: 3}
propertyPath: m_enableWordWrapping
value: 0

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: aedf6f9892e6a9545a8e4bfce4d03063
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,139 @@
using Convention.Collections;
using Convention.Collections.Generic;
using Convention.Experimental.PublicType;
using Convention.ReferenceManagement;
using System;
using System.Collections.Generic;
namespace Convention.Experimental
{
public static class Architecture
{
private static readonly LinkedCacheList<object> s_GameFrameworkModules = new();
/// <summary>
/// <20><><EFBFBD><EFBFBD>ʵ<EFBFBD><CAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
/// <param name="instanceType">Ҫ<><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></param>
/// <returns>Ŀ<><C4BF>ʵ<EFBFBD><CAB5></returns>
private static object Create(Type instanceType, int stackLayer = 0)
{
if (stackLayer >= 100)
{
throw new GameException($"Create instance '{instanceType.FullName}' failed, recursion too deep, there may be a circular dependency.");
}
object instance = Activator.CreateInstance(instanceType);
if (instance == null)
{
throw new GameException($"Can not create instance '{instanceType.FullName}'");
}
if (instance is GameModule module)
{
// <20>ݹ鴴<DDB9><E9B4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ģ<EFBFBD><C4A3>
foreach (var dependenceType in module.Dependences())
_ = Get(dependenceType, stackLayer + 1);
var current = s_GameFrameworkModules.First;
while (current != null)
{
if (current.Value is GameModule nextModule && module.Priority > nextModule.Priority)
{
break;
}
current = current.Next;
}
if (current != null)
{
s_GameFrameworkModules.AddBefore(current, module);
}
else
{
s_GameFrameworkModules.AddLast(module);
}
}
return instance;
}
/// <summary>
/// <20><>ȡʵ<C8A1><CAB5>
/// </summary>
/// <param name="instanceType">Ҫ<><D2AA>ȡ<EFBFBD><C8A1>ʵ<EFBFBD><CAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD></param>
/// <returns>ʵ<><CAB5></returns>
/// <remarks><3E><><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA>ȡ<EFBFBD><C8A1>ʵ<EFBFBD><CAB5><EFBFBD><EFBFBD><EFBFBD>Ͳ<EFBFBD><CDB2><EFBFBD><EFBFBD>ڣ<EFBFBD><DAA3><EFBFBD><EFBFBD>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>͵<EFBFBD>ʵ<EFBFBD><CAB5><EFBFBD><EFBFBD></remarks>
public static object Get(Type instanceType, int stackLayer = 0)
{
foreach (object obj in s_GameFrameworkModules)
{
if (obj.GetType() == instanceType)
{
return obj;
}
}
return Create(instanceType, stackLayer + 1);
}
/// <summary>
/// <20>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><CAB5>
/// </summary>
/// <param name="type">Ҫ<><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><CAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD></param>
/// <returns>ʵ<><CAB5><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD></returns>
public static bool Contains(Type type)
{
foreach (object obj in s_GameFrameworkModules)
{
if (obj.GetType() == type)
{
return true;
}
}
return false;
}
/// <summary>
/// <20><>ȡ<EFBFBD><C8A1>Ϸ<EFBFBD><CFB7><EFBFBD><EFBFBD>ģ<EFBFBD>
/// </summary>
/// <typeparam name="T">Ҫ<><D2AA>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>Ϸ<EFBFBD><CFB7><EFBFBD><EFBFBD>ģ<EFBFBD><C4A3><EFBFBD><EFBFBD><EFBFBD>͡<EFBFBD></typeparam>
/// <returns>Ҫ<><D2AA>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>Ϸ<EFBFBD><CFB7><EFBFBD><EFBFBD>ģ<EFBFBD>顣</returns>
/// <remarks><3E><><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>Ϸ<EFBFBD><CFB7><EFBFBD><EFBFBD>ģ<EFBFBD><EFBFBD><E9B2BB><EFBFBD>ڣ<EFBFBD><DAA3><EFBFBD><EFBFBD>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϸ<EFBFBD><CFB7><EFBFBD><EFBFBD>ģ<EFBFBD>顣</remarks>
public static T GetModule<T>() where T : GameModule
{
return (T)Get(typeof(T));
}
/// <summary>
/// <20>رղ<D8B1><D5B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϸ<EFBFBD><CFB7><EFBFBD><EFBFBD>ģ<EFBFBD>
/// </summary>
public static void Shutdown()
{
for (var current = s_GameFrameworkModules.Last; current != null; current = current.Previous)
{
if (current.Value is GameModule module)
module.Shutdown();
}
s_GameFrameworkModules.Clear();
ReferencePool.ClearAll();
Utility.Marshal.FreeCachedHGlobal();
}
/// <summary>
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϸ<EFBFBD><CFB7><EFBFBD><EFBFBD>ģ<EFBFBD><C4A3><EFBFBD><EFBFBD>ѯ<EFBFBD><D1AF>
/// </summary>
/// <param name="elapseSeconds"><3E>߼<EFBFBD><DFBC><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><E4A3AC><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA>λ<EFBFBD><CEBB></param>
/// <param name="realElapseSeconds"><3E><>ʵ<EFBFBD><CAB5><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><E4A3AC><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA>λ<EFBFBD><CEBB></param>
public static void Update(float elapseSeconds, float realElapseSeconds)
{
foreach (object obj in s_GameFrameworkModules)
{
if (obj is GameModule module)
module.Update(elapseSeconds, realElapseSeconds);
}
}
}
}

View File

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

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 591a2c63cd01a22408284eeaa811e930
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,111 @@
using System;
using System.Collections.Generic;
namespace Convention.Experimental.Modules
{
public partial class ActionManager : PublicType.GameModule
{
public interface IActor
{
void Execute();
void Undo();
string Description { get; }
}
private readonly object m_lock = new();
private readonly LinkedList<IActor> m_history = new();
private readonly Stack<IActor> m_redoStack = new();
private int m_historyLimit = 100;
public int HistoryLimit
{
get => m_historyLimit;
set
{
m_historyLimit = value;
while (m_history.Count > m_historyLimit)
{
m_history.RemoveFirst();
}
}
}
public bool CanUndo => m_history.Count > 0;
public int UndoCount => m_history.Count;
public List<string> GetHistoryDescription()
{
lock (m_lock)
{
var descriptions = new List<string>();
foreach (var actor in m_history)
{
descriptions.Add(actor.Description);
}
return descriptions;
}
}
public bool CanRedo => m_redoStack.Count > 0;
public int RedoCount => m_redoStack.Count;
public List<string> GetRedoDescription()
{
lock (m_lock)
{
var descriptions = new List<string>();
foreach (var actor in m_redoStack)
{
descriptions.Add(actor.Description);
}
return descriptions;
}
}
public void Execute(IActor actor)
{
lock (m_lock)
{
actor.Execute();
m_history.AddLast(actor);
m_redoStack.Clear();
if (m_history.Count > m_historyLimit)
{
m_history.RemoveFirst();
}
}
}
public bool Undo()
{
lock (m_lock)
{
if (CanUndo)
{
var actor = m_history.Last.Value;
m_history.RemoveLast();
actor.Undo();
m_redoStack.Push(actor);
return true;
}
return false;
}
}
public bool Redo()
{
lock (m_lock)
{
if (CanRedo)
{
var actor = m_redoStack.Pop();
actor.Execute();
m_history.AddLast(actor);
return true;
}
return false;
}
}
}
}

View File

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

View File

@@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
namespace Convention.Experimental.Modules
{
public class ConfigManager : PublicType.GameModule
{
public readonly ProjectConfig Config = new();
public bool IsSavePropertiesWhenShutdown = false;
internal override void Shutdown()
{
if (IsSavePropertiesWhenShutdown)
Config.SaveProperties();
}
}
}

View File

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

View File

@@ -0,0 +1,339 @@
using Convention.Experimental.PublicType;
using System;
using System.Linq;
using System.Collections.Generic;
using UnityEngine;
namespace Convention.Experimental.Modules
{
public class GameObjectPoolManager : GameModule
{
/// <summary>
/// <para><3E>̳иýӿڵ<D3BF>Component<6E><74><EFBFBD>ڻ<EFBFBD><DABB>յ<EFBFBD><D5B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><see cref="Release"/></para>
/// <para><b><see cref="Release"/><3E>н<EFBFBD>ֹ<EFBFBD><D6B9><EFBFBD><EFBFBD><see cref="Unspawn(GameObject)"/></b></para>
/// </summary>
public interface IPoolPawn
{
void Release();
}
private readonly Dictionary<GameObject, Stack<GameObject>> GameObjectPools = new();
private readonly Dictionary<GameObject, GameObject> LeaveGameObjectPoolObjects = new();
private bool GameObjectPoolStatus = true;
/// <summary>
/// <20><><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϸ<EFBFBD><CFB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
/// <param name="prefab"><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԥ<EFBFBD><D4A4><EFBFBD><EFBFBD></param>
/// <returns></returns>
public bool Contains(GameObject prefab)
{
return GameObjectPools.ContainsKey(prefab);
}
/// <summary>
/// ȷ<><C8B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƕ<EFBFBD>׵<EFBFBD><D7B5><EFBFBD>
/// </summary>
/// <exception cref="GameException"></exception>
private void EnsureSafeStatus()
{
if (GameObjectPoolStatus == false)
{
throw new GameException("GameObjectPool is busy now.");
}
}
/// <summary>
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϸ<EFBFBD><CFB7><EFBFBD><EFBFBD>
/// </summary>
/// <param name="prefab"></param>
/// <returns></returns>
public GameObject Spawn(GameObject prefab)
{
EnsureSafeStatus();
lock (GameObjectPools)
{
if (!GameObjectPools.ContainsKey(prefab))
{
GameObjectPools[prefab] = new();
}
var pool = GameObjectPools[prefab];
GameObject instance;
if (pool.Count > 0)
{
instance = pool.Pop();
instance.SetActive(true);
instance.transform.SetParent(null);
}
else
{
instance = GameObject.Instantiate(prefab);
}
lock (LeaveGameObjectPoolObjects)
{
LeaveGameObjectPoolObjects[instance] = prefab;
}
return instance;
}
}
/// <summary>
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϸ<EFBFBD><CFB7><EFBFBD><EFBFBD>
/// </summary>
/// <param name="instance"></param>
/// <exception cref="PublicType.GameException"></exception>
public void Unspawn(GameObject instance)
{
EnsureSafeStatus();
lock (LeaveGameObjectPoolObjects)
{
if (LeaveGameObjectPoolObjects.TryGetValue(instance, out var prefab))
{
var releaser = instance.GetComponents<IPoolPawn>();
GameObjectPoolStatus = false;
foreach (var r in releaser)
{
r.Release();
}
GameObjectPoolStatus = true;
instance.SetActive(false);
instance.transform.SetParent(ConventionUtility.Singleton.transform);
lock (GameObjectPools)
{
GameObjectPools[prefab].Push(instance);
LeaveGameObjectPoolObjects.Remove(instance);
}
}
else
{
Debug.LogError("This object does not belong to any pool.", instance);
throw new PublicType.GameException("This object does not belong to any pool.");
}
}
}
public void Clear(GameObject prefab)
{
EnsureSafeStatus();
lock (GameObjectPools)
{
lock (LeaveGameObjectPoolObjects)
{
// <20><><EFBFBD>ٳ<EFBFBD><D9B3>ж<EFBFBD><D0B6><EFBFBD>
if (GameObjectPools.TryGetValue(prefab, out var pool))
{
while (pool.Count > 0)
{
var instance = pool.Pop();
GameObject.Destroy(instance);
}
}
else
{
throw new PublicType.GameException("This pool does not exist.");
}
// <20><><EFBFBD><EFBFBD>δ<EFBFBD><CEB4><EFBFBD>ն<EFBFBD><D5B6><EFBFBD>
var unbackInstances = from item in LeaveGameObjectPoolObjects
where item.Value == prefab
select item.Key;
foreach (var instance in unbackInstances)
{
LeaveGameObjectPoolObjects.Remove(instance);
}
foreach (var instance in unbackInstances)
{
GameObject.Destroy(instance);
}
}
}
}
}
public class ObjectPoolManager
{
/// <summary>
/// <para><3E>̳иýӿڵ<D3BF>Component<6E><74><EFBFBD>ڻ<EFBFBD><DABB>յ<EFBFBD><D5B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><see cref="Release"/></para>
/// <para><b><see cref="Release"/><3E>н<EFBFBD>ֹ<EFBFBD><D6B9><EFBFBD><EFBFBD><see cref="Reclaim(object)"/></b></para>
/// </summary>
public interface IPoolPawn
{
void Release();
}
private readonly Dictionary<Type, object> ObjectPools = new();
private readonly Dictionary<object, Type> LeaveObjectPoolObjects = new();
private bool GameObjectPoolStatus = true;
private void EnsureSafeStatus()
{
if (GameObjectPoolStatus == false)
{
throw new GameException("ObjectPool is busy now.");
}
}
public bool Contains(Type type)
{
return ObjectPools.ContainsKey(type);
}
public bool Contains<T>() where T : class, new()
{
return ObjectPools.ContainsKey(typeof(T));
}
/// <summary>
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>д<EFBFBD><D0B4><EFBFBD><EFBFBD>Ķ<EFBFBD><C4B6>󵽶<EFBFBD><F3B5BDB6><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
/// <param name="type"><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></param>
/// <param name="value">ʵ<><CAB5></param>
/// <returns></returns>
/// <exception cref="GameException"></exception>
public object Insert(Type type, object value)
{
if(LeaveObjectPoolObjects.ContainsKey(value))
{
throw new PublicType.GameException("This object is already registered in pool");
}
if (!ObjectPools.ContainsKey(type))
{
ObjectPools[type] = Utility.CreateStack(type);
}
var pool = ObjectPools[type];
var methodInfo = pool.GetType().GetMethod("Push");
methodInfo.Invoke(pool, new object[] { value });
return value;
}
/// <summary>
/// <20><><EFBFBD>д<EFBFBD><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>󲢲<EFBFBD><F3B2A2B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
/// <typeparam name="T"><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></typeparam>
/// <param name="value">ʵ<><CAB5></param>
/// <returns></returns>
/// <exception cref="PublicType.GameException"></exception>
public T Insert<T>(T value) where T : class
{
if(LeaveObjectPoolObjects.ContainsKey(value))
{
throw new PublicType.GameException("This object is already registered in pool");
}
var type = typeof(T);
if (!ObjectPools.ContainsKey(type))
{
ObjectPools[type] = new Stack<T>();
}
var pool = (Stack<T>)ObjectPools[type];
pool.Push(value);
return value;
}
/// <summary>
/// <20><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD>󲢷<EFBFBD><F3B2A2B7><EFBFBD>ʵ<EFBFBD><CAB5>
/// </summary>
/// <param name="type"><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></param>
/// <returns></returns>
public object Summon(Type type)
{
if (!ObjectPools.ContainsKey(type))
{
ObjectPools[type] = Utility.CreateStack(type);
}
var pool = ObjectPools[type];
var methodInfo = pool.GetType().GetMethod("Pop");
object instance;
var countProperty = pool.GetType().GetProperty("Count");
var count = (int)countProperty.GetValue(pool);
if (count > 0)
{
instance = methodInfo.Invoke(pool, null);
}
else
{
instance = Activator.CreateInstance(type);
}
LeaveObjectPoolObjects[instance] = type;
return instance;
}
/// <summary>
/// <20><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD>󲢷<EFBFBD><F3B2A2B7><EFBFBD>ʵ<EFBFBD><CAB5>
/// </summary>
/// <typeparam name="T"><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></typeparam>
/// <returns></returns>
public T Summon<T>() where T : class, new()
{
var type = typeof(T);
if (!ObjectPools.ContainsKey(type))
{
ObjectPools[type] = new Stack<T>();
}
var pool = (Stack<T>)ObjectPools[type];
T instance;
if (pool.Count > 0)
{
instance = pool.Pop();
}
else
{
instance = new T();
}
LeaveObjectPoolObjects[instance] = type;
return instance;
}
/// <summary>
/// <20><><EFBFBD>ն<EFBFBD><D5B6><EFBFBD>
/// </summary>
/// <param name="instance">ʵ<><CAB5></param>
/// <exception cref="PublicType.GameException"></exception>
public void Reclaim(object instance)
{
if (LeaveObjectPoolObjects.TryGetValue(instance, out var objType))
{
var pool = ObjectPools[objType];
var methodInfo = pool.GetType().GetMethod("Push");
if(instance is IPoolPawn pawn)
{
pawn.Release();
}
methodInfo.Invoke(pool, new object[] { instance });
LeaveObjectPoolObjects.Remove(instance);
}
else
{
throw new GameException("This object does not belong to any pool.");
}
}
public void Clear(Type type)
{
if (ObjectPools.TryGetValue(type, out var pool))
{
var clearMethod = pool.GetType().GetMethod("Clear");
clearMethod.Invoke(pool, null);
}
else
{
throw new PublicType.GameException("This pool does not exist.");
}
}
public void Clear<T>() where T : class, new()
{
var type = typeof(T);
if (ObjectPools.TryGetValue(type, out var pool))
{
var clearMethod = pool.GetType().GetMethod("Clear");
clearMethod.Invoke(pool, null);
}
else
{
throw new PublicType.GameException("This pool does not exist.");
}
}
}
}

View File

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

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 997615a04b8d2844aa27b8d212998bd6
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,52 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.Serialization;
using UnityEngine;
namespace Convention.Experimental.PublicType
{
/// <summary>
/// <20><>Ϸ<EFBFBD><CFB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
[Serializable]
public class GameException : Exception
{
/// <summary>
/// <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD>Ϸ<EFBFBD><CFB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><ECB3A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><CAB5><EFBFBD><EFBFBD>
/// </summary>
public GameException()
: base()
{
}
/// <summary>
/// ʹ<><CAB9>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD>Ϸ<EFBFBD><CFB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><ECB3A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><CAB5><EFBFBD><EFBFBD>
/// </summary>
/// <param name="message"><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2></param>
public GameException(string message)
: base(message)
{
}
/// <summary>
/// ʹ<><CAB9>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD>Ͷ<EFBFBD><CDB6><EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD>쳣ԭ<ECB3A3><D4AD><EFBFBD><EFBFBD><EFBFBD>ڲ<EFBFBD><DAB2><EFBFBD><ECB3A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD>Ϸ<EFBFBD><CFB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><ECB3A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><CAB5><EFBFBD><EFBFBD>
/// </summary>
/// <param name="message"><3E><><EFBFBD><EFBFBD><EFBFBD>쳣ԭ<ECB3A3><D4AD><EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2></param>
/// <param name="innerException"><3E><><EFBFBD>µ<EFBFBD>ǰ<EFBFBD><EFBFBD><ECB3A3><EFBFBD><EFBFBD><ECB3A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD> innerException <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD><EFBFBD>ã<EFBFBD><C3A3><EFBFBD><EFBFBD>ڴ<EFBFBD><DAB4><EFBFBD><EFBFBD>ڲ<EFBFBD><DAB2><EFBFBD><ECB3A3> catch <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD><EFBFBD><ECB3A3></param>
public GameException(string message, Exception innerException)
: base(message, innerException)
{
}
/// <summary>
/// <20><><EFBFBD><EFBFBD><EFBFBD>л<EFBFBD><D0BB><EFBFBD><EFBFBD>ݳ<EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD>Ϸ<EFBFBD><CFB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><ECB3A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><CAB5><EFBFBD><EFBFBD>
/// </summary>
/// <param name="info"><3E><><EFBFBD><EFBFBD><EFBFBD>й<EFBFBD><D0B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><ECB3A3><EFBFBD><EFBFBD><EFBFBD>л<EFBFBD><D0BB>Ķ<EFBFBD><C4B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݡ<EFBFBD></param>
/// <param name="context"><3E><><EFBFBD><EFBFBD><EFBFBD>й<EFBFBD>Դ<EFBFBD><D4B4>Ŀ<EFBFBD><C4BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2></param>
protected GameException(SerializationInfo info, StreamingContext context)
: base(info, context)
{
}
}
}

View File

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

View File

@@ -0,0 +1,40 @@
using System;
using System.Collections.Generic;
namespace Convention.Experimental.PublicType
{
/// <summary>
/// <20><>Ϸ<EFBFBD><CFB7><EFBFBD><EFBFBD>ģ<EFBFBD><C4A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
public abstract class GameModule
{
/// <summary>
/// <20><>ȡ<EFBFBD><C8A1>Ϸ<EFBFBD><CFB7><EFBFBD><EFBFBD>ģ<EFBFBD><C4A3><EFBFBD><EFBFBD><EFBFBD>ȼ<EFBFBD>
/// </summary>
/// <remarks><3E><><EFBFBD>ȼ<EFBFBD><C8BC>ϸߵ<CFB8>ģ<EFBFBD><C4A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѯ<EFBFBD><D1AF><EFBFBD><EFBFBD><EFBFBD>ȼ<EFBFBD><C8BC>ϵ͵<CFB5>ģ<EFBFBD><C4A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD><D0B6></remarks>
internal virtual int Priority
{
get
{
return 0;
}
}
/// <summary>
/// <20><>Ϸ<EFBFBD><CFB7><EFBFBD><EFBFBD>ģ<EFBFBD><C4A3><EFBFBD><EFBFBD>ѯ
/// </summary>
/// <param name="elapseSeconds"><3E>߼<EFBFBD><DFBC><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><E4A3AC><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA>λ</param>
/// <param name="realElapseSeconds"><3E><>ʵ<EFBFBD><CAB5><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><E4A3AC><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA>λ</param>
internal virtual void Update(float elapseSeconds, float realElapseSeconds) { }
/// <summary>
/// <20>رղ<D8B1><D5B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϸ<EFBFBD><CFB7><EFBFBD><EFBFBD>ģ<EFBFBD><C4A3>
/// </summary>
internal virtual void Shutdown() { }
/// <summary>
/// ǰ<><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϸ<EFBFBD><CFB7><EFBFBD><EFBFBD>ģ<EFBFBD><C4A3><EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD>
/// </summary>
internal virtual IEnumerable<Type> Dependences() => Array.Empty<Type>();
}
}

View File

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

View File

@@ -0,0 +1,10 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using UnityEngine;
namespace Convention.Experimental.PublicType
{
}

View File

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

View File

@@ -0,0 +1,10 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using Unity.VisualScripting;
using UnityEngine;
namespace Convention.Experimental.PublicType
{
}

View File

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

View File

@@ -12,7 +12,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
m_Name:
m_EditorClassIdentifier:
version: 7
version: 10
--- !u!21 &2100000
Material:
serializedVersion: 8
@@ -25,13 +25,15 @@ Material:
m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords: []
m_InvalidKeywords: []
m_InvalidKeywords:
- _EMISSION
m_LightmapFlags: 2
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
disabledShaderPasses:
- MOTIONVECTORS
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3
@@ -57,3 +59,4 @@ Material:
- _FocusColor: {r: 0, g: 0, b: 0, a: 1}
- _FocusEmisson: {r: 0, g: 0, b: 1, a: 0}
m_BuildTextureStacks: []
m_AllowLocking: 1

View File

@@ -12,7 +12,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
m_Name:
m_EditorClassIdentifier:
version: 7
version: 10
--- !u!21 &2100000
Material:
serializedVersion: 8
@@ -25,13 +25,15 @@ Material:
m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords: []
m_InvalidKeywords: []
m_InvalidKeywords:
- _EMISSION
m_LightmapFlags: 2
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
disabledShaderPasses:
- MOTIONVECTORS
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3
@@ -55,4 +57,6 @@ Material:
m_Colors:
- _Color: {r: 0, g: 0, b: 0, a: 0}
- _FocusColor: {r: 0, g: 0, b: 1, a: 0}
- _FocusEmisson: {r: 0, g: 0, b: 0, a: 0}
m_BuildTextureStacks: []
m_AllowLocking: 1

View File

@@ -12,7 +12,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
m_Name:
m_EditorClassIdentifier:
version: 7
version: 10
--- !u!21 &2100000
Material:
serializedVersion: 8
@@ -25,13 +25,15 @@ Material:
m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords: []
m_InvalidKeywords: []
m_InvalidKeywords:
- _EMISSION
m_LightmapFlags: 2
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
disabledShaderPasses:
- MOTIONVECTORS
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3
@@ -57,3 +59,4 @@ Material:
- _FocusColor: {r: 0, g: 0, b: 0, a: 1}
- _FocusEmisson: {r: 0, g: 1, b: 0, a: 0}
m_BuildTextureStacks: []
m_AllowLocking: 1

View File

@@ -12,7 +12,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
m_Name:
m_EditorClassIdentifier:
version: 7
version: 10
--- !u!21 &2100000
Material:
serializedVersion: 8
@@ -25,13 +25,15 @@ Material:
m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords: []
m_InvalidKeywords: []
m_InvalidKeywords:
- _EMISSION
m_LightmapFlags: 2
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
disabledShaderPasses:
- MOTIONVECTORS
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3
@@ -55,4 +57,6 @@ Material:
m_Colors:
- _Color: {r: 0, g: 0, b: 0, a: 0}
- _FocusColor: {r: 0, g: 1, b: 0, a: 0}
- _FocusEmisson: {r: 0, g: 0, b: 0, a: 0}
m_BuildTextureStacks: []
m_AllowLocking: 1

View File

@@ -12,7 +12,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
m_Name:
m_EditorClassIdentifier:
version: 7
version: 10
--- !u!21 &2100000
Material:
serializedVersion: 8
@@ -25,13 +25,15 @@ Material:
m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords: []
m_InvalidKeywords: []
m_InvalidKeywords:
- _EMISSION
m_LightmapFlags: 2
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
disabledShaderPasses:
- MOTIONVECTORS
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3
@@ -57,3 +59,4 @@ Material:
- _FocusColor: {r: 0, g: 0, b: 0, a: 1}
- _FocusEmisson: {r: 1, g: 0, b: 0, a: 0}
m_BuildTextureStacks: []
m_AllowLocking: 1

View File

@@ -12,7 +12,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
m_Name:
m_EditorClassIdentifier:
version: 7
version: 10
--- !u!21 &2100000
Material:
serializedVersion: 8
@@ -25,13 +25,15 @@ Material:
m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords: []
m_InvalidKeywords: []
m_InvalidKeywords:
- _EMISSION
m_LightmapFlags: 2
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
disabledShaderPasses:
- MOTIONVECTORS
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3
@@ -57,3 +59,4 @@ Material:
- _FocusColor: {r: 1, g: 0, b: 0, a: 0}
- _FocusEmisson: {r: 0, g: 0, b: 0, a: 0}
m_BuildTextureStacks: []
m_AllowLocking: 1

View File

@@ -12,7 +12,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
m_Name:
m_EditorClassIdentifier:
version: 7
version: 10
--- !u!21 &2100000
Material:
serializedVersion: 8
@@ -25,13 +25,15 @@ Material:
m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords: []
m_InvalidKeywords: []
m_InvalidKeywords:
- _EMISSION
m_LightmapFlags: 2
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
disabledShaderPasses:
- MOTIONVECTORS
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3
@@ -57,3 +59,4 @@ Material:
- _FocusColor: {r: 0, g: 0, b: 0, a: 0}
- _FocusEmisson: {r: 1, g: 1, b: 1, a: 0}
m_BuildTextureStacks: []
m_AllowLocking: 1

View File

@@ -12,7 +12,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
m_Name:
m_EditorClassIdentifier:
version: 7
version: 10
--- !u!21 &2100000
Material:
serializedVersion: 8
@@ -25,13 +25,15 @@ Material:
m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords: []
m_InvalidKeywords: []
m_InvalidKeywords:
- _EMISSION
m_LightmapFlags: 2
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
disabledShaderPasses:
- MOTIONVECTORS
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3
@@ -57,3 +59,4 @@ Material:
- _FocusColor: {r: 1, g: 1, b: 1, a: 0}
- _FocusEmisson: {r: 0, g: 0, b: 0, a: 0}
m_BuildTextureStacks: []
m_AllowLocking: 1

View File

@@ -12,7 +12,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
m_Name:
m_EditorClassIdentifier:
version: 7
version: 10
--- !u!21 &2100000
Material:
serializedVersion: 8
@@ -32,7 +32,8 @@ Material:
m_CustomRenderQueue: -1
stringTagMap:
RenderType: Opaque
disabledShaderPasses: []
disabledShaderPasses:
- MOTIONVECTORS
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3
@@ -131,3 +132,4 @@ Material:
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1}
m_BuildTextureStacks: []
m_AllowLocking: 1

View File

@@ -12,7 +12,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
m_Name:
m_EditorClassIdentifier:
version: 7
version: 10
--- !u!21 &2100000
Material:
serializedVersion: 8
@@ -21,19 +21,19 @@ Material:
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: Template
m_Shader: {fileID: -6465566751694194690, guid: be64c4a17e7d11847942454405ae536d,
type: 3}
m_Shader: {fileID: -6465566751694194690, guid: be64c4a17e7d11847942454405ae536d, type: 3}
m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords:
m_ValidKeywords: []
m_InvalidKeywords:
- _REFLECTION_PROBE_BOX_PROJECTION
m_InvalidKeywords: []
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
disabledShaderPasses:
- MOTIONVECTORS
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3
@@ -82,3 +82,4 @@ Material:
- _ColorFilter: {r: 0.7411765, g: 0.8392157, b: 1, a: 1}
- _TransitionEdgeColor: {r: 7.1354446, g: 2.9139512, b: 0.41094184, a: 0}
m_BuildTextureStacks: []
m_AllowLocking: 1

View File

@@ -32,8 +32,6 @@ MonoBehaviour:
assemblyNames:
- Assembly-CSharp
- Assembly-CSharp-firstpass
- Cinemachine
- CW.Common
- Dreamteck.Splines
- Dreamteck.Utilities
- EasySave3
@@ -42,9 +40,6 @@ MonoBehaviour:
- glTFast.dots
- glTFast.Export
- glTFast.Newtonsoft
- LeanCommon
- LeanGUI
- LeanTransition
showAdvancedSettings: 0
addMgrToSceneAutomatically: 0
autoUpdateReferences: 1

View File

@@ -22,7 +22,7 @@ namespace ES3Internal
public StreamReader baseReader;
internal ES3JSONReader(Stream stream, ES3Settings settings, bool readHeaderAndFooter = true) : base(settings, readHeaderAndFooter)
public ES3JSONReader(Stream stream, ES3Settings settings, bool readHeaderAndFooter = true) : base(settings, readHeaderAndFooter)
{
this.baseReader = new StreamReader(stream);

View File

@@ -49,7 +49,7 @@ namespace ES3Types
instance.contactOffset = reader.Read<System.Single>();
break;
case "material":
instance.sharedMaterial = reader.Read<UnityEngine.PhysicMaterial>();
instance.sharedMaterial = reader.Read<UnityEngine.PhysicsMaterial>();
break;
default:
reader.Skip();

View File

@@ -57,7 +57,7 @@ namespace ES3Types
instance.contactOffset = reader.Read<System.Single>(ES3Type_float.Instance);
break;
case "material":
instance.sharedMaterial = reader.Read<UnityEngine.PhysicMaterial>();
instance.sharedMaterial = reader.Read<UnityEngine.PhysicsMaterial>();
break;
default:
reader.Skip();

View File

@@ -58,7 +58,7 @@ namespace ES3Types
instance.contactOffset = reader.Read<System.Single>(ES3Type_float.Instance);
break;
case "material":
instance.sharedMaterial = reader.Read<UnityEngine.PhysicMaterial>(ES3Type_PhysicMaterial.Instance);
instance.sharedMaterial = reader.Read<PhysicsMaterial>(ES3Type_PhysicMaterial.Instance);
break;
default:
reader.Skip();

View File

@@ -16,10 +16,10 @@ namespace ES3Types
{
var instance = (UnityEngine.Rigidbody)obj;
writer.WriteProperty("velocity", instance.velocity, ES3Type_Vector3.Instance);
writer.WriteProperty("velocity", instance.linearVelocity, ES3Type_Vector3.Instance);
writer.WriteProperty("angularVelocity", instance.angularVelocity, ES3Type_Vector3.Instance);
writer.WriteProperty("drag", instance.drag, ES3Type_float.Instance);
writer.WriteProperty("angularDrag", instance.angularDrag, ES3Type_float.Instance);
writer.WriteProperty("drag", instance.linearDamping, ES3Type_float.Instance);
writer.WriteProperty("angularDrag", instance.angularDamping, ES3Type_float.Instance);
writer.WriteProperty("mass", instance.mass, ES3Type_float.Instance);
writer.WriteProperty("useGravity", instance.useGravity, ES3Type_bool.Instance);
writer.WriteProperty("maxDepenetrationVelocity", instance.maxDepenetrationVelocity, ES3Type_float.Instance);
@@ -47,16 +47,16 @@ namespace ES3Types
{
case "velocity":
instance.velocity = reader.Read<UnityEngine.Vector3>(ES3Type_Vector3.Instance);
instance.linearVelocity = reader.Read<UnityEngine.Vector3>(ES3Type_Vector3.Instance);
break;
case "angularVelocity":
instance.angularVelocity = reader.Read<UnityEngine.Vector3>(ES3Type_Vector3.Instance);
break;
case "drag":
instance.drag = reader.Read<System.Single>(ES3Type_float.Instance);
instance.linearDamping = reader.Read<System.Single>(ES3Type_float.Instance);
break;
case "angularDrag":
instance.angularDrag = reader.Read<System.Single>(ES3Type_float.Instance);
instance.angularDamping = reader.Read<System.Single>(ES3Type_float.Instance);
break;
case "mass":
instance.mass = reader.Read<System.Single>(ES3Type_float.Instance);

View File

@@ -48,7 +48,7 @@ namespace ES3Types
instance.contactOffset = reader.Read<System.Single>(ES3Type_float.Instance);
break;
case "material":
instance.sharedMaterial = reader.Read<UnityEngine.PhysicMaterial>();
instance.sharedMaterial = reader.Read<UnityEngine.PhysicsMaterial>();
break;
default:
reader.Skip();

View File

@@ -8,11 +8,11 @@ namespace ES3Types
{
public static ES3Type Instance = null;
public ES3Type_PhysicMaterial() : base(typeof(UnityEngine.PhysicMaterial)){ Instance = this; }
public ES3Type_PhysicMaterial() : base(typeof(UnityEngine.PhysicsMaterial)){ Instance = this; }
protected override void WriteObject(object obj, ES3Writer writer)
{
var instance = (UnityEngine.PhysicMaterial)obj;
var instance = (UnityEngine.PhysicsMaterial)obj;
writer.WriteProperty("dynamicFriction", instance.dynamicFriction, ES3Type_float.Instance);
writer.WriteProperty("staticFriction", instance.staticFriction, ES3Type_float.Instance);
@@ -23,7 +23,7 @@ namespace ES3Types
protected override void ReadObject<T>(ES3Reader reader, object obj)
{
var instance = (UnityEngine.PhysicMaterial)obj;
var instance = (UnityEngine.PhysicsMaterial)obj;
foreach(string propertyName in reader.Properties)
{
switch(propertyName)
@@ -39,10 +39,10 @@ namespace ES3Types
instance.bounciness = reader.Read<System.Single>(ES3Type_float.Instance);
break;
case "frictionCombine":
instance.frictionCombine = reader.Read<UnityEngine.PhysicMaterialCombine>();
instance.frictionCombine = reader.Read<UnityEngine.PhysicsMaterialCombine>();
break;
case "bounceCombine":
instance.bounceCombine = reader.Read<UnityEngine.PhysicMaterialCombine>();
instance.bounceCombine = reader.Read<UnityEngine.PhysicsMaterialCombine>();
break;
default:
reader.Skip();
@@ -53,7 +53,7 @@ namespace ES3Types
protected override object ReadObject<T>(ES3Reader reader)
{
var instance = new UnityEngine.PhysicMaterial();
var instance = new UnityEngine.PhysicsMaterial();
ReadObject<T>(reader, instance);
return instance;
}
@@ -63,7 +63,7 @@ namespace ES3Types
{
public static ES3Type Instance;
public ES3Type_PhysicMaterialArray() : base(typeof(UnityEngine.PhysicMaterial[]), ES3Type_PhysicMaterial.Instance)
public ES3Type_PhysicMaterialArray() : base(typeof(UnityEngine.PhysicsMaterial[]), ES3Type_PhysicMaterial.Instance)
{
Instance = this;
}

View File

@@ -8,10 +8,15 @@ using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using Convention.WindowsUI;
using Sirenix.Utilities;
using Demo.Game;
using Unity.Collections;
using UnityEditor;
#if UNITY_EDITOR
using UnityEditor.Build;
#endif
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Rendering;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
@@ -423,6 +428,245 @@ namespace Convention
{
return DateTime.Now.ToString(format);
}
/// <summary>
/// Marshal 相关的实用函数。
/// </summary>
public static class Marshal
{
[Serializable]
public class MarshalException : Exception
{
public MarshalException() { }
public MarshalException(string message) : base(message) { }
public MarshalException(string message, Exception inner) : base(message, inner) { }
protected MarshalException(
System.Runtime.Serialization.SerializationInfo info,
System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
}
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 MarshalException("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 MarshalException("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 MarshalException("Structure size is invalid.");
}
if (result == null)
{
throw new MarshalException("Result is invalid.");
}
if (startIndex < 0)
{
throw new MarshalException("Start index is invalid.");
}
if (startIndex + structureSize > result.Length)
{
throw new MarshalException("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 MarshalException("Structure size is invalid.");
}
if (buffer == null)
{
throw new MarshalException("Buffer is invalid.");
}
if (startIndex < 0)
{
throw new MarshalException("Start index is invalid.");
}
if (startIndex + structureSize > buffer.Length)
{
throw new MarshalException("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));
}
}
}
}
@@ -438,7 +682,7 @@ namespace Convention
public static _T convert_xvalue<_T>([In] string str)
{
Type type = typeof(_T);
var parse_method = type.GetMethod("Parse");
var parse_method = type.GetMethod(nameof(int.Parse), BindingFlags.Static | BindingFlags.Public, null, new Type[] { typeof(string) }, null);
if (parse_method != null &&
(parse_method.ReturnType.IsSubclassOf(type) || parse_method.ReturnType == type) &&
parse_method.GetParameters().Length == 1 &&
@@ -1030,7 +1274,11 @@ namespace Convention
#endif
public static void InitExtensionEnv()
{
UnityEngine.Application.quitting += () => CoroutineStarter = null;
UnityEngine.Application.quitting += () =>
{
GameObject.Destroy(s_CoroutineStarter.gameObject);
s_CoroutineStarter = null;
};
InitExtensionEnvCalls();
GlobalConfig.InitExtensionEnv();
@@ -1044,26 +1292,82 @@ namespace Convention
return MainThreadID == Thread.CurrentThread.ManagedThreadId;
}
private static CoroutineMonoStarterUtil CoroutineStarter;
private static CoroutineMonoStarterUtil s_CoroutineStarter;
private static CoroutineMonoStarterUtil CoroutineStarter
{
get
{
if (s_CoroutineStarter == null)
{
s_CoroutineStarter = new GameObject($"{nameof(ConventionUtility)}-{nameof(CoroutineStarter)}").AddComponent<CoroutineMonoStarterUtil>();
}
return s_CoroutineStarter;
}
}
public static GameObject Singleton => CoroutineStarter.gameObject;
private class CoroutineMonoStarterUtil : MonoBehaviour
{
internal float waitClock;
private void Update()
{
waitClock = Time.realtimeSinceStartup;
MainThreadID = Thread.CurrentThread.ManagedThreadId;
}
private void OnDestroy()
{
CoroutineStarter = null;
s_CoroutineStarter = null;
}
}
/// <summary>
/// 包装即将用于协程的迭代器成为一个防止假死机的迭代器
/// </summary>
/// <param name="ir"></param>
/// <returns></returns>
public static IEnumerator AvoidFakeStop(IEnumerator ir, float fps = 5)
{
Stack<IEnumerator> loadingTask = new();
loadingTask.Push(ir);
float maxWaitClock = 1 / fps;
while (loadingTask.Count > 0)
{
// 防止大量无延迟函数的使用导致假死机
//if (Time.realtimeSinceStartup - CoroutineStarter.waitClock > maxWaitClock)
{
yield return null;
}
if (loadingTask.Peek().MoveNext())
{
if (loadingTask.Peek().Current is IEnumerator next)
loadingTask.Push(next);
}
else
{
loadingTask.Pop();
}
}
}
/// <summary>
/// 包装即将用于协程的迭代器成为一个防止假死机的迭代器
/// </summary>
/// <param name="ir"></param>
/// <returns></returns>
public static IEnumerator AvoidFakeStopWithoutDeepStack(IEnumerator ir, float fps = 5)
{
float maxWaitClock = 1 / fps;
while (ir.MoveNext())
{
// 防止大量无延迟函数的使用导致假死机
if (Time.realtimeSinceStartup - CoroutineStarter.waitClock > maxWaitClock)
{
yield return null;
}
}
}
public static Coroutine StartCoroutine(IEnumerator coroutine)
{
if (CoroutineStarter == null)
{
CoroutineStarter = new GameObject($"{nameof(ConventionUtility)}-{nameof(CoroutineStarter)}").AddComponent<CoroutineMonoStarterUtil>();
}
return CoroutineStarter.StartCoroutine(coroutine);
}
public static void CloseCoroutine(Coroutine coroutine)
@@ -1077,28 +1381,30 @@ namespace Convention
public class ActionStepCoroutineWrapper
{
private class YieldInstructionWrapper
private struct YieldInstructionWrapper
{
public YieldInstruction UnityYieldInstruction;
public CustomYieldInstruction CustomYieldInstruction;
public YieldInstructionWrapper()
{
}
public YieldInstructionWrapper(YieldInstruction unityYieldInstruction)
public YieldInstructionWrapper(YieldInstruction unityYieldInstruction, CustomYieldInstruction customYieldInstruction)
{
this.UnityYieldInstruction = unityYieldInstruction;
this.CustomYieldInstruction = customYieldInstruction;
}
public YieldInstructionWrapper(CustomYieldInstruction customYieldInstruction)
public static YieldInstructionWrapper Make(YieldInstruction unityYieldInstruction)
{
this.CustomYieldInstruction = customYieldInstruction;
return new(unityYieldInstruction, null);
}
public static YieldInstructionWrapper Make(CustomYieldInstruction customYieldInstruction)
{
return new(null, customYieldInstruction);
}
}
private List<KeyValuePair<YieldInstructionWrapper, Action>> steps = new();
public ActionStepCoroutineWrapper Update(Action action)
{
steps.Add(new(new(), action));
@@ -1106,33 +1412,33 @@ namespace Convention
}
public ActionStepCoroutineWrapper Wait(float time, Action action)
{
steps.Add(new(new(new WaitForSeconds(time)), action));
steps.Add(new(YieldInstructionWrapper.Make(new WaitForSeconds(time)), action));
return this;
}
public ActionStepCoroutineWrapper FixedUpdate(Action action)
{
steps.Add(new(new (new WaitForFixedUpdate()), action));
steps.Add(new(YieldInstructionWrapper.Make(new WaitForFixedUpdate()), action));
return this;
}
public ActionStepCoroutineWrapper Next(Action action)
{
steps.Add(new(new(new WaitForEndOfFrame()), action));
steps.Add(new(YieldInstructionWrapper.Make(new WaitForEndOfFrame()), action));
return this;
}
public ActionStepCoroutineWrapper Until(Func<bool> pr, Action action)
{
steps.Add(new(new(new WaitUntil(pr)), action));
steps.Add(new(YieldInstructionWrapper.Make(new WaitUntil(pr)), action));
return this;
}
private static IEnumerator Execute(List<KeyValuePair<YieldInstructionWrapper, Action>> steps)
{
foreach (var (waiting, action) in steps)
{
action();
if (waiting.UnityYieldInstruction != null)
yield return waiting.UnityYieldInstruction;
else
yield return waiting.CustomYieldInstruction;
action();
}
}
~ActionStepCoroutineWrapper()
@@ -1960,6 +2266,39 @@ namespace Convention
public static class ScriptingDefineUtility
{
#if UNITY_EDITOR
#if UNITY_6000_0_OR_NEWER
public static void Add(string define, NamedBuildTarget target, bool log = false)
{
string definesString = PlayerSettings.GetScriptingDefineSymbols(target);
if (definesString.Contains(define)) return;
string[] allDefines = definesString.Split(';');
ArrayUtility.Add(ref allDefines, define);
definesString = string.Join(";", allDefines);
PlayerSettings.SetScriptingDefineSymbols(target, definesString);
Debug.Log("Added \"" + define + "\" from " + EditorUserBuildSettings.selectedBuildTargetGroup + " Scripting define in Player Settings");
}
public static void Remove(string define, NamedBuildTarget target, bool log = false)
{
string definesString = PlayerSettings.GetScriptingDefineSymbols(target);
if (!definesString.Contains(define)) return;
string[] allDefines = definesString.Split(';');
ArrayUtility.Remove(ref allDefines, define);
definesString = string.Join(";", allDefines);
PlayerSettings.SetScriptingDefineSymbols(target, definesString);
Debug.Log("Removed \"" + define + "\" from " + EditorUserBuildSettings.selectedBuildTargetGroup + " Scripting define in Player Settings");
}
public static void Add(string define, BuildTargetGroup target, bool log = false)
{
Add(define, NamedBuildTarget.FromBuildTargetGroup(target), log);
}
public static void Remove(string define, BuildTargetGroup target, bool log = false)
{
Remove(define, NamedBuildTarget.FromBuildTargetGroup(target), log);
}
#else
public static void Add(string define, BuildTargetGroup target, bool log = false)
{
string definesString = PlayerSettings.GetScriptingDefineSymbolsForGroup(target);
@@ -1981,6 +2320,8 @@ namespace Convention
PlayerSettings.SetScriptingDefineSymbolsForGroup(target, definesString);
Debug.Log("Removed \"" + define + "\" from " + EditorUserBuildSettings.selectedBuildTargetGroup + " Scripting define in Player Settings");
}
#endif
#endif
}
}
@@ -2205,3 +2546,496 @@ namespace Convention
}
}
namespace Convention
{
public static partial class Utility
{
/// <summary>
/// 生成期望类型的栈实例
/// </summary>
/// <param name="type">期望类型</param>
/// <returns></returns>
public static object CreateStack([In] Type type)
{
var stackType = typeof(Stack<>).MakeGenericType(type);
var stackInstance = Activator.CreateInstance(stackType);
return stackInstance;
}
/// <summary>
/// 生成期望类型的队列实例
/// </summary>
/// <param name="type">期望类型</param>
/// <returns></returns>
public static object CreateQueue([In] Type type)
{
var queueType = typeof(Queue<>).MakeGenericType(type);
var queueInstance = Activator.CreateInstance(queueType);
return queueInstance;
}
/// <summary>
/// 生成期望类型的列表实例
/// </summary>
/// <param name="type">期望类型</param>
/// <returns></returns>
public static object CreateList([In] Type type)
{
var listType = typeof(List<>).MakeGenericType(type);
var listInstance = Activator.CreateInstance(listType);
return listInstance;
}
/// <summary>
/// 生成期望键值对类型的字典实例
/// </summary>
/// <param name="keyType">期望键类型</param>
/// <param name="valueType">期望值类型</param>
/// <returns></returns>
public static object CreateDictionary([In] Type keyType, [In] Type valueType)
{
var dictType = typeof(Dictionary<,>).MakeGenericType(keyType, valueType);
var dictInstance = Activator.CreateInstance(dictType);
return dictInstance;
}
}
}
namespace Convention
{
public static class BinarySerializeUtility
{
#region Base
public static void WriteBool(BinaryWriter writer, bool data)
{
writer.Write(data);
}
public static bool ReadBool(BinaryReader reader)
{
return reader.ReadBoolean();
}
public static void WriteInt(BinaryWriter writer, in int data)
{
writer.Write(data);
}
public static int ReadInt(BinaryReader reader)
{
return reader.ReadInt32();
}
public static void WriteFloat(BinaryWriter writer, in float data)
{
writer.Write(data);
}
public static float ReadFloat(BinaryReader reader)
{
return reader.ReadSingle();
}
public static void WriteChar(BinaryWriter writer, in char data)
{
writer.Write(data);
}
public static char ReadChar(BinaryReader reader)
{
return reader.ReadChar();
}
public static void WriteString(BinaryWriter writer, in string data)
{
writer.Write(data ?? "");
}
public static string ReadString(BinaryReader reader)
{
return reader.ReadString();
}
public static void WriteVec3(BinaryWriter writer, in Vector3 data)
{
writer.Write(data.x);
writer.Write(data.y);
writer.Write(data.z);
}
public static Vector3 ReadVec3(BinaryReader reader)
{
float x, y, z;
x = reader.ReadSingle();
y = reader.ReadSingle();
z = reader.ReadSingle();
return new Vector3(x, y, z);
}
public static void WriteVec2(BinaryWriter writer, in Vector2 data)
{
writer.Write(data.x);
writer.Write(data.y);
}
public static Vector2 ReadVec2(BinaryReader reader)
{
float x, y;
x = reader.ReadSingle();
y = reader.ReadSingle();
return new Vector2(x, y);
}
public static void WriteColor(BinaryWriter writer, in Color data)
{
writer.Write(data.r);
writer.Write(data.g);
writer.Write(data.b);
writer.Write(data.a);
}
public static Color ReadColor(BinaryReader reader)
{
float r, g, b, a;
r = reader.ReadSingle();
g = reader.ReadSingle();
b = reader.ReadSingle();
a = reader.ReadSingle();
return new(r, g, b, a);
}
#endregion
#region Serialize
#region Int
public static void SerializeNativeArray(BinaryWriter writer, in NativeArray<int> array, int start = 0, int end = int.MaxValue)
{
int e = Mathf.Min(array.Length, end);
writer.Write(e - start);
while (start < e)
{
writer.Write(array[start++]);
}
}
public static int DeserializeNativeArray(BinaryReader reader, ref NativeArray<int> array)
{
int count = reader.ReadInt32();
if (array.Length < count)
array.ResizeArray(count);
for (int i = 0; i < count; i++)
{
array[i] = reader.ReadInt32();
}
return count;
}
public static void SerializeArray(BinaryWriter writer, in int[] array, int start = 0, int end = int.MaxValue)
{
int e = Mathf.Min(array.Length, end);
writer.Write(e - start);
while (start < e)
{
writer.Write(array[start++]);
}
}
public static int[] DeserializeIntArray(BinaryReader reader)
{
int count = reader.ReadInt32();
int[] array = new int[count];
for (int i = 0; i < count; i++)
{
array[i] = reader.ReadInt32();
}
return array;
}
#endregion
#region Float
public static void SerializeNativeArray(BinaryWriter writer, in NativeArray<float> array, int start = 0, int end = int.MaxValue)
{
int e = Mathf.Min(array.Length, end);
writer.Write(e - start);
while (start < e)
{
writer.Write(array[start++]);
}
}
public static int DeserializeNativeArray(BinaryReader reader, ref NativeArray<float> array)
{
int count = reader.ReadInt32();
if (array.Length < count)
array.ResizeArray(count);
for (int i = 0; i < count; i++)
{
array[i] = reader.ReadSingle();
}
return count;
}
public static void SerializeArray(BinaryWriter writer, in float[] array, int start = 0, int end = int.MaxValue)
{
int e = Mathf.Min(array.Length, end);
writer.Write(e - start);
while (start < e)
{
writer.Write(array[start++]);
}
}
public static float[] DeserializeFloatArray(BinaryReader reader)
{
int count = reader.ReadInt32();
float[] array = new float[count];
for (int i = 0; i < count; i++)
{
array[i] = reader.ReadSingle();
}
return array;
}
#endregion
#region String
public static void SerializeArray(BinaryWriter writer, in string[] array, int start = 0, int end = int.MaxValue)
{
int e = Mathf.Min(array.Length, end);
writer.Write(e - start);
while (start < e)
{
writer.Write(array[start++] ?? "");
}
}
public static string[] DeserializeStringArray(BinaryReader reader)
{
int count = reader.ReadInt32();
string[] array = new string[count];
for (int i = 0; i < count; i++)
{
array[i] = reader.ReadString();
}
return array;
}
#endregion
#region Vector3
public static void SerializeNativeArray(BinaryWriter writer, in NativeArray<Vector3> array, int start = 0, int end = int.MaxValue)
{
int e = Mathf.Min(array.Length, end);
writer.Write(e - start);
while (start < e)
{
writer.Write(array[start].x);
writer.Write(array[start].y);
writer.Write(array[start].z);
start++;
}
}
public static int DeserializeNativeArray(BinaryReader reader, ref NativeArray<Vector3> array)
{
int count = reader.ReadInt32();
if (array.Length < count)
array.ResizeArray(count);
float x, y, z;
for (int i = 0; i < count; i++)
{
x = reader.ReadSingle();
y = reader.ReadSingle();
z = reader.ReadSingle();
array[i] = new(x, y, z);
}
return count;
}
public static void SerializeArray(BinaryWriter writer, in Vector3[] array, int start = 0, int end = int.MaxValue)
{
int e = Mathf.Min(array.Length, end);
writer.Write(e - start);
while (start < e)
{
writer.Write(array[start].x);
writer.Write(array[start].y);
writer.Write(array[start].z);
start++;
}
}
public static Vector3[] DeserializeVec3Array(BinaryReader reader, int start = 0)
{
int count = reader.ReadInt32();
Vector3[] array = new Vector3[count];
float x, y, z;
for (int i = 0; i < count; i++)
{
x = reader.ReadSingle();
y = reader.ReadSingle();
z = reader.ReadSingle();
array[start + i] = new(x, y, z);
}
return array;
}
#endregion
#region Vector2
public static void SerializeNativeArray(BinaryWriter writer, in NativeArray<Vector2> array, int start = 0, int end = int.MaxValue)
{
int e = Mathf.Min(array.Length, end);
writer.Write(e - start);
while (start < e)
{
writer.Write(array[start].x);
writer.Write(array[start].y);
start++;
}
}
public static int DeserializeNativeArray(BinaryReader reader, ref NativeArray<Vector2> array)
{
int count = reader.ReadInt32();
if (array.Length < count)
array.ResizeArray(count);
float x, y;
for (int i = 0; i < count; i++)
{
x = reader.ReadSingle();
y = reader.ReadSingle();
array[i] = new(x, y);
}
return count;
}
public static void SerializeArray(BinaryWriter writer, in Vector2[] array, int start = 0, int end = int.MaxValue)
{
int e = Mathf.Min(array.Length, end);
writer.Write(e - start);
while (start < e)
{
writer.Write(array[start].x);
writer.Write(array[start].y);
start++;
}
}
public static Vector2[] DeserializeVec2Array(BinaryReader reader)
{
int count = reader.ReadInt32();
Vector2[] array = new Vector2[count];
float x, y;
for (int i = 0; i < count; i++)
{
x = reader.ReadSingle();
y = reader.ReadSingle();
array[i] = new(x, y);
}
return array;
}
#endregion
#region Color
public static void SerializeNativeArray(BinaryWriter writer, in NativeArray<Color> array, int start = 0, int end = int.MaxValue)
{
int e = Mathf.Min(array.Length, end);
writer.Write(e - start);
while (start < e)
{
WriteColor(writer, array[start]);
start++;
}
}
public static int DeserializeNativeArray(BinaryReader reader, ref NativeArray<Color> array)
{
int count = reader.ReadInt32();
if (array.Length < count)
array.ResizeArray(count);
float x, y, z;
for (int i = 0; i < count; i++)
{
array[i] = ReadColor(reader);
}
return count;
}
public static void SerializeArray(BinaryWriter writer, in Color[] array, int start = 0, int end = int.MaxValue)
{
int e = Mathf.Min(array.Length, end);
writer.Write(e - start);
while (start < e)
{
WriteColor(writer, array[start]);
start++;
}
}
public static Color[] DeserializeVec3Array(BinaryReader reader)
{
int count = reader.ReadInt32();
Color[] array = new Color[count];
float x, y, z;
for (int i = 0; i < count; i++)
{
array[i] = ReadColor(reader);
}
return array;
}
#endregion
#endregion
}
public static partial class Utility
{
/// <summary>
/// 获取类型的友好显示名称,支持泛型、数组等复杂类型
/// </summary>
public static string GetFriendlyName(this Type type)
{
if (type == null) return null;
// 处理泛型类型
if (type.IsGenericType)
{
// 特殊处理可空类型Nullable<T>
if (type.IsNullable())
{
return $"{GetFriendlyName(type.GetGenericArguments()[0])}?";
}
var sb = new StringBuilder();
// 获取类型基础名称(移除 `1, `2 等后缀)
string baseName = type.Name.Contains('`') ? type.Name[..type.Name.IndexOf('`')] : type.Name;
sb.Append(baseName);
sb.Append('<');
// 递归处理泛型参数
Type[] args = type.GetGenericArguments();
for (int i = 0; i < args.Length; i++)
{
if (i > 0) sb.Append(", ");
sb.Append(GetFriendlyName(args[i]));
}
sb.Append('>');
return sb.ToString();
}
// 处理数组类型
if (type.IsArray)
{
string elementName = GetFriendlyName(type.GetElementType());
int rank = type.GetArrayRank();
return rank == 1 ? $"{elementName}[]" : $"{elementName}[{new string(',', rank - 1)}]";
}
// 处理指针类型
if (type.IsPointer)
{
return $"{GetFriendlyName(type.GetElementType())}*";
}
// 处理引用类型ref/out 参数)
if (type.IsByRef)
{
return $"{GetFriendlyName(type.GetElementType())}&";
}
// 普通类型直接返回名称
return type.Name;
}
/// <summary>
/// 判断是否为可空类型
/// </summary>
public static bool IsNullable(this Type type)
{
return type.IsGenericType &&
type.GetGenericTypeDefinition() == typeof(Nullable<>);
}
}
}

File diff suppressed because it is too large Load Diff

View File

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

View File

@@ -0,0 +1,490 @@
using Convention.Experimental.PublicType;
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
namespace Convention.ReferenceManagement
{
/// <summary>
/// <20><><EFBFBD>ýӿ<C3BD>
/// </summary>
public interface IReference
{
/// <summary>
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
void Clear();
}
/// <summary>
/// <20><><EFBFBD>ó<EFBFBD>
/// </summary>
public static partial class ReferencePool
{
private static bool m_EnableStrictCheck = false;
/// <summary>
/// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD>ǿ<EFBFBD>Ƽ<EFBFBD><C6BC><EFBFBD>
/// </summary>
public static bool EnableStrictCheck
{
get
{
return m_EnableStrictCheck;
}
set
{
m_EnableStrictCheck = value;
}
}
private sealed class ReferenceCollection
{
private readonly Queue<IReference> m_References;
private readonly Type m_ReferenceType;
private int m_UsingReferenceCount;
private int m_AcquireReferenceCount;
private int m_ReleaseReferenceCount;
private int m_AddReferenceCount;
private int m_RemoveReferenceCount;
public ReferenceCollection(Type referenceType)
{
m_References = new Queue<IReference>();
m_ReferenceType = referenceType;
m_UsingReferenceCount = 0;
m_AcquireReferenceCount = 0;
m_ReleaseReferenceCount = 0;
m_AddReferenceCount = 0;
m_RemoveReferenceCount = 0;
}
public Type ReferenceType
{
get
{
return m_ReferenceType;
}
}
public int UnusedReferenceCount
{
get
{
return m_References.Count;
}
}
public int UsingReferenceCount
{
get
{
return m_UsingReferenceCount;
}
}
public int AcquireReferenceCount
{
get
{
return m_AcquireReferenceCount;
}
}
public int ReleaseReferenceCount
{
get
{
return m_ReleaseReferenceCount;
}
}
public int AddReferenceCount
{
get
{
return m_AddReferenceCount;
}
}
public int RemoveReferenceCount
{
get
{
return m_RemoveReferenceCount;
}
}
public T Acquire<T>() where T : class, IReference, new()
{
if (typeof(T) != m_ReferenceType)
{
throw new GameException("Type is invalid.");
}
m_UsingReferenceCount++;
m_AcquireReferenceCount++;
lock (m_References)
{
if (m_References.Count > 0)
{
return (T)m_References.Dequeue();
}
}
m_AddReferenceCount++;
return new T();
}
public IReference Acquire()
{
m_UsingReferenceCount++;
m_AcquireReferenceCount++;
lock (m_References)
{
if (m_References.Count > 0)
{
return m_References.Dequeue();
}
}
m_AddReferenceCount++;
return (IReference)Activator.CreateInstance(m_ReferenceType);
}
public void Release(IReference reference)
{
reference.Clear();
lock (m_References)
{
if (m_EnableStrictCheck && m_References.Contains(reference))
{
throw new GameException("The reference has been released.");
}
m_References.Enqueue(reference);
}
m_ReleaseReferenceCount++;
m_UsingReferenceCount--;
}
public void Add<T>(int count) where T : class, IReference, new()
{
if (typeof(T) != m_ReferenceType)
{
throw new GameException("Type is invalid.");
}
lock (m_References)
{
m_AddReferenceCount += count;
while (count-- > 0)
{
m_References.Enqueue(new T());
}
}
}
public void Add(int count)
{
lock (m_References)
{
m_AddReferenceCount += count;
while (count-- > 0)
{
m_References.Enqueue((IReference)Activator.CreateInstance(m_ReferenceType));
}
}
}
public void Remove(int count)
{
lock (m_References)
{
if (count > m_References.Count)
{
count = m_References.Count;
}
m_RemoveReferenceCount += count;
while (count-- > 0)
{
m_References.Dequeue();
}
}
}
public void RemoveAll()
{
lock (m_References)
{
m_RemoveReferenceCount += m_References.Count;
m_References.Clear();
}
}
}
private static readonly Dictionary<Type, ReferenceCollection> s_ReferenceCollections = new();
/// <summary>
/// <20><>ȡ<EFBFBD><C8A1><EFBFBD>óص<C3B3><D8B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
public static int Count
{
get
{
return s_ReferenceCollections.Count;
}
}
/// <summary>
/// <20><><EFBFBD>ó<EFBFBD><C3B3><EFBFBD>Ϣ
/// </summary>
[StructLayout(LayoutKind.Auto)]
public readonly struct ReferencePoolInfo
{
/// <summary>
/// <20><><EFBFBD>ó<EFBFBD><C3B3><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
public readonly Type Type;
/// <summary>
/// δʹ<CEB4><CAB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
public readonly int UnusedReferenceCount;
/// <summary>
/// <20><><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
public readonly int UsingReferenceCount;
/// <summary>
/// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
public readonly int AcquireReferenceCount;
/// <summary>
/// <20><EFBFBD><E9BBB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
public readonly int ReleaseReferenceCount;
/// <summary>
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
public readonly int AddReferenceCount;
/// <summary>
/// <20>Ƴ<EFBFBD><C6B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
public readonly int RemoveReferenceCount;
/// <summary>
/// <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD>ó<EFBFBD><C3B3><EFBFBD>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD>ʵ<EFBFBD><CAB5><EFBFBD><EFBFBD>
/// </summary>
/// <param name="type"><3E><><EFBFBD>ó<EFBFBD><C3B3><EFBFBD><EFBFBD>͡<EFBFBD></param>
/// <param name="unusedReferenceCount">δʹ<CEB4><CAB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></param>
/// <param name="usingReferenceCount"><3E><><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></param>
/// <param name="acquireReferenceCount"><3E><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></param>
/// <param name="releaseReferenceCount"><3E><EFBFBD><E9BBB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></param>
/// <param name="addReferenceCount"><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></param>
/// <param name="removeReferenceCount"><3E>Ƴ<EFBFBD><C6B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></param>
public ReferencePoolInfo(Type type,
int unusedReferenceCount,
int usingReferenceCount,
int acquireReferenceCount,
int releaseReferenceCount,
int addReferenceCount,
int removeReferenceCount)
{
this.Type = type;
this.UnusedReferenceCount = unusedReferenceCount;
this.UsingReferenceCount = usingReferenceCount;
this.AcquireReferenceCount = acquireReferenceCount;
this.ReleaseReferenceCount = releaseReferenceCount;
this.AddReferenceCount = addReferenceCount;
this.RemoveReferenceCount = removeReferenceCount;
}
}
/// <summary>
/// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>óص<C3B3><D8B5><EFBFBD>Ϣ
/// </summary>
/// <returns><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>óص<C3B3><D8B5><EFBFBD>Ϣ</returns>
public static ReferencePoolInfo[] GetAllReferencePoolInfos()
{
int index = 0;
ReferencePoolInfo[] results = null;
lock (s_ReferenceCollections)
{
results = new ReferencePoolInfo[s_ReferenceCollections.Count];
foreach (var (key, value) in s_ReferenceCollections)
{
results[index++] = new ReferencePoolInfo(key,
value.UnusedReferenceCount,
value.UsingReferenceCount,
value.AcquireReferenceCount,
value.ReleaseReferenceCount,
value.AddReferenceCount,
value.RemoveReferenceCount);
}
}
return results;
}
/// <summary>
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ó<EFBFBD>
/// </summary>
public static void ClearAll()
{
lock (s_ReferenceCollections)
{
foreach (var (_, value) in s_ReferenceCollections)
{
value.RemoveAll();
}
s_ReferenceCollections.Clear();
}
}
private static ReferenceCollection GetReferenceCollection(Type referenceType)
{
if (referenceType == null)
{
throw new GameException("ReferenceType is invalid.");
}
ReferenceCollection referenceCollection = null;
lock (s_ReferenceCollections)
{
if (!s_ReferenceCollections.TryGetValue(referenceType, out referenceCollection))
{
referenceCollection = new ReferenceCollection(referenceType);
s_ReferenceCollections.Add(referenceType, referenceCollection);
}
}
return referenceCollection;
}
private static void InternalCheckReferenceType(Type referenceType)
{
if (!m_EnableStrictCheck)
{
return;
}
if (referenceType == null)
{
throw new GameException("Reference type is invalid.");
}
if (!referenceType.IsClass || referenceType.IsAbstract)
{
throw new GameException("Reference type is not a non-abstract class type.");
}
if (!typeof(IReference).IsAssignableFrom(referenceType))
{
throw new GameException($"Reference type '{referenceType.FullName}' is invalid.");
}
}
/// <summary>
/// <20><><EFBFBD><EFBFBD><EFBFBD>óػ<C3B3>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>
/// </summary>
/// <param name="referenceType"><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></param>
/// <returns><3E><><EFBFBD><EFBFBD></returns>
public static IReference Acquire(Type referenceType)
{
InternalCheckReferenceType(referenceType);
return GetReferenceCollection(referenceType).Acquire();
}
/// <summary>
/// <20><><EFBFBD><EFBFBD><EFBFBD>óػ<C3B3>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>
/// </summary>
/// <typeparam name="T"><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></typeparam>
/// <returns><3E><><EFBFBD><EFBFBD></returns>
public static T Acquire<T>() where T : class, IReference, new()
{
return GetReferenceCollection(typeof(T)).Acquire<T>();
}
/// <summary>
/// <20><><EFBFBD><EFBFBD><EFBFBD>ù黹<C3B9><E9BBB9><EFBFBD>ó<EFBFBD>
/// </summary>
/// <param name="reference"><3E><><EFBFBD><EFBFBD></param>
public static void Release(IReference reference)
{
if (reference == null)
{
throw new GameException("Reference is invalid.");
}
Type referenceType = reference.GetType();
InternalCheckReferenceType(referenceType);
GetReferenceCollection(referenceType).Release(reference);
}
/// <summary>
/// <20><><EFBFBD><EFBFBD><EFBFBD>ó<EFBFBD><C3B3><EFBFBD>׷<EFBFBD><D7B7>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
/// <typeparam name="T"><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></typeparam>
/// <param name="count">׷<><D7B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD></param>
public static void Add<T>(int count) where T : class, IReference, new()
{
GetReferenceCollection(typeof(T)).Add<T>(count);
}
/// <summary>
/// <20><><EFBFBD><EFBFBD><EFBFBD>ó<EFBFBD><C3B3><EFBFBD>׷<EFBFBD><D7B7>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
/// <param name="referenceType"><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></param>
/// <param name="count">׷<><D7B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD></param>
public static void Add(Type referenceType, int count)
{
InternalCheckReferenceType(referenceType);
GetReferenceCollection(referenceType).Add(count);
}
/// <summary>
/// <20><><EFBFBD><EFBFBD><EFBFBD>ó<EFBFBD><C3B3><EFBFBD><EFBFBD>Ƴ<EFBFBD>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
/// <typeparam name="T"><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></typeparam>
/// <param name="count"><3E>Ƴ<EFBFBD><C6B3><EFBFBD><EFBFBD><EFBFBD></param>
public static void Remove<T>(int count) where T : class, IReference
{
GetReferenceCollection(typeof(T)).Remove(count);
}
/// <summary>
/// <20><><EFBFBD><EFBFBD><EFBFBD>ó<EFBFBD><C3B3><EFBFBD><EFBFBD>Ƴ<EFBFBD>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
/// <param name="referenceType"><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></param>
/// <param name="count"><3E>Ƴ<EFBFBD><C6B3><EFBFBD><EFBFBD><EFBFBD></param>
public static void Remove(Type referenceType, int count)
{
InternalCheckReferenceType(referenceType);
GetReferenceCollection(referenceType).Remove(count);
}
/// <summary>
/// <20><><EFBFBD><EFBFBD><EFBFBD>ó<EFBFBD><C3B3><EFBFBD><EFBFBD>Ƴ<EFBFBD><C6B3><EFBFBD><EFBFBD>е<EFBFBD><D0B5><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
/// <typeparam name="T"><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></typeparam>
public static void RemoveAll<T>() where T : class, IReference
{
GetReferenceCollection(typeof(T)).RemoveAll();
}
/// <summary>
/// <20><><EFBFBD><EFBFBD><EFBFBD>ó<EFBFBD><C3B3><EFBFBD><EFBFBD>Ƴ<EFBFBD><C6B3><EFBFBD><EFBFBD>е<EFBFBD><D0B5><EFBFBD><EFBFBD>á<EFBFBD>
/// </summary>
/// <param name="referenceType"><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>͡<EFBFBD></param>
public static void RemoveAll(Type referenceType)
{
InternalCheckReferenceType(referenceType);
GetReferenceCollection(referenceType).RemoveAll();
}
}
}

View File

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

View File

@@ -0,0 +1,803 @@
using Convention.Collections;
using Convention.Collections.Generic;
using Convention.ReferenceManagement;
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
namespace Convention.TaskManagement
{
/// <summary>
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
public abstract class TaskBase: IReference
{
/// <summary>
/// <20><><EFBFBD><EFBFBD>Ĭ<EFBFBD><C4AC><EFBFBD><EFBFBD><EFBFBD>ȼ<EFBFBD><C8BC><EFBFBD>
/// </summary>
public const int DefaultPriority = 0;
private int m_SerialId;
private string m_Tag;
private int m_Priority;
private object m_UserData;
private bool m_Done;
/// <summary>
/// <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><CAB5>
/// </summary>
public TaskBase()
{
m_SerialId = 0;
m_Tag = null;
m_Priority = DefaultPriority;
m_Done = false;
m_UserData = null;
}
/// <summary>
/// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD><D0B1><EFBFBD>
/// </summary>
public int SerialId
{
get
{
return m_SerialId;
}
}
/// <summary>
/// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD>ı<EFBFBD>ǩ
/// </summary>
public string Tag
{
get
{
return m_Tag;
}
}
/// <summary>
/// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȼ<EFBFBD>
/// </summary>
public int Priority
{
get
{
return m_Priority;
}
}
/// <summary>
/// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>û<EFBFBD><C3BB>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
public object UserData
{
get
{
return m_UserData;
}
}
/// <summary>
/// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
public bool Done
{
get
{
return m_Done;
}
set
{
m_Done = value;
}
}
/// <summary>
/// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
public virtual string Description
{
get
{
return null;
}
}
/// <summary>
/// <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
/// <param name="serialId"><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD><D0B1><EFBFBD></param>
/// <param name="tag"><3E><><EFBFBD><EFBFBD><EFBFBD>ı<EFBFBD>ǩ</param>
/// <param name="priority"><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȼ<EFBFBD></param>
/// <param name="userData"><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>û<EFBFBD><C3BB>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></param>
internal void Initialize(int serialId, string tag, int priority, object userData)
{
m_SerialId = serialId;
m_Tag = tag;
m_Priority = priority;
m_UserData = userData;
m_Done = false;
}
/// <summary>
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
public virtual void Clear()
{
m_SerialId = 0;
m_Tag = null;
m_Priority = DefaultPriority;
m_UserData = null;
m_Done = false;
}
}
/// <summary>
/// <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>״̬
/// </summary>
public enum StartTaskStatus : byte
{
/// <summary>
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̴<EFBFBD><CCB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɴ<EFBFBD><C9B4><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
Done = 0,
/// <summary>
/// <20><><EFBFBD>Լ<EFBFBD><D4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
CanResume,
/// <summary>
/// <20><><EFBFBD>ܼ<EFBFBD><DCBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȴ<EFBFBD><C8B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ִ<EFBFBD><D6B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
HasToWait,
/// <summary>
/// <20><><EFBFBD>ܼ<EFBFBD><DCBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>񣬳<EFBFBD><F1A3ACB3><EFBFBD>δ֪<CEB4><D6AA><EFBFBD><EFBFBD>
/// </summary>
UnknownError
}
/// <summary>
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӿ<EFBFBD>
/// </summary>
/// <typeparam name="T"><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></typeparam>
public interface ITaskAgent<T> where T : TaskBase
{
/// <summary>
/// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>
/// </summary>
T Task
{
get;
}
/// <summary>
/// <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
void Initialize();
/// <summary>
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѯ
/// </summary>
/// <param name="elapseSeconds"><3E>߼<EFBFBD><DFBC><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><E4A3AC><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA>λ</param>
/// <param name="realElapseSeconds"><3E><>ʵ<EFBFBD><CAB5><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><E4A3AC><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA>λ</param>
void Update(float elapseSeconds, float realElapseSeconds);
/// <summary>
/// <20>رղ<D8B1><D5B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
void Shutdown();
/// <summary>
/// <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
/// <param name="task">Ҫ<><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></param>
/// <returns><3E><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>״̬</returns>
StartTaskStatus Start(T task);
/// <summary>
/// ֹͣ<CDA3><D6B9><EFBFBD>ڴ<EFBFBD><DAB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
void Reset();
}
/// <summary>
/// <20><><EFBFBD><EFBFBD>״̬
/// </summary>
public enum TaskStatus : byte
{
/// <summary>
/// δ<><CEB4>ʼ
/// </summary>
Todo = 0,
/// <summary>
/// ִ<><D6B4><EFBFBD><EFBFBD>
/// </summary>
Doing,
/// <summary>
/// <20><><EFBFBD><EFBFBD>
/// </summary>
Done
}
/// <summary>
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ
/// </summary>
[StructLayout(LayoutKind.Auto)]
public readonly struct TaskInfo
{
private readonly bool m_IsValid;
private readonly int m_SerialId;
private readonly string m_Tag;
private readonly int m_Priority;
private readonly object m_UserData;
private readonly TaskStatus m_Status;
private readonly string m_Description;
/// <summary>
/// <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD>ʵ<EFBFBD><CAB5><EFBFBD><EFBFBD>
/// </summary>
/// <param name="serialId"><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD><D0B1><EFBFBD></param>
/// <param name="tag"><3E><><EFBFBD><EFBFBD><EFBFBD>ı<EFBFBD>ǩ</param>
/// <param name="priority"><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȼ<EFBFBD></param>
/// <param name="userData"><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>û<EFBFBD><C3BB>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></param>
/// <param name="status"><3E><><EFBFBD><EFBFBD>״̬</param>
/// <param name="description"><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></param>
public TaskInfo(int serialId, string tag, int priority, object userData, TaskStatus status, string description)
{
m_IsValid = true;
m_SerialId = serialId;
m_Tag = tag;
m_Priority = priority;
m_UserData = userData;
m_Status = status;
m_Description = description;
}
/// <summary>
/// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD>Ч
/// </summary>
public bool IsValid
{
get
{
return m_IsValid;
}
}
/// <summary>
/// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD><D0B1><EFBFBD>
/// </summary>
public int SerialId
{
get
{
if (!m_IsValid)
{
throw new InvalidOperationException("Data is invalid.");
}
return m_SerialId;
}
}
/// <summary>
/// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD>ı<EFBFBD>ǩ
/// </summary>
public string Tag
{
get
{
if (!m_IsValid)
{
throw new InvalidOperationException("Data is invalid.");
}
return m_Tag;
}
}
/// <summary>
/// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȼ<EFBFBD>
/// </summary>
public int Priority
{
get
{
if (!m_IsValid)
{
throw new InvalidOperationException("Data is invalid.");
}
return m_Priority;
}
}
/// <summary>
/// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>û<EFBFBD><C3BB>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
public object UserData
{
get
{
if (!m_IsValid)
{
throw new InvalidOperationException("Data is invalid.");
}
return m_UserData;
}
}
/// <summary>
/// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>״̬
/// </summary>
public TaskStatus Status
{
get
{
if (!m_IsValid)
{
throw new InvalidOperationException("Data is invalid.");
}
return m_Status;
}
}
/// <summary>
/// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
public string Description
{
get
{
if (!m_IsValid)
{
throw new InvalidOperationException("Data is invalid.");
}
return m_Description;
}
}
}
/// <summary>
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
/// <typeparam name="T"><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></typeparam>
public class TaskPool<T> where T : TaskBase
{
private readonly Stack<ITaskAgent<T>> m_FreeAgents;
private readonly LinkedCacheList<ITaskAgent<T>> m_WorkingAgents;
private readonly LinkedCacheList<T> m_WaitingTasks;
private bool m_Paused;
/// <summary>
/// <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ص<EFBFBD><D8B5><EFBFBD>ʵ<EFBFBD><CAB5><EFBFBD><EFBFBD>
/// </summary>
public TaskPool()
{
m_FreeAgents = new Stack<ITaskAgent<T>>();
m_WorkingAgents = new LinkedCacheList<ITaskAgent<T>>();
m_WaitingTasks = new LinkedCacheList<T>();
m_Paused = false;
}
/// <summary>
/// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD>ͣ<EFBFBD><CDA3>
/// </summary>
public bool Paused
{
get
{
return m_Paused;
}
set
{
m_Paused = value;
}
}
/// <summary>
/// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
public int TotalAgentCount
{
get
{
return FreeAgentCount + WorkingAgentCount;
}
}
/// <summary>
/// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
public int FreeAgentCount
{
get
{
return m_FreeAgents.Count;
}
}
/// <summary>
/// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
public int WorkingAgentCount
{
get
{
return m_WorkingAgents.Count;
}
}
/// <summary>
/// <20><>ȡ<EFBFBD>ȴ<EFBFBD><C8B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
public int WaitingTaskCount
{
get
{
return m_WaitingTasks.Count;
}
}
/// <summary>
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѯ<EFBFBD><D1AF>
/// </summary>
/// <param name="elapseSeconds"><3E>߼<EFBFBD><DFBC><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><E4A3AC><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA>λ<EFBFBD><CEBB></param>
/// <param name="realElapseSeconds"><3E><>ʵ<EFBFBD><CAB5><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><E4A3AC><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA>λ<EFBFBD><CEBB></param>
public void Update(float elapseSeconds, float realElapseSeconds)
{
if (m_Paused)
{
return;
}
ProcessRunningTasks(elapseSeconds, realElapseSeconds);
ProcessWaitingTasks(elapseSeconds, realElapseSeconds);
}
/// <summary>
/// <20>رղ<D8B1><D5B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ء<EFBFBD>
/// </summary>
public void Shutdown()
{
RemoveAllTasks();
while (FreeAgentCount > 0)
{
m_FreeAgents.Pop().Shutdown();
}
}
/// <summary>
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
/// <param name="agent">Ҫ<><D2AA><EFBFBD>ӵ<EFBFBD><D3B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></param>
public void AddAgent(ITaskAgent<T> agent)
{
if (agent == null)
{
throw new InvalidOperationException("Task agent is invalid.");
}
agent.Initialize();
m_FreeAgents.Push(agent);
}
/// <summary>
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD><D0B1>Ż<EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2>
/// </summary>
/// <param name="serialId">Ҫ<><D2AA>ȡ<EFBFBD><C8A1>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD><D0B1>š<EFBFBD></param>
/// <returns><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2></returns>
public TaskInfo GetTaskInfo(int serialId)
{
foreach (ITaskAgent<T> workingAgent in m_WorkingAgents)
{
T workingTask = workingAgent.Task;
if (workingTask.SerialId == serialId)
{
return new TaskInfo(workingTask.SerialId, workingTask.Tag, workingTask.Priority, workingTask.UserData, workingTask.Done ? TaskStatus.Done : TaskStatus.Doing, workingTask.Description);
}
}
foreach (T waitingTask in m_WaitingTasks)
{
if (waitingTask.SerialId == serialId)
{
return new TaskInfo(waitingTask.SerialId, waitingTask.Tag, waitingTask.Priority, waitingTask.UserData, TaskStatus.Todo, waitingTask.Description);
}
}
return default(TaskInfo);
}
/// <summary>
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ı<EFBFBD>ǩ<EFBFBD><C7A9>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2>
/// </summary>
/// <param name="tag">Ҫ<><D2AA>ȡ<EFBFBD><C8A1>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ı<EFBFBD>ǩ<EFBFBD><C7A9></param>
/// <returns><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2></returns>
public TaskInfo[] GetTaskInfos(string tag)
{
List<TaskInfo> results = new List<TaskInfo>();
GetTaskInfos(tag, results);
return results.ToArray();
}
/// <summary>
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ı<EFBFBD>ǩ<EFBFBD><C7A9>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2>
/// </summary>
/// <param name="tag">Ҫ<><D2AA>ȡ<EFBFBD><C8A1>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ı<EFBFBD>ǩ<EFBFBD><C7A9></param>
/// <param name="results"><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2></param>
public void GetTaskInfos(string tag, List<TaskInfo> results)
{
if (results == null)
{
throw new InvalidOperationException("Results is invalid.");
}
results.Clear();
foreach (ITaskAgent<T> workingAgent in m_WorkingAgents)
{
T workingTask = workingAgent.Task;
if (workingTask.Tag == tag)
{
results.Add(new TaskInfo(workingTask.SerialId, workingTask.Tag, workingTask.Priority, workingTask.UserData, workingTask.Done ? TaskStatus.Done : TaskStatus.Doing, workingTask.Description));
}
}
foreach (T waitingTask in m_WaitingTasks)
{
if (waitingTask.Tag == tag)
{
results.Add(new TaskInfo(waitingTask.SerialId, waitingTask.Tag, waitingTask.Priority, waitingTask.UserData, TaskStatus.Todo, waitingTask.Description));
}
}
}
/// <summary>
/// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2>
/// </summary>
/// <returns><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2></returns>
public TaskInfo[] GetAllTaskInfos()
{
int index = 0;
TaskInfo[] results = new TaskInfo[m_WorkingAgents.Count + m_WaitingTasks.Count];
foreach (ITaskAgent<T> workingAgent in m_WorkingAgents)
{
T workingTask = workingAgent.Task;
results[index++] = new TaskInfo(workingTask.SerialId, workingTask.Tag, workingTask.Priority, workingTask.UserData, workingTask.Done ? TaskStatus.Done : TaskStatus.Doing, workingTask.Description);
}
foreach (T waitingTask in m_WaitingTasks)
{
results[index++] = new TaskInfo(waitingTask.SerialId, waitingTask.Tag, waitingTask.Priority, waitingTask.UserData, TaskStatus.Todo, waitingTask.Description);
}
return results;
}
/// <summary>
/// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2>
/// </summary>
/// <param name="results"><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2></param>
public void GetAllTaskInfos(List<TaskInfo> results)
{
if (results == null)
{
throw new InvalidOperationException("Results is invalid.");
}
results.Clear();
foreach (ITaskAgent<T> workingAgent in m_WorkingAgents)
{
T workingTask = workingAgent.Task;
results.Add(new TaskInfo(workingTask.SerialId, workingTask.Tag, workingTask.Priority, workingTask.UserData, workingTask.Done ? TaskStatus.Done : TaskStatus.Doing, workingTask.Description));
}
foreach (T waitingTask in m_WaitingTasks)
{
results.Add(new TaskInfo(waitingTask.SerialId, waitingTask.Tag, waitingTask.Priority, waitingTask.UserData, TaskStatus.Todo, waitingTask.Description));
}
}
/// <summary>
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
/// <param name="task">Ҫ<><D2AA><EFBFBD>ӵ<EFBFBD><D3B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></param>
public void AddTask(T task)
{
LinkedListNode<T> current = m_WaitingTasks.Last;
while (current != null)
{
if (task.Priority <= current.Value.Priority)
{
break;
}
current = current.Previous;
}
if (current != null)
{
m_WaitingTasks.AddAfter(current, task);
}
else
{
m_WaitingTasks.AddFirst(task);
}
}
/// <summary>
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD><D0B1><EFBFBD><EFBFBD>Ƴ<EFBFBD><C6B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
/// <param name="serialId">Ҫ<>Ƴ<EFBFBD><C6B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD><D0B1>š<EFBFBD></param>
/// <returns><3E>Ƿ<EFBFBD><C7B7>Ƴ<EFBFBD><C6B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɹ<EFBFBD><C9B9><EFBFBD></returns>
public bool RemoveTask(int serialId)
{
foreach (T task in m_WaitingTasks)
{
if (task.SerialId == serialId)
{
m_WaitingTasks.Remove(task);
ReferencePool.Release(task);
return true;
}
}
LinkedListNode<ITaskAgent<T>> currentWorkingAgent = m_WorkingAgents.First;
while (currentWorkingAgent != null)
{
LinkedListNode<ITaskAgent<T>> next = currentWorkingAgent.Next;
ITaskAgent<T> workingAgent = currentWorkingAgent.Value;
T task = workingAgent.Task;
if (task.SerialId == serialId)
{
workingAgent.Reset();
m_FreeAgents.Push(workingAgent);
m_WorkingAgents.Remove(currentWorkingAgent);
ReferencePool.Release(task);
return true;
}
currentWorkingAgent = next;
}
return false;
}
/// <summary>
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ı<EFBFBD>ǩ<EFBFBD>Ƴ<EFBFBD><C6B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
/// <param name="tag">Ҫ<>Ƴ<EFBFBD><C6B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ı<EFBFBD>ǩ<EFBFBD><C7A9></param>
/// <returns><3E>Ƴ<EFBFBD><C6B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></returns>
public int RemoveTasks(string tag)
{
int count = 0;
LinkedListNode<T> currentWaitingTask = m_WaitingTasks.First;
while (currentWaitingTask != null)
{
LinkedListNode<T> next = currentWaitingTask.Next;
T task = currentWaitingTask.Value;
if (task.Tag == tag)
{
m_WaitingTasks.Remove(currentWaitingTask);
ReferencePool.Release(task);
count++;
}
currentWaitingTask = next;
}
LinkedListNode<ITaskAgent<T>> currentWorkingAgent = m_WorkingAgents.First;
while (currentWorkingAgent != null)
{
LinkedListNode<ITaskAgent<T>> next = currentWorkingAgent.Next;
ITaskAgent<T> workingAgent = currentWorkingAgent.Value;
T task = workingAgent.Task;
if (task.Tag == tag)
{
workingAgent.Reset();
m_FreeAgents.Push(workingAgent);
m_WorkingAgents.Remove(currentWorkingAgent);
ReferencePool.Release(task);
count++;
}
currentWorkingAgent = next;
}
return count;
}
/// <summary>
/// <20>Ƴ<EFBFBD><C6B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
/// <returns><3E>Ƴ<EFBFBD><C6B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></returns>
public int RemoveAllTasks()
{
int count = m_WaitingTasks.Count + m_WorkingAgents.Count;
foreach (T task in m_WaitingTasks)
{
ReferencePool.Release(task);
}
m_WaitingTasks.Clear();
foreach (ITaskAgent<T> workingAgent in m_WorkingAgents)
{
T task = workingAgent.Task;
workingAgent.Reset();
m_FreeAgents.Push(workingAgent);
ReferencePool.Release(task);
}
m_WorkingAgents.Clear();
return count;
}
private void ProcessRunningTasks(float elapseSeconds, float realElapseSeconds)
{
LinkedListNode<ITaskAgent<T>> current = m_WorkingAgents.First;
while (current != null)
{
T task = current.Value.Task;
if (!task.Done)
{
current.Value.Update(elapseSeconds, realElapseSeconds);
current = current.Next;
continue;
}
LinkedListNode<ITaskAgent<T>> next = current.Next;
current.Value.Reset();
m_FreeAgents.Push(current.Value);
m_WorkingAgents.Remove(current);
ReferencePool.Release(task);
current = next;
}
}
private void ProcessWaitingTasks(float elapseSeconds, float realElapseSeconds)
{
LinkedListNode<T> current = m_WaitingTasks.First;
while (current != null && FreeAgentCount > 0)
{
ITaskAgent<T> agent = m_FreeAgents.Pop();
LinkedListNode<ITaskAgent<T>> agentNode = m_WorkingAgents.AddLast(agent);
T task = current.Value;
LinkedListNode<T> next = current.Next;
StartTaskStatus status = agent.Start(task);
if (status == StartTaskStatus.Done || status == StartTaskStatus.HasToWait || status == StartTaskStatus.UnknownError)
{
agent.Reset();
m_FreeAgents.Push(agent);
m_WorkingAgents.Remove(agentNode);
}
if (status == StartTaskStatus.Done || status == StartTaskStatus.CanResume || status == StartTaskStatus.UnknownError)
{
m_WaitingTasks.Remove(current);
}
if (status == StartTaskStatus.Done || status == StartTaskStatus.UnknownError)
{
ReferencePool.Release(task);
}
current = next;
}
}
}
}

View File

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

View File

@@ -4,7 +4,6 @@ using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Text;
using UnityEngine;
@@ -37,7 +36,7 @@ namespace Convention
}
[Serializable]
public sealed class ToolFile
public class ToolFile
{
public static string[] TextFileExtensions = new string[] { "txt", "ini", "manifest" };
public static string[] AudioFileExtension = new string[] { "ogg", "mp2", "mp3", "mod", "wav", "it" };
@@ -58,24 +57,28 @@ namespace Convention
};
}
private string FullPath;
private string OriginPath;
private FileSystemInfo OriginInfo;
public ToolFile(string path)
{
FullPath = Path.GetFullPath(Environment.ExpandEnvironmentVariables(path));
OriginPath = Environment.ExpandEnvironmentVariables(path).Replace('\\', '/');
Refresh();
}
public override string ToString()
{
return this.FullPath;
return this.OriginPath;
}
#region Path
public static implicit operator string(ToolFile data) => data.FullPath;
public static implicit operator string(ToolFile data) => data.OriginPath;
public string GetAbsPath()
{
return Path.GetFullPath(OriginPath);
}
public string GetFullPath()
{
return this.FullPath;
return this.OriginPath;
}
public string GetName(bool is_ignore_extension = false)
{
@@ -86,13 +89,13 @@ namespace Convention
else if (OriginInfo is DirectoryInfo dinfo)
return dinfo.Name;
}
var result = this.FullPath[..(
(this.FullPath.Contains('.') && is_ignore_extension)
? this.FullPath.LastIndexOf('.')
var result = this.OriginPath[..(
(this.OriginPath.Contains('.') && is_ignore_extension)
? this.OriginPath.LastIndexOf('.')
: ^0
)]
[..(
(this.FullPath[^1] == '/' || this.FullPath[^1] == '\\')
(this.OriginPath[^1] == '/' || this.OriginPath[^1] == '\\')
? ^1
: ^0
)];
@@ -103,32 +106,32 @@ namespace Convention
{
if (IsDir())
return "";
return this.FullPath[(
(this.FullPath.Contains('.'))
? this.FullPath.LastIndexOf('.')
return this.OriginPath[(
(this.OriginPath.Contains('.'))
? this.OriginPath.LastIndexOf('.')
: ^0
)..];
}
public string GetFilename(bool is_without_extension = false)
{
if (is_without_extension && Path.HasExtension(FullPath))
if (is_without_extension && Path.HasExtension(OriginPath))
{
return Path.GetFileNameWithoutExtension(FullPath);
return Path.GetFileNameWithoutExtension(OriginPath);
}
else if (FullPath.EndsWith(Path.DirectorySeparatorChar.ToString()) || FullPath.EndsWith(Path.AltDirectorySeparatorChar.ToString()))
else if (OriginPath.EndsWith(Path.DirectorySeparatorChar.ToString()) || OriginPath.EndsWith(Path.AltDirectorySeparatorChar.ToString()))
{
return Path.GetFileName(FullPath.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar));
return Path.GetFileName(OriginPath.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar));
}
else
{
return Path.GetFileName(FullPath);
return Path.GetFileName(OriginPath);
}
}
public string GetDir()
{
return Path.GetDirectoryName(FullPath);
return Path.GetDirectoryName(OriginPath);
}
public ToolFile GetDirToolFile()
@@ -138,7 +141,7 @@ namespace Convention
public string GetCurrentDirName()
{
return Path.GetDirectoryName(FullPath);
return Path.GetDirectoryName(OriginPath);
}
public ToolFile GetParentDir()
@@ -150,7 +153,7 @@ namespace Convention
#region Exists
public bool Exists() => File.Exists(FullPath) || Directory.Exists(FullPath);
public bool Exists() => File.Exists(OriginPath) || Directory.Exists(OriginPath);
public static implicit operator bool(ToolFile file) => file.Exists();
@@ -162,13 +165,13 @@ namespace Convention
OriginInfo = null;
else if (IsDir())
{
OriginInfo = new DirectoryInfo(FullPath);
FullPath = Path.GetFullPath(FullPath);
OriginInfo = new DirectoryInfo(OriginPath);
OriginPath = Path.GetFullPath(OriginPath);
}
else
{
OriginInfo = new FileInfo(FullPath);
FullPath = Path.GetFullPath(FullPath);
OriginInfo = new FileInfo(OriginPath);
OriginPath = Path.GetFullPath(OriginPath);
}
return this;
}
@@ -181,7 +184,7 @@ namespace Convention
}
public T LoadAsJson<T>(string key = "data")
{
return ES3.Load<T>(key, FullPath);
return ES3.Load<T>(key, OriginPath);
}
public string LoadAsText()
{
@@ -198,18 +201,7 @@ namespace Convention
{
if (IsFile() == false)
throw new InvalidOperationException("Target is not a file");
var file = this.OriginInfo as FileInfo;
const int BlockSize = 1024;
long FileSize = file.Length;
byte[] result = new byte[FileSize];
long offset = 0;
using (var fs = file.OpenRead())
{
fs.ReadAsync(result[(int)(offset)..(int)(offset + BlockSize)], 0, (int)(offset + BlockSize) - (int)(offset));
offset += BlockSize;
offset = System.Math.Min(offset, FileSize);
}
return result;
return File.ReadAllBytes(OriginPath);
}
public List<string[]> LoadAsCsv()
@@ -217,7 +209,7 @@ namespace Convention
if (IsFile() == false)
throw new InvalidOperationException("Target is not a file");
var lines = File.ReadAllLines(FullPath);
var lines = File.ReadAllLines(OriginPath);
var result = new List<string[]>();
foreach (var line in lines)
@@ -244,11 +236,11 @@ namespace Convention
public Texture2D LoadAsImage()
{
return ES3Plugin.LoadImage(FullPath);
return ES3Plugin.LoadImage(OriginPath);
}
public IEnumerator LoadAsImage([In] Action<Texture2D> callback)
{
UnityWebRequest request = UnityWebRequestTexture.GetTexture(FullPath);
UnityWebRequest request = UnityWebRequestTexture.GetTexture(OriginPath);
yield return request.SendWebRequest();
if (request.result == UnityWebRequest.Result.Success)
@@ -259,11 +251,11 @@ namespace Convention
}
public AudioClip LoadAsAudio()
{
return ES3Plugin.LoadAudio(FullPath, GetAudioType(FullPath));
return ES3Plugin.LoadAudio(OriginPath, GetAudioType(OriginPath));
}
public IEnumerator LoadAsAudio([In] Action<AudioClip> callback)
{
UnityWebRequest request = UnityWebRequestMultimedia.GetAudioClip(FullPath, GetAudioType(FullPath));
UnityWebRequest request = UnityWebRequestMultimedia.GetAudioClip(OriginPath, GetAudioType(OriginPath));
yield return request.SendWebRequest();
if (request.result == UnityWebRequest.Result.Success)
@@ -274,18 +266,18 @@ namespace Convention
}
public AssetBundle LoadAsAssetBundle()
{
return AssetBundle.LoadFromFile(FullPath);
return AssetBundle.LoadFromFile(OriginPath);
}
public IEnumerator LoadAsAssetBundle([In] Action<AssetBundle> callback)
{
AssetBundleCreateRequest result = AssetBundle.LoadFromFileAsync(FullPath);
AssetBundleCreateRequest result = AssetBundle.LoadFromFileAsync(OriginPath);
yield return result;
callback(result.assetBundle);
yield return null;
}
public IEnumerator LoadAsAssetBundle([In]Action<float> progress, [In] Action<AssetBundle> callback)
public IEnumerator LoadAsAssetBundle([In] Action<float> progress, [In] Action<AssetBundle> callback)
{
AssetBundleCreateRequest result = AssetBundle.LoadFromFileAsync(FullPath);
AssetBundleCreateRequest result = AssetBundle.LoadFromFileAsync(OriginPath);
while (result.isDone == false)
{
progress(result.progress);
@@ -311,11 +303,11 @@ namespace Convention
}
public void SaveAsJson<T>(T data, string key = "data")
{
ES3.Save(key, data,FullPath);
ES3.Save(key, data, OriginPath);
}
public void SaveAsText(string data)
{
using var fs = new FileStream(FullPath, FileMode.CreateNew, FileAccess.Write);
using var fs = new FileStream(OriginPath, FileMode.Create, FileAccess.Write);
using var sw = new StreamWriter(fs);
sw.Write(data);
sw.Flush();
@@ -329,7 +321,7 @@ namespace Convention
}
else
{
using var fs = new FileStream(path, FileMode.CreateNew, FileAccess.Write);
using var fs = new FileStream(path, FileMode.Create, FileAccess.Write);
fs.Write(outdata, 0, outdata.Length);
fs.Flush();
}
@@ -337,7 +329,8 @@ namespace Convention
public void SaveAsBinary(byte[] data)
{
SaveDataAsBinary(FullPath, data, (OriginInfo as FileInfo).OpenWrite());
using var fs = (OriginInfo as FileInfo).OpenWrite();
SaveDataAsBinary(OriginPath, data, fs);
}
public void SaveAsCsv(List<string[]> csvData)
@@ -346,7 +339,7 @@ namespace Convention
throw new InvalidOperationException("Target is not a file");
var lines = csvData.Select(row => string.Join(",", row));
File.WriteAllLines(FullPath, lines);
File.WriteAllLines(OriginPath, lines);
}
public void SaveAsXml(string xmlData)
@@ -380,9 +373,9 @@ namespace Convention
{
if (Exists())
{
return Directory.Exists(this.FullPath);
return Directory.Exists(this.OriginPath);
}
return this.FullPath[^1] == '\\' || this.FullPath[^1] == '/';
return this.OriginPath[^1] == '\\' || this.OriginPath[^1] == '/';
}
public bool IsFile()
@@ -420,7 +413,7 @@ namespace Convention
{
if (IsDir())
{
return GetDirectorySize(FullPath);
return GetDirectorySize(OriginPath);
}
else
{
@@ -457,29 +450,38 @@ namespace Convention
#region Operator
public static ToolFile operator |(ToolFile left, string rightPath)
public static ToolFile operator |(ToolFile left, [Opt] string rightPath)
{
string lp = left.GetFullPath();
return new ToolFile(Path.Combine(lp, rightPath));
if (rightPath == null)
{
return new ToolFile(left.IsDir() ? left.GetFullPath() : $"{left.GetFullPath().Replace('\\', '/')}/");
}
string first = left.GetFullPath().Replace('\\', '/');
string second = rightPath.Replace('\\', '/');
if (first == "./")
return new ToolFile(second);
else if (first == "../")
return new ToolFile($"{new ToolFile(left.GetAbsPath()).GetParentDir()}/{second}");
return new ToolFile($"{first}{(first.EndsWith('/') ? "" : "/")}{second}");
}
public override bool Equals(object obj)
{
if (obj is ToolFile other)
{
return Path.GetFullPath(FullPath).Equals(Path.GetFullPath(other.FullPath), StringComparison.OrdinalIgnoreCase);
return Path.GetFullPath(OriginPath).Equals(Path.GetFullPath(other.OriginPath), StringComparison.OrdinalIgnoreCase);
}
return false;
}
public override int GetHashCode()
{
return Path.GetFullPath(FullPath).GetHashCode();
return Path.GetFullPath(OriginPath).GetHashCode();
}
public ToolFile Open(string path)
{
this.FullPath = path;
this.OriginPath = path;
Refresh();
return this;
}
@@ -492,16 +494,16 @@ namespace Convention
if (Exists() == false)
{
if (IsDir())
Directory.CreateDirectory(this.FullPath);
Directory.CreateDirectory(this.OriginPath);
else
File.Create(this.FullPath).Close();
File.Create(this.OriginPath).Close();
Refresh();
}
return this;
}
public ToolFile Rename(string newPath)
{
if(IsDir())
if (IsDir())
{
var dir = OriginInfo as DirectoryInfo;
dir.MoveTo(newPath);
@@ -511,7 +513,7 @@ namespace Convention
var file = OriginInfo as FileInfo;
file.MoveTo(newPath);
}
FullPath = newPath;
OriginPath = newPath;
return this;
}
public ToolFile Move(string path)
@@ -519,7 +521,7 @@ namespace Convention
Rename(path);
return this;
}
public ToolFile Copy(string path,out ToolFile copyTo)
public ToolFile Copy(string path, out ToolFile copyTo)
{
if (IsDir())
{
@@ -537,7 +539,7 @@ namespace Convention
public ToolFile Copy(string targetPath = null)
{
if (targetPath == null)
return new ToolFile(FullPath);
return new ToolFile(OriginPath);
if (!Exists())
throw new FileNotFoundException("File not found");
@@ -547,9 +549,9 @@ namespace Convention
targetFile = targetFile | GetFilename();
if (IsDir())
CopyDirectory(FullPath, targetFile.GetFullPath());
CopyDirectory(OriginPath, targetFile.GetFullPath());
else
File.Copy(FullPath, targetFile.GetFullPath());
File.Copy(OriginPath, targetFile.GetFullPath());
return targetFile;
}
@@ -575,9 +577,9 @@ namespace Convention
public ToolFile Delete()
{
if (IsDir())
Directory.Delete(FullPath);
Directory.Delete(OriginPath);
else
File.Delete(FullPath);
File.Delete(OriginPath);
return this;
}
@@ -598,7 +600,7 @@ namespace Convention
}
public ToolFile TryCreateParentPath()
{
string dirPath = Path.GetDirectoryName(FullPath);
string dirPath = Path.GetDirectoryName(OriginPath);
if (!string.IsNullOrEmpty(dirPath) && !Directory.Exists(dirPath))
{
Directory.CreateDirectory(dirPath);
@@ -609,14 +611,14 @@ namespace Convention
{
if (!IsDir())
throw new InvalidOperationException("Target is not a directory");
return Directory.GetFileSystemEntries(FullPath).ToList();
return Directory.GetFileSystemEntries(OriginPath).ToList();
}
public List<ToolFile> DirToolFileIter()
{
if (!IsDir())
throw new InvalidOperationException("Target is not a directory");
var result = new List<ToolFile>();
foreach (var entry in Directory.GetFileSystemEntries(FullPath))
foreach (var entry in Directory.GetFileSystemEntries(OriginPath))
{
result.Add(new ToolFile(entry));
}
@@ -624,7 +626,7 @@ namespace Convention
}
public ToolFile BackToParentDir()
{
FullPath = GetDir();
OriginPath = GetDir();
Refresh();
return this;
}
@@ -633,7 +635,7 @@ namespace Convention
if (!IsDir())
throw new InvalidOperationException("Target is not a directory");
var entries = Directory.GetFileSystemEntries(FullPath);
var entries = Directory.GetFileSystemEntries(OriginPath);
if (ignore_folder)
{
return entries.Count(entry => File.Exists(entry));
@@ -740,13 +742,13 @@ namespace Convention
{
if (IsDir())
{
ZipFile.CreateFromDirectory(FullPath, outputPath);
ZipFile.CreateFromDirectory(OriginPath, outputPath);
}
else
{
using (var archive = ZipFile.Open(outputPath, ZipArchiveMode.Create))
{
archive.CreateEntryFromFile(FullPath, GetFilename());
archive.CreateEntryFromFile(OriginPath, GetFilename());
}
}
}
@@ -778,7 +780,7 @@ namespace Convention
try
{
ZipFile.ExtractToDirectory(FullPath, outputPath);
ZipFile.ExtractToDirectory(OriginPath, outputPath);
return new ToolFile(outputPath);
}
catch (Exception ex)
@@ -897,7 +899,7 @@ namespace Convention
try
{
using (var hashAlgorithm = GetHashAlgorithm(algorithm))
using (var stream = File.OpenRead(FullPath))
using (var stream = File.OpenRead(OriginPath))
{
byte[] hash = hashAlgorithm.ComputeHash(stream);
return BitConverter.ToString(hash).Replace("-", "").ToLower();
@@ -955,7 +957,7 @@ namespace Convention
// 注意:这是一个简化实现,实际的文件监控需要更复杂的实现
// 可以使用 FileSystemWatcher 来实现完整功能
var watcher = new FileSystemWatcher(FullPath)
var watcher = new FileSystemWatcher(OriginPath)
{
IncludeSubdirectories = recursive,
EnableRaisingEvents = true
@@ -1087,7 +1089,7 @@ namespace Convention
try
{
var fileInfo = new FileInfo(FullPath);
var fileInfo = new FileInfo(OriginPath);
var attributes = fileInfo.Attributes;
permissions["read"] = true; // 如果能获取到文件信息,说明可读
@@ -1114,7 +1116,7 @@ namespace Convention
try
{
var fileInfo = new FileInfo(FullPath);
var fileInfo = new FileInfo(OriginPath);
var attributes = fileInfo.Attributes;
if (write.HasValue)
@@ -1216,15 +1218,15 @@ namespace Convention
}
public static string[] SelectMultipleFiles(string filter = "所有文件|*.*", string title = "选择文件")
{
return PluginExtenion.SelectMultipleFiles(filter,title);
return PluginExtenion.SelectMultipleFiles(filter, title);
}
public static string SelectFile(string filter = "所有文件|*.*", string title = "选择文件")
{
return PluginExtenion.SelectFile(filter,title);
return PluginExtenion.SelectFile(filter, title);
}
public static string SaveFile(string filter = "所有文件|*.*", string title = "保存文件")
{
return PluginExtenion.SaveFile(filter,title);
return PluginExtenion.SaveFile(filter, title);
}
public static string SelectFolder(string description = "请选择文件夹")
{
@@ -1247,4 +1249,23 @@ namespace Convention
#endregion
}
[Serializable]
public class MustExistFile : ToolFile
{
public MustExistFile(string path) : base(path)
{
MustExistsPath();
}
}
[Serializable]
public class DependentFile : ToolFile
{
public DependentFile(string path) : base(path)
{
if (Exists() == false)
throw new FileNotFoundException($"Dependent file not found: {path}");
}
}
}

View File

@@ -5,9 +5,10 @@ using UnityEngine;
namespace Convention
{
[Serializable]
public class GlobalConfig : IEnumerable<KeyValuePair<string, object>>
{
public static string ConstConfigFile = "config.json";
public static string ConstConfigFile = "config.easysave";
public static void InitExtensionEnv()
{
@@ -18,7 +19,7 @@ namespace Convention
private int configLogging_tspace = "Property not found".Length;
private ToolFile DataDir;
private Dictionary<string, object> data_pair = new();
[Content, SerializeField] private Dictionary<string, object> data_pair = new();
public GlobalConfig(string dataDir, bool isTryCreateDataDir = false, bool isLoad = true)
: this(new ToolFile(dataDir), isTryCreateDataDir, isLoad) { }
@@ -124,10 +125,10 @@ namespace Convention
public int DataSize() => data_pair.Count;
[Serializable]
public class InternalProperty
public struct InternalProperty
{
public Dictionary<string, object> property = new();
public Dictionary<string, object> find = new();
public Dictionary<string, object> property;
public Dictionary<string, object> find;
}
public GlobalConfig SaveProperties()

View File

@@ -0,0 +1,679 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.Networking;
namespace Convention
{
/// <summary>
/// 统一的文件交互类支持本地文件、网络文件和localhost路径的自适应处理
/// 使用UnityWebRequest实现跨平台兼容支持WebGL和IL2CPP
///
/// <list type="bullet"><see cref="ToolFile"/>是依赖项</list>
/// </summary>
[Serializable]
public sealed class Interaction
{
#region Fields and Properties
private string originalPath;
private string processedPath;
private PathType pathType;
private object cachedData;
public string OriginalPath => originalPath;
public string ProcessedPath => processedPath;
public PathType Type => pathType;
public enum PathType
{
LocalFile, // 本地文件 (file://)
NetworkHTTP, // 网络HTTP (http://)
NetworkHTTPS, // 网络HTTPS (https://)
LocalServer, // 本地服务器 (localhost)
StreamingAssets // StreamingAssets目录
}
#endregion
public Interaction(string path)
{
SetPath(path);
}
#region Setup
/// <summary>
/// 设置并处理路径
/// </summary>
public Interaction SetPath(string path)
{
originalPath = path;
processedPath = ProcessPath(path);
pathType = DeterminePathType(path);
return this;
}
/// <summary>
/// 处理路径转换为UnityWebRequest可识别的格式
/// </summary>
private string ProcessPath(string path)
{
if (string.IsNullOrEmpty(path))
return path;
// 网络路径直接返回
if (path.StartsWith("http://") || path.StartsWith("https://"))
{
return path;
}
// localhost处理
if (path.StartsWith("localhost"))
{
return path.StartsWith("localhost/") ? "http://" + path : "http://localhost/" + path;
}
// StreamingAssets路径处理
if (path.StartsWith("StreamingAssets/") || path.StartsWith("StreamingAssets\\"))
{
return Path.Combine(Application.streamingAssetsPath, path.Substring(16)).Replace("\\", "/");
}
// 本地文件路径处理
string fullPath = Path.IsPathRooted(path) ? path : Path.GetFullPath(path);
// WebGL平台特殊处理
if (Application.platform == RuntimePlatform.WebGLPlayer)
{
// WebGL只能访问StreamingAssets尝试构建StreamingAssets路径
return Application.streamingAssetsPath + "/" + Path.GetFileName(fullPath);
}
// 其他平台使用file://协议
return "file:///" + fullPath.Replace("\\", "/");
}
/// <summary>
/// 确定路径类型
/// </summary>
private PathType DeterminePathType(string path)
{
if (string.IsNullOrEmpty(path))
return PathType.LocalFile;
if (path.StartsWith("https://"))
return PathType.NetworkHTTPS;
if (path.StartsWith("http://"))
return PathType.NetworkHTTP;
if (path.StartsWith("localhost"))
return PathType.LocalServer;
if (path.StartsWith("StreamingAssets"))
return PathType.StreamingAssets;
return PathType.LocalFile;
}
#endregion
#region Load
#region LoadAsync
public IEnumerator LoadAsTextAsync(Action<string> onSuccess, Action<string> onError = null)
{
using UnityWebRequest request = UnityWebRequest.Get(processedPath);
yield return request.SendWebRequest();
if (request.result == UnityWebRequest.Result.Success)
{
cachedData = request.downloadHandler.text;
onSuccess?.Invoke((string)cachedData);
}
else
{
string errorMsg = $"Failed to load text from {originalPath}: {request.error}";
onError?.Invoke(errorMsg);
}
}
public IEnumerator LoadAsBinaryAsync(Action<byte[]> onSuccess, Action<string> onError = null)
{
using UnityWebRequest request = UnityWebRequest.Get(processedPath);
yield return request.SendWebRequest();
if (request.result == UnityWebRequest.Result.Success)
{
cachedData = request.downloadHandler.data;
onSuccess?.Invoke((byte[])cachedData);
}
else
{
string errorMsg = $"Failed to load binary from {originalPath}: {request.error}";
onError?.Invoke(errorMsg);
}
}
public IEnumerator LoadAsBinaryAsync(Action<float> progress, Action<byte[]> onSuccess, Action<string> onError = null)
{
using UnityWebRequest request = UnityWebRequest.Get(processedPath);
var result = request.SendWebRequest();
while (result.isDone == false)
{
progress(result.progress);
yield return null;
}
if (request.result == UnityWebRequest.Result.Success)
{
cachedData = request.downloadHandler.data;
onSuccess?.Invoke((byte[])cachedData);
}
else
{
string errorMsg = $"Failed to load binary from {originalPath}: {request.error}";
onError?.Invoke(errorMsg);
}
}
public IEnumerator LoadAsRawJsonAsync<T>(Action<T> onSuccess, Action<string> onError = null)
{
yield return LoadAsTextAsync(
text =>
{
try
{
T result = JsonUtility.FromJson<T>(text);
cachedData = result;
onSuccess?.Invoke(result);
}
catch (Exception e)
{
onError?.Invoke($"Failed to parse JSON: {e.Message}");
}
},
onError
);
}
public IEnumerator LoadAsJsonAsync<T>(Action<T> onSuccess, Action<string> onError = null)
{
yield return LoadAsTextAsync(
text =>
{
try
{
using StreamReader reader = new(new MemoryStream(System.Text.Encoding.UTF8.GetBytes(text)));
var jsonReader = new ES3Internal.ES3JSONReader(reader.BaseStream, new(originalPath));
onSuccess?.Invoke(jsonReader.Read<T>());
}
catch (Exception e)
{
onError?.Invoke($"Failed to parse JSON: {e.Message}");
}
},
onError
);
}
public IEnumerator LoadAsImageAsync(Action<Texture2D> onSuccess, Action<string> onError = null)
{
using (UnityWebRequest request = UnityWebRequestTexture.GetTexture(processedPath))
{
yield return request.SendWebRequest();
if (request.result == UnityWebRequest.Result.Success)
{
Texture2D texture = DownloadHandlerTexture.GetContent(request);
cachedData = texture;
onSuccess?.Invoke(texture);
}
else
{
string errorMsg = $"Failed to load image from {originalPath}: {request.error}";
onError?.Invoke(errorMsg);
}
}
}
public IEnumerator LoadAsAudioAsync(Action<AudioClip> onSuccess, Action<string> onError = null, AudioType audioType = AudioType.UNKNOWN)
{
if (audioType == AudioType.UNKNOWN)
audioType = GetAudioType(originalPath);
using (UnityWebRequest request = UnityWebRequestMultimedia.GetAudioClip(processedPath, audioType))
{
yield return request.SendWebRequest();
if (request.result == UnityWebRequest.Result.Success)
{
AudioClip audioClip = DownloadHandlerAudioClip.GetContent(request);
cachedData = audioClip;
onSuccess?.Invoke(audioClip);
}
else
{
string errorMsg = $"Failed to load audio from {originalPath}: {request.error}";
onError?.Invoke(errorMsg);
}
}
}
public IEnumerator LoadAsAssetBundle(Action<float> progress, Action<AssetBundle> onSuccess, Action<string> onError = null)
{
AssetBundleCreateRequest request = null;
yield return LoadAsBinaryAsync(x => progress(x * 0.5f), data => request = AssetBundle.LoadFromMemoryAsync(data), onError);
while (request.isDone == false)
{
progress(0.5f + request.progress * 0.5f);
yield return null;
}
try
{
AssetBundle bundle = request.assetBundle;
if (bundle != null)
{
cachedData = bundle;
onSuccess?.Invoke(bundle);
}
else
{
onError?.Invoke($"Failed to load AssetBundle from data.");
}
}
catch (Exception e)
{
onError?.Invoke($"Failed to load AssetBundle: {e.Message}");
}
}
#endregion
#region Load Sync
public string LoadAsText()
{
string buffer = null;
bool isEnd = false;
bool IsError = false;
var it = LoadAsTextAsync(x =>
{
buffer = x;
isEnd = true;
}, e =>
{
IsError = true;
throw new Exception(e);
});
try
{
while (!isEnd)
{
it.MoveNext();
}
}
catch
{
if(IsError)
{
throw;
}
}
return buffer;
}
public byte[] LoadAsBinary()
{
byte[] buffer = null;
bool isEnd = false;
bool IsError = false;
var it = LoadAsBinaryAsync(x =>
{
buffer = x;
isEnd = true;
}, e =>
{
IsError = true;
throw new Exception(e);
});
try
{
while (!isEnd)
{
it.MoveNext();
}
}
catch
{
if (IsError)
{
throw;
}
}
return buffer;
}
public T LoadAsRawJson<T>()
{
T buffer = default;
bool isEnd = false;
bool IsError = false;
var it = LoadAsRawJsonAsync<T>(x =>
{
buffer = x;
isEnd = true;
}, e =>
{
IsError = true;
throw new Exception(e);
});
try
{
while (!isEnd)
{
it.MoveNext();
}
}
catch
{
if (IsError)
{
throw;
}
}
return buffer;
}
public T LoadAsJson<T>()
{
T buffer = default;
bool isEnd = false;
bool IsError = false;
var it = LoadAsJsonAsync<T>(x =>
{
buffer = x;
isEnd = true;
}, e =>
{
IsError = true;
throw new Exception(e);
});
try
{
while (!isEnd)
{
it.MoveNext();
}
}
catch
{
if (IsError)
{
throw;
}
}
return buffer;
}
public Texture2D LoadAsImage()
{
Texture2D buffer = null;
bool isEnd = false;
bool IsError = false;
var it = LoadAsImageAsync(x =>
{
buffer = x;
isEnd = true;
}, e =>
{
IsError = true;
throw new Exception(e);
});
try
{
while (!isEnd)
{
it.MoveNext();
}
}
catch
{
if (IsError)
{
throw;
}
}
return buffer;
}
public AudioClip LoadAsAudio(AudioType audioType = AudioType.UNKNOWN)
{
AudioClip buffer = null;
bool isEnd = false;
bool IsError = false;
var it = LoadAsAudioAsync(x =>
{
buffer = x;
isEnd = true;
}, e =>
{
IsError = true;
throw new Exception(e);
}, audioType);
try
{
while (!isEnd)
{
it.MoveNext();
}
}
catch
{
if (IsError)
{
throw;
}
}
return buffer;
}
#endregion
#endregion
#region Save
public Interaction SaveAsText(string content)
{
if (Application.platform == RuntimePlatform.WebGLPlayer)
{
throw new NotSupportedException("WebGL平台不支持文件保存。");
}
if (pathType != PathType.LocalFile)
{
throw new NotSupportedException("仅支持保存到本地文件路径。");
}
new ToolFile(originalPath).SaveAsText(content);
return this;
}
public Interaction SaveAsBinary(byte[] data)
{
if (Application.platform == RuntimePlatform.WebGLPlayer)
{
throw new NotSupportedException("WebGL平台不支持文件保存。");
}
if (pathType != PathType.LocalFile)
{
throw new NotSupportedException("仅支持保存到本地文件路径。");
}
new ToolFile(originalPath).SaveAsBinary(data);
return this;
}
public Interaction SaveAsRawJson<T>(T obj)
{
new ToolFile(originalPath).SaveAsRawJson(obj);
return this;
}
public Interaction SaveAsJson<T>(T obj)
{
new ToolFile(originalPath).SaveAsJson(obj);
return this;
}
#endregion
#region Tools
/// <summary>
/// 获取本地文件路径
/// </summary>
private string GetLocalPath()
{
if (processedPath.StartsWith("file:///"))
{
return processedPath.Substring(8);
}
return originalPath;
}
/// <summary>
/// 根据文件扩展名获取音频类型
/// </summary>
private AudioType GetAudioType(string path)
{
return BasicAudioSystem.GetAudioType(path);
}
/// <summary>
/// 检查文件是否存在
/// </summary>
public bool Exists()
{
if (pathType == PathType.LocalFile && Application.platform != RuntimePlatform.WebGLPlayer)
{
return File.Exists(GetLocalPath());
}
else
{
// TODO : 网络文件和WebGL平台需要通过请求检查
// 当前默认存在
return true;
}
}
/// <summary>
/// 异步检查文件是否存在
/// </summary>
public IEnumerator ExistsAsync(Action<bool> callback)
{
using UnityWebRequest request = UnityWebRequest.Head(processedPath);
yield return request.SendWebRequest();
callback?.Invoke(request.result == UnityWebRequest.Result.Success);
}
#endregion
#region Operator
public static implicit operator string(Interaction interaction) => interaction?.originalPath;
public override string ToString() => originalPath;
/// <summary>
/// 路径连接操作符
/// </summary>
public static Interaction operator |(Interaction left, string rightPath)
{
if (left.pathType == PathType.NetworkHTTP || left.pathType == PathType.NetworkHTTPS || left.pathType == PathType.LocalServer)
{
string baseUrl = left.originalPath;
string newUrl = baseUrl.EndsWith("/") ? baseUrl + rightPath : baseUrl + "/" + rightPath;
return new Interaction(newUrl);
}
else
{
string newPath = Path.Combine(left.originalPath, rightPath);
return new Interaction(newPath);
}
}
#endregion
#region Tools
/// <summary>
/// 获取文件名
/// </summary>
public string GetFilename()
{
if (pathType == PathType.NetworkHTTP || pathType == PathType.NetworkHTTPS || pathType == PathType.LocalServer)
{
var uri = new Uri(processedPath);
return Path.GetFileName(uri.AbsolutePath);
}
return Path.GetFileName(originalPath);
}
/// <summary>
/// 获取文件扩展名
/// </summary>
public string GetExtension()
{
return Path.GetExtension(GetFilename());
}
/// <summary>
/// 检查扩展名
/// </summary>
public bool ExtensionIs(params string[] extensions)
{
string ext = GetExtension().ToLower();
string extWithoutDot = ext.Length > 1 ? ext[1..] : "";
foreach (string extension in extensions)
{
string checkExt = extension.ToLower();
if (ext == checkExt || extWithoutDot == checkExt || ext == "." + checkExt)
return true;
}
return false;
}
#endregion
#region Tools
/// <summary>
/// 创建一个新的Interaction实例
/// </summary>
public static Interaction Create(string path) => new(path);
/// <summary>
/// 从StreamingAssets创建
/// </summary>
public static Interaction FromStreamingAssets(string relativePath)
{
return new Interaction("StreamingAssets/" + relativePath);
}
/// <summary>
/// 从本地服务器创建
/// </summary>
public static Interaction FromLocalhost(string path, int port = 80)
{
string url = port == 80 ? $"localhost/{path}" : $"localhost:{port}/{path}";
return new Interaction(url);
}
#endregion
}
}

View File

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

View File

@@ -1,14 +1,15 @@
using System;
using System.Collections;
using System.Collections.Generic;
using Unity.Burst;
using UnityEngine;
#if UNITY_URP
using static Unity.Mathematics.math;
#endif
using static Convention.MathExtension;
namespace Convention
{
[BurstCompile]
public static partial class MathExtension
{
#region EaseCurve
@@ -105,6 +106,7 @@ namespace Convention
};
}
[BurstCompile]
public static float Linear(float from, float to, float t)
{
float c = to - from;
@@ -112,6 +114,7 @@ namespace Convention
return c * t / 1f + from;
}
[BurstCompile]
public static float InQuad(float from, float to, float t)
{
float c = to - from;
@@ -119,6 +122,7 @@ namespace Convention
return c * t * t + from;
}
[BurstCompile]
public static float OutQuad(float from, float to, float t)
{
float c = to - from;
@@ -126,6 +130,7 @@ namespace Convention
return -c * t * (t - 2f) + from;
}
[BurstCompile]
public static float InOutQuad(float from, float to, float t)
{
float c = to - from;
@@ -135,6 +140,7 @@ namespace Convention
return -c / 2f * (t * (t - 2) - 1) + from;
}
[BurstCompile]
public static float InCubic(float from, float to, float t)
{
float c = to - from;
@@ -142,6 +148,7 @@ namespace Convention
return c * t * t * t + from;
}
[BurstCompile]
public static float OutCubic(float from, float to, float t)
{
float c = to - from;
@@ -150,6 +157,7 @@ namespace Convention
return c * (t * t * t + 1) + from;
}
[BurstCompile]
public static float InOutCubic(float from, float to, float t)
{
float c = to - from;
@@ -159,6 +167,7 @@ namespace Convention
return c / 2f * (t * t * t + 2) + from;
}
[BurstCompile]
public static float InQuart(float from, float to, float t)
{
float c = to - from;
@@ -166,6 +175,7 @@ namespace Convention
return c * t * t * t * t + from;
}
[BurstCompile]
public static float OutQuart(float from, float to, float t)
{
float c = to - from;
@@ -174,6 +184,7 @@ namespace Convention
return -c * (t * t * t * t - 1) + from;
}
[BurstCompile]
public static float InOutQuart(float from, float to, float t)
{
float c = to - from;
@@ -183,6 +194,7 @@ namespace Convention
return -c / 2f * (t * t * t * t - 2) + from;
}
[BurstCompile]
public static float InQuint(float from, float to, float t)
{
float c = to - from;
@@ -190,6 +202,7 @@ namespace Convention
return c * t * t * t * t * t + from;
}
[BurstCompile]
public static float OutQuint(float from, float to, float t)
{
float c = to - from;
@@ -198,6 +211,7 @@ namespace Convention
return c * (t * t * t * t * t + 1) + from;
}
[BurstCompile]
public static float InOutQuint(float from, float to, float t)
{
float c = to - from;
@@ -207,36 +221,42 @@ namespace Convention
return c / 2f * (t * t * t * t * t + 2) + from;
}
[BurstCompile]
public static float InSine(float from, float to, float t)
{
float c = to - from;
return -c * Mathf.Cos(t / 1f * (Mathf.PI / 2f)) + c + from;
}
[BurstCompile]
public static float OutSine(float from, float to, float t)
{
float c = to - from;
return c * Mathf.Sin(t / 1f * (Mathf.PI / 2f)) + from;
}
[BurstCompile]
public static float InOutSine(float from, float to, float t)
{
float c = to - from;
return -c / 2f * (Mathf.Cos(Mathf.PI * t / 1f) - 1) + from;
}
[BurstCompile]
public static float InExpo(float from, float to, float t)
{
float c = to - from;
return c * Mathf.Pow(2, 10 * (t / 1f - 1)) + from;
}
[BurstCompile]
public static float OutExpo(float from, float to, float t)
{
float c = to - from;
return c * (-Mathf.Pow(2, -10 * t / 1f) + 1) + from;
}
[BurstCompile]
public static float InOutExpo(float from, float to, float t)
{
float c = to - from;
@@ -246,6 +266,7 @@ namespace Convention
return c / 2f * (-Mathf.Pow(2, -10 * t) + 2) + from;
}
[BurstCompile]
public static float InCirc(float from, float to, float t)
{
float c = to - from;
@@ -253,6 +274,7 @@ namespace Convention
return -c * (Mathf.Sqrt(1 - t * t) - 1) + from;
}
[BurstCompile]
public static float OutCirc(float from, float to, float t)
{
float c = to - from;
@@ -261,6 +283,7 @@ namespace Convention
return c * Mathf.Sqrt(1 - t * t) + from;
}
[BurstCompile]
public static float InOutCirc(float from, float to, float t)
{
float c = to - from;
@@ -270,12 +293,14 @@ namespace Convention
return c / 2f * (Mathf.Sqrt(1 - t * t) + 1) + from;
}
[BurstCompile]
public static float InBounce(float from, float to, float t)
{
float c = to - from;
return c - OutBounce(0f, c, 1f - t) + from; //does this work?
}
[BurstCompile]
public static float OutBounce(float from, float to, float t)
{
float c = to - from;
@@ -298,6 +323,7 @@ namespace Convention
}
}
[BurstCompile]
public static float InOutBounce(float from, float to, float t)
{
float c = to - from;
@@ -306,6 +332,7 @@ namespace Convention
}
[BurstCompile]
public static float InElastic(float from, float to, float t)
{
float c = to - from;
@@ -316,6 +343,7 @@ namespace Convention
return -(c * Mathf.Pow(2, 10 * (t -= 1)) * Mathf.Sin((t - s) * (2 * Mathf.PI) / p)) + from;
}
[BurstCompile]
public static float OutElastic(float from, float to, float t)
{
float c = to - from;
@@ -326,6 +354,7 @@ namespace Convention
return (c * Mathf.Pow(2, -10 * t) * Mathf.Sin((t - s) * (2 * Mathf.PI) / p) + c + from);
}
[BurstCompile]
public static float InOutElastic(float from, float to, float t)
{
float c = to - from;
@@ -338,6 +367,7 @@ namespace Convention
return c * Mathf.Pow(2, -10 * (t -= 1)) * Mathf.Sin((t - s) * (2f * Mathf.PI) / p) * 0.5f + c + from;
}
[BurstCompile]
public static float InBack(float from, float to, float t)
{
float c = to - from;
@@ -346,6 +376,7 @@ namespace Convention
return c * t * t * ((s + 1) * t - s) + from;
}
[BurstCompile]
public static float OutBack(float from, float to, float t)
{
float c = to - from;
@@ -354,6 +385,7 @@ namespace Convention
return c * (t * t * ((s + 1) * t + s) + 1) + from;
}
[BurstCompile]
public static float InOutBack(float from, float to, float t)
{
float c = to - from;

View File

@@ -2,7 +2,11 @@ using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
#if UNITY_6000_0_OR_NEWER
using Unity.Cinemachine;
#else
using Cinemachine;
#endif
using System.Linq;
using UnityEngine.UI;

View File

@@ -118,6 +118,14 @@ namespace Convention.WindowsUI.Variant
dropdownImage.eulerAngles = new(0, 0, 0);
}
public virtual void RefreshChilds()
{
ConventionUtility.CreateSteps()
.Next(() => Switch())
.Next(() => Switch())
.Invoke();
}
public List<ItemEntry> CreateSubPropertyItem([In] PropertiesWindow propertyWindow, int count)
{
List<ItemEntry> result = new();

View File

@@ -178,6 +178,11 @@ MeshRenderer:
m_ReflectionProbeUsage: 1
m_RayTracingMode: 2
m_RayTraceProcedural: 0
m_RayTracingAccelStructBuildFlagsOverride: 0
m_RayTracingAccelStructBuildFlags: 1
m_SmallMeshCulling: 1
m_ForceMeshLod: -1
m_MeshLodSelectionBias: 0
m_RenderingLayerMask: 1
m_RendererPriority: 0
m_Materials:
@@ -199,6 +204,7 @@ MeshRenderer:
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_GlobalIlluminationMeshLod: 0
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
@@ -261,6 +267,11 @@ MeshRenderer:
m_ReflectionProbeUsage: 1
m_RayTracingMode: 2
m_RayTraceProcedural: 0
m_RayTracingAccelStructBuildFlagsOverride: 0
m_RayTracingAccelStructBuildFlags: 1
m_SmallMeshCulling: 1
m_ForceMeshLod: -1
m_MeshLodSelectionBias: 0
m_RenderingLayerMask: 1
m_RendererPriority: 0
m_Materials:
@@ -282,6 +293,7 @@ MeshRenderer:
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_GlobalIlluminationMeshLod: 0
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
@@ -432,6 +444,7 @@ MonoBehaviour:
m_DeselectOnBackgroundClick: 1
m_PointerBehavior: 0
m_CursorLockBehavior: 0
m_ScrollDeltaPerTick: 6
--- !u!114 &5755241224653137510
MonoBehaviour:
m_ObjectHideFlags: 0
@@ -472,7 +485,7 @@ MonoBehaviour:
m_BoolArgument: 0
m_CallState: 2
m_ActionId: 6aef4bef-4ba7-40e0-a7d1-d7f1e248ca58
m_ActionName: Global/MinimizeWindow[/Keyboard/minus]
m_ActionName: 'Global/MinimizeWindow[/Keyboard/minus]'
- m_PersistentCalls:
m_Calls:
- m_Target: {fileID: 2842681098514009160}
@@ -488,7 +501,7 @@ MonoBehaviour:
m_BoolArgument: 0
m_CallState: 2
m_ActionId: 5a8d46e2-d677-458a-9ff0-f6c3f3617562
m_ActionName: Global/MaximizeWindow[/Keyboard/ctrl,/Keyboard/w,/Keyboard/equals]
m_ActionName: 'Global/MaximizeWindow[/Keyboard/ctrl,/Keyboard/w,/Keyboard/equals]'
- m_PersistentCalls:
m_Calls:
- m_Target: {fileID: 5097730334777079569}
@@ -505,7 +518,7 @@ MonoBehaviour:
m_BoolArgument: 0
m_CallState: 2
m_ActionId: 019b3bce-869c-4779-9021-77ca15e4c92f
m_ActionName: Global/FocusHierarchy[/Keyboard/ctrl,/Keyboard/w,/Keyboard/h]
m_ActionName: 'Global/FocusHierarchy[/Keyboard/ctrl,/Keyboard/w,/Keyboard/h]'
- m_PersistentCalls:
m_Calls:
- m_Target: {fileID: 5097730334777079569}
@@ -522,7 +535,7 @@ MonoBehaviour:
m_BoolArgument: 0
m_CallState: 2
m_ActionId: 427a3330-d987-4cc4-80f1-5481caffc3f2
m_ActionName: Global/FocusTools[/Keyboard/ctrl,/Keyboard/w,/Keyboard/t]
m_ActionName: 'Global/FocusTools[/Keyboard/ctrl,/Keyboard/w,/Keyboard/t]'
- m_PersistentCalls:
m_Calls:
- m_Target: {fileID: 5097730334777079569}
@@ -539,7 +552,7 @@ MonoBehaviour:
m_BoolArgument: 0
m_CallState: 2
m_ActionId: b988c7ef-3a1d-4e95-9fc8-bcacf7a33267
m_ActionName: Global/FocusAssets[/Keyboard/ctrl,/Keyboard/w,/Keyboard/a]
m_ActionName: 'Global/FocusAssets[/Keyboard/ctrl,/Keyboard/w,/Keyboard/a]'
- m_PersistentCalls:
m_Calls:
- m_Target: {fileID: 5097730334777079569}
@@ -568,7 +581,7 @@ MonoBehaviour:
m_BoolArgument: 0
m_CallState: 2
m_ActionId: 056fffef-8a96-49e4-b2b2-ad08f4f8e42a
m_ActionName: Global/FocusInspector[/Keyboard/ctrl,/Keyboard/w,/Keyboard/i]
m_ActionName: 'Global/FocusInspector[/Keyboard/ctrl,/Keyboard/w,/Keyboard/i]'
- m_PersistentCalls:
m_Calls:
- m_Target: {fileID: 5097730334777079569}
@@ -585,7 +598,7 @@ MonoBehaviour:
m_BoolArgument: 0
m_CallState: 2
m_ActionId: 1e8842a8-dd79-4d95-87e5-1f7635d66606
m_ActionName: Global/FocusMain[/Keyboard/ctrl,/Keyboard/w,/Keyboard/m]
m_ActionName: 'Global/FocusMain[/Keyboard/ctrl,/Keyboard/w,/Keyboard/m]'
- m_PersistentCalls:
m_Calls:
- m_Target: {fileID: 2842681098514009160}
@@ -601,7 +614,7 @@ MonoBehaviour:
m_BoolArgument: 0
m_CallState: 2
m_ActionId: 232e2893-c8ea-4bad-bec4-adbfa058ba13
m_ActionName: Global/ExitFullWindow[/Keyboard/ctrl,/Keyboard/w,/Keyboard/leftBracket]
m_ActionName: 'Global/ExitFullWindow[/Keyboard/ctrl,/Keyboard/w,/Keyboard/leftBracket]'
- m_PersistentCalls:
m_Calls:
- m_Target: {fileID: 2842681098514009160}
@@ -617,7 +630,7 @@ MonoBehaviour:
m_BoolArgument: 0
m_CallState: 2
m_ActionId: f5fc4030-90d0-4d71-baba-a1d93b407b76
m_ActionName: Global/FullWindow[/Keyboard/ctrl,/Keyboard/w,/Keyboard/rightBracket]
m_ActionName: 'Global/FullWindow[/Keyboard/ctrl,/Keyboard/w,/Keyboard/rightBracket]'
- m_PersistentCalls:
m_Calls:
- m_Target: {fileID: 2842681098514009160}
@@ -633,15 +646,15 @@ MonoBehaviour:
m_BoolArgument: 0
m_CallState: 2
m_ActionId: 72e4bc9a-bf8d-4cf6-bcb4-635303b3dd91
m_ActionName: Global/ExitFocusInspector[/Keyboard/ctrl,/Keyboard/w,/Keyboard/quote]
m_ActionName: 'Global/ExitFocusInspector[/Keyboard/ctrl,/Keyboard/w,/Keyboard/quote]'
- m_PersistentCalls:
m_Calls: []
m_ActionId: 09e09383-f82c-482a-942b-c8eb0834e6a6
m_ActionName: Global/CommandMode[/Keyboard/leftCtrl,/Keyboard/p]
m_ActionName: 'Global/CommandMode[/Keyboard/leftCtrl,/Keyboard/p]'
- m_PersistentCalls:
m_Calls: []
m_ActionId: 59ef6b68-5b72-429d-b115-6351f9c596b4
m_ActionName: Global/EscAnyMode[/Keyboard/escape]
m_ActionName: 'Global/EscAnyMode[/Keyboard/escape]'
- m_PersistentCalls:
m_Calls:
- m_Target: {fileID: 8774020968396821109}
@@ -657,7 +670,7 @@ MonoBehaviour:
m_BoolArgument: 0
m_CallState: 2
m_ActionId: 6f11972a-292f-4ec8-a47a-c08a5255a3ec
m_ActionName: Global/RefreshMode[/Keyboard/ctrl,/Keyboard/r]
m_ActionName: 'Global/RefreshMode[/Keyboard/ctrl,/Keyboard/r]'
- m_PersistentCalls:
m_Calls:
- m_Target: {fileID: 9026220626307204097}
@@ -673,7 +686,7 @@ MonoBehaviour:
m_BoolArgument: 0
m_CallState: 2
m_ActionId: f01a7483-b388-46f9-9104-0100e1d7c09e
m_ActionName: Global/Rename[/Keyboard/f2]
m_ActionName: 'Global/Rename[/Keyboard/f2]'
m_NeverAutoSwitchControlSchemes: 0
m_DefaultControlScheme:
m_DefaultActionMap: Global
@@ -811,7 +824,6 @@ MonoBehaviour:
m_ScreenCoordScaleBias: {x: 0, y: 0, z: 0, w: 0}
m_RequiresDepthTexture: 0
m_RequiresColorTexture: 0
m_Version: 2
m_TaaSettings:
m_Quality: 3
m_FrameInfluence: 0.1
@@ -819,6 +831,7 @@ MonoBehaviour:
m_MipBias: 0
m_VarianceClampScale: 0.9
m_ContrastAdaptiveSharpening: 0
m_Version: 2
--- !u!114 &4433285524107997579
MonoBehaviour:
m_ObjectHideFlags: 0
@@ -831,28 +844,26 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 72ece51f2901e7445ab60da3685d6b5f, type: 3}
m_Name:
m_EditorClassIdentifier:
m_ShowDebugText: 0
m_ShowCameraFrustum: 1
m_IgnoreTimeScale: 0
m_WorldUpOverride: {fileID: 0}
m_UpdateMethod: 2
m_BlendUpdateMethod: 1
m_DefaultBlend:
m_Style: 1
m_Time: 0.5
m_CustomCurve:
ShowDebugText: 0
ShowCameraFrustum: 1
IgnoreTimeScale: 0
WorldUpOverride: {fileID: 0}
ChannelMask: -1
UpdateMethod: 2
BlendUpdateMethod: 1
LensModeOverride:
Enabled: 0
DefaultMode: 2
DefaultBlend:
Style: 1
Time: 0.5
CustomCurve:
serializedVersion: 2
m_Curve: []
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
m_CustomBlends: {fileID: 0}
m_CameraCutEvent:
m_PersistentCalls:
m_Calls: []
m_CameraActivatedEvent:
m_PersistentCalls:
m_Calls: []
CustomBlends: {fileID: 0}
--- !u!114 &1937889226080204937
MonoBehaviour:
m_ObjectHideFlags: 0
@@ -979,7 +990,7 @@ MonoBehaviour:
m_Bits: 55
--- !u!95 &2842681098514009160
Animator:
serializedVersion: 5
serializedVersion: 7
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
@@ -993,6 +1004,7 @@ Animator:
m_ApplyRootMotion: 0
m_LinearVelocityBlending: 0
m_StabilizeFeet: 0
m_AnimatePhysics: 0
m_WarningMessage:
m_HasTransformHierarchy: 1
m_AllowConstantClipSamplingOptimization: 1
@@ -1046,12 +1058,13 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 45e653bab7fb20e499bda25e1b646fea, type: 3}
m_Name:
m_EditorClassIdentifier:
m_ExcludedPropertiesInInspector:
- m_Script
m_LockStageInInspector:
Priority:
Enabled: 0
m_Value: 0
OutputChannel: 1
StandbyUpdate: 2
m_StreamingVersion: 20170927
m_Priority: 10
m_StandbyUpdate: 2
m_LegacyPriority: 10
m_LookAt: {fileID: 0}
m_Follow: {fileID: 0}
m_Lens:
@@ -1061,17 +1074,30 @@ MonoBehaviour:
FarClipPlane: 5000
Dutch: 0
ModeOverride: 0
LensShift: {x: 0, y: 0}
GateFit: 2
FocusDistance: 10
m_SensorSize: {x: 1, y: 1}
m_Transitions:
LensShift: {x: 0, y: 0}
FocusDistance: 10
Iso: 200
ShutterSpeed: 0.005
Aperture: 16
BladeCount: 5
Curvature: {x: 2, y: 11}
BarrelClipping: 0.25
Anamorphism: 0
BlendHint: 0
m_OnCameraLiveEvent:
m_PersistentCalls:
m_Calls: []
m_ExcludedPropertiesInInspector:
- m_Script
m_LockStageInInspector:
m_LegacyTransitions:
m_BlendHint: 0
m_InheritPosition: 0
m_OnCameraLive:
m_PersistentCalls:
m_Calls: []
m_LegacyBlendHint: 0
m_ComponentOwner: {fileID: 11535700043902880}
--- !u!20 &2319537278398014183
Camera:
@@ -1160,7 +1186,6 @@ MonoBehaviour:
m_ScreenCoordScaleBias: {x: 0, y: 0, z: 0, w: 0}
m_RequiresDepthTexture: 0
m_RequiresColorTexture: 0
m_Version: 2
m_TaaSettings:
m_Quality: 3
m_FrameInfluence: 0.1
@@ -1168,6 +1193,7 @@ MonoBehaviour:
m_MipBias: 0
m_VarianceClampScale: 0.9
m_ContrastAdaptiveSharpening: 0
m_Version: 2
--- !u!114 &9221906298468010471
MonoBehaviour:
m_ObjectHideFlags: 0
@@ -1300,6 +1326,11 @@ MeshRenderer:
m_ReflectionProbeUsage: 1
m_RayTracingMode: 2
m_RayTraceProcedural: 0
m_RayTracingAccelStructBuildFlagsOverride: 0
m_RayTracingAccelStructBuildFlags: 1
m_SmallMeshCulling: 1
m_ForceMeshLod: -1
m_MeshLodSelectionBias: 0
m_RenderingLayerMask: 1
m_RendererPriority: 0
m_Materials:
@@ -1321,6 +1352,7 @@ MeshRenderer:
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_GlobalIlluminationMeshLod: 0
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
@@ -1419,12 +1451,13 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 45e653bab7fb20e499bda25e1b646fea, type: 3}
m_Name:
m_EditorClassIdentifier:
m_ExcludedPropertiesInInspector:
- m_Script
m_LockStageInInspector:
Priority:
Enabled: 0
m_Value: 0
OutputChannel: 1
StandbyUpdate: 2
m_StreamingVersion: 20170927
m_Priority: 10
m_StandbyUpdate: 2
m_LegacyPriority: 10
m_LookAt: {fileID: 0}
m_Follow: {fileID: 0}
m_Lens:
@@ -1434,17 +1467,30 @@ MonoBehaviour:
FarClipPlane: 5000
Dutch: 0
ModeOverride: 0
LensShift: {x: 0, y: 0}
GateFit: 2
FocusDistance: 10
m_SensorSize: {x: 1, y: 1}
m_Transitions:
LensShift: {x: 0, y: 0}
FocusDistance: 10
Iso: 200
ShutterSpeed: 0.005
Aperture: 16
BladeCount: 5
Curvature: {x: 2, y: 11}
BarrelClipping: 0.25
Anamorphism: 0
BlendHint: 0
m_OnCameraLiveEvent:
m_PersistentCalls:
m_Calls: []
m_ExcludedPropertiesInInspector:
- m_Script
m_LockStageInInspector:
m_LegacyTransitions:
m_BlendHint: 0
m_InheritPosition: 0
m_OnCameraLive:
m_PersistentCalls:
m_Calls: []
m_LegacyBlendHint: 0
m_ComponentOwner: {fileID: 3000479872335485243}
--- !u!20 &7206794941111705965
Camera:
@@ -1533,7 +1579,6 @@ MonoBehaviour:
m_ScreenCoordScaleBias: {x: 0, y: 0, z: 0, w: 0}
m_RequiresDepthTexture: 0
m_RequiresColorTexture: 0
m_Version: 2
m_TaaSettings:
m_Quality: 3
m_FrameInfluence: 0.1
@@ -1541,6 +1586,7 @@ MonoBehaviour:
m_MipBias: 0
m_VarianceClampScale: 0.9
m_ContrastAdaptiveSharpening: 0
m_Version: 2
--- !u!114 &5183958985083021394
MonoBehaviour:
m_ObjectHideFlags: 0