mirror of
https://github.com/Cardidi/ca2d-unity-toolkit.git
synced 2025-12-20 01:06:03 +08:00
Remove UnityObjectWarp and add gui for Option
This commit is contained in:
parent
f320b479ea
commit
3e8f62f5cf
6
.idea/.idea.ca2d-unity-toolkit/.idea/vcs.xml
generated
Normal file
6
.idea/.idea.ca2d-unity-toolkit/.idea/vcs.xml
generated
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
3
Assets/Toolkit/Toolkit/Editor.meta
Normal file
3
Assets/Toolkit/Toolkit/Editor.meta
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 9fbae8b6b0a64df885641b3584fcb15b
|
||||||
|
timeCreated: 1719991315
|
||||||
3
Assets/Toolkit/Toolkit/Editor/Scripts.meta
Normal file
3
Assets/Toolkit/Toolkit/Editor/Scripts.meta
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: ce8a0f7441b34ce9a8f891b87fbaad91
|
||||||
|
timeCreated: 1719991325
|
||||||
105
Assets/Toolkit/Toolkit/Editor/Scripts/AssetDatabaseUtility.cs
Normal file
105
Assets/Toolkit/Toolkit/Editor/Scripts/AssetDatabaseUtility.cs
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
using System.Text;
|
||||||
|
using UnityEditor;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Ca2d.Toolkit.Editor
|
||||||
|
{
|
||||||
|
public static class AssetDatabaseUtility
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Check if this path contains a valid asset.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="path">Target path</param>
|
||||||
|
/// <returns>True that path is an asset</returns>
|
||||||
|
public static bool PathIsValidAsset(string path)
|
||||||
|
{
|
||||||
|
return AssetDatabase.IsValidFolder(path) == false &&
|
||||||
|
string.IsNullOrWhiteSpace(AssetDatabase.AssetPathToGUID(path)) == false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Create a folder in a path if this folder has not been created.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="folderPath">Target folder path</param>
|
||||||
|
/// <returns>Is this path is ready to be a folder?</returns>
|
||||||
|
public static bool CreateFolderIfNotExist(string folderPath)
|
||||||
|
{
|
||||||
|
if (PathIsValidAsset(folderPath)) return false;
|
||||||
|
if (AssetDatabase.IsValidFolder(folderPath)) return true;
|
||||||
|
|
||||||
|
var pathVector = folderPath.Split('/');
|
||||||
|
if (pathVector.Length == 0) return false;
|
||||||
|
if (pathVector.Length == 1) return AssetDatabase.IsValidFolder(pathVector[0]);
|
||||||
|
if (pathVector.Length < 2)
|
||||||
|
{
|
||||||
|
if (AssetDatabase.IsValidFolder($"{pathVector[0]}/{pathVector[1]}")) return true;
|
||||||
|
return string.IsNullOrEmpty(AssetDatabase.CreateFolder(pathVector[0], pathVector[1])) == false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var sb = new StringBuilder(pathVector[0]);
|
||||||
|
var prev = pathVector[0];
|
||||||
|
for (var i = 1; i < pathVector.Length; i++)
|
||||||
|
{
|
||||||
|
var tk = pathVector[i];
|
||||||
|
if (i == pathVector.Length - 1 && tk.Contains('.')) continue;
|
||||||
|
sb.Append('/').Append(tk);
|
||||||
|
|
||||||
|
var cur = sb.ToString();
|
||||||
|
if (AssetDatabase.IsValidFolder(cur) == false)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(AssetDatabase.CreateFolder(prev, tk)))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
prev = cur;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Create asset at path with everything done (include create path and create asset.).
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="path">The folder path this file will be create to.</param>
|
||||||
|
/// <typeparam name="T">The type of asset.</typeparam>
|
||||||
|
/// <returns>If asset path is valid, return new asset.</returns>
|
||||||
|
public static T CreateAssetAtPath<T>(string path) where T : ScriptableObject
|
||||||
|
{
|
||||||
|
if (CreateFolderIfNotExist(path) == false) return null;
|
||||||
|
var asset = ScriptableObject.CreateInstance<T>();
|
||||||
|
|
||||||
|
AssetDatabase.CreateAsset(asset, $"{path}");
|
||||||
|
|
||||||
|
return asset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Create asset at path with everything done (include create path and create asset.).
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="path">The folder path this file will be create to.</param>
|
||||||
|
/// <param name="name">The file name this asset will be.</param>
|
||||||
|
/// <typeparam name="T">The type of asset.</typeparam>
|
||||||
|
/// <returns>If asset path is valid, return new asset.</returns>
|
||||||
|
public static T CreateAssetAtPath<T>(string path, string name) where T : ScriptableObject
|
||||||
|
{
|
||||||
|
if (CreateFolderIfNotExist(path) == false) return null;
|
||||||
|
var asset = ScriptableObject.CreateInstance<T>();
|
||||||
|
|
||||||
|
if (path.EndsWith('/')) AssetDatabase.CreateAsset(asset, $"{path}{name}.asset");
|
||||||
|
else AssetDatabase.CreateAsset(asset, $"{path}/{name}.asset");
|
||||||
|
|
||||||
|
return asset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Trim an editor path to resource path.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="path">Editor path</param>
|
||||||
|
public static void AssetPathTrimmer(ref string path)
|
||||||
|
{
|
||||||
|
path = path.Replace("Assets/Resources/", "");
|
||||||
|
path = path.Replace(".asset", "");
|
||||||
|
path = path.Replace(".prefab", "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 97def5fd9acbf7db4a7e5cee4537f1c5
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
35
Assets/Toolkit/Toolkit/Editor/Scripts/OptionDrawer.cs
Normal file
35
Assets/Toolkit/Toolkit/Editor/Scripts/OptionDrawer.cs
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
using UnityEditor;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Ca2d.Toolkit.Editor
|
||||||
|
{
|
||||||
|
[CustomPropertyDrawer(typeof(Option<>))]
|
||||||
|
public class OptionDrawer : PropertyDrawer
|
||||||
|
{
|
||||||
|
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
|
||||||
|
{
|
||||||
|
return EditorGUI.GetPropertyHeight(property.FindPropertyRelative("Value")); ;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
|
||||||
|
{
|
||||||
|
var value = property.FindPropertyRelative("Value");
|
||||||
|
var enable = property.FindPropertyRelative("Enabled");
|
||||||
|
|
||||||
|
var toggleRect = position;
|
||||||
|
toggleRect.height = toggleRect.width = 18;
|
||||||
|
|
||||||
|
enable.boolValue = EditorGUI.Toggle(toggleRect, GUIContent.none, enable.boolValue);
|
||||||
|
var prev = GUI.enabled;
|
||||||
|
GUI.enabled = enable.boolValue;
|
||||||
|
|
||||||
|
var propertyRect = position;
|
||||||
|
propertyRect.x += 18;
|
||||||
|
propertyRect.width -= 18;
|
||||||
|
EditorGUI.PropertyField(propertyRect, value, label, true);
|
||||||
|
GUI.enabled = prev;
|
||||||
|
|
||||||
|
if (value.serializedObject.hasModifiedProperties) value.serializedObject.ApplyModifiedProperties();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
11
Assets/Toolkit/Toolkit/Editor/Scripts/OptionDrawer.cs.meta
Normal file
11
Assets/Toolkit/Toolkit/Editor/Scripts/OptionDrawer.cs.meta
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: f242342c346b40fb2836611534f4e953
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@ -11,7 +11,9 @@ namespace Ca2d.Toolkit
|
|||||||
|
|
||||||
private static void IgnoreNoTarget()
|
private static void IgnoreNoTarget()
|
||||||
{
|
{
|
||||||
|
#if UNITY_EDITOR
|
||||||
Debug.LogError("Ignore Exception should run with executor!");
|
Debug.LogError("Ignore Exception should run with executor!");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#region IgnoreException(Action)
|
#region IgnoreException(Action)
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
#if ENABLE_LOGG
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace Ca2d.Toolkit
|
namespace Ca2d.Toolkit
|
||||||
@ -41,3 +42,4 @@ namespace Ca2d.Toolkit
|
|||||||
public void ClearLabel();
|
public void ClearLabel();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
@ -1,3 +1,4 @@
|
|||||||
|
#if ENABLE_LOGG
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
@ -280,3 +281,4 @@ namespace Ca2d.Toolkit
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
@ -1,3 +1,4 @@
|
|||||||
|
#if ENABLE_LOGG
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
@ -100,3 +101,4 @@ namespace Ca2d.Toolkit
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
281
Assets/Toolkit/Toolkit/Scripts/ResLock.cs
Normal file
281
Assets/Toolkit/Toolkit/Scripts/ResLock.cs
Normal file
@ -0,0 +1,281 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Ca2d.Toolkit
|
||||||
|
{
|
||||||
|
|
||||||
|
public delegate void ResLockStateChanged(ResLock resLock, uint notionId, bool notionSelfState);
|
||||||
|
|
||||||
|
public class ResLock
|
||||||
|
{
|
||||||
|
private struct ResourceNotionCore : IDisposable
|
||||||
|
{
|
||||||
|
|
||||||
|
#region Allocator
|
||||||
|
|
||||||
|
private static SortedSet<uint> m_allocateMap = new();
|
||||||
|
|
||||||
|
private static uint AllocateId()
|
||||||
|
{
|
||||||
|
// Id should start at 1 to avoid 0 as default.
|
||||||
|
uint id = 1;
|
||||||
|
foreach (var u in m_allocateMap)
|
||||||
|
{
|
||||||
|
if (id < u) break;
|
||||||
|
id = u + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_allocateMap.Add(id);
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void FreeId(uint id)
|
||||||
|
{
|
||||||
|
m_allocateMap.Remove(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Notification
|
||||||
|
|
||||||
|
|
||||||
|
private static bool _LockStateNotifyGuard = false;
|
||||||
|
|
||||||
|
private static void NotifyLoopDetect()
|
||||||
|
{
|
||||||
|
if (_LockStateNotifyGuard) throw new InvalidOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void Notify(ResLock target, ref ResourceNotionCore core)
|
||||||
|
{
|
||||||
|
_LockStateNotifyGuard = true;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_LockStateEvents?.Invoke(target, core.Id, core.Target.m_resNotions.Contains(core.Id));
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Debug.LogError(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
_LockStateNotifyGuard = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
public readonly uint Id;
|
||||||
|
|
||||||
|
public readonly ResLock Target;
|
||||||
|
|
||||||
|
public ResourceNotionCore(ResLock target)
|
||||||
|
{
|
||||||
|
Target = target;
|
||||||
|
Id = AllocateId();
|
||||||
|
#if DEBUG
|
||||||
|
Debug.LogFormat("Resource Notion '{0}' was allocated for {1}", Id, target.FriendlyName);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool SetState(bool enabled)
|
||||||
|
{
|
||||||
|
NotifyLoopDetect();
|
||||||
|
|
||||||
|
var result = enabled ? Target.m_resNotions.Add(Id) : Target.m_resNotions.Remove(Id);
|
||||||
|
Notify(Target, ref this);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
FreeId(Id);
|
||||||
|
#if DEBUG
|
||||||
|
Debug.LogFormat("Resource Notion '{0}' was released from {1}", Id, Target.FriendlyName);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct LiteResourceNotion : IDisposable
|
||||||
|
{
|
||||||
|
private ResourceNotionCore m_core;
|
||||||
|
|
||||||
|
internal LiteResourceNotion(ResLock parent)
|
||||||
|
{
|
||||||
|
m_core = new ResourceNotionCore(parent);
|
||||||
|
m_core.SetState(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
if (m_core.Target == null)
|
||||||
|
throw new InvalidOperationException("Can not dispose a disposed Resource Notion!");
|
||||||
|
|
||||||
|
m_core.SetState(false);
|
||||||
|
m_core.Dispose();
|
||||||
|
m_core = default;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public class ResourceNotion : IDisposable
|
||||||
|
{
|
||||||
|
private ResourceNotionCore m_core;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Event when locking state changed.
|
||||||
|
/// </summary>
|
||||||
|
public event Action<bool> OnStateChanged;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The locking state of this notion.
|
||||||
|
/// </summary>
|
||||||
|
public bool LockStateSelf { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The parent of this notion.
|
||||||
|
/// </summary>
|
||||||
|
public ResLock Parent => m_core.Target;
|
||||||
|
|
||||||
|
internal ResourceNotion(ResLock parent)
|
||||||
|
{
|
||||||
|
m_core = new ResourceNotionCore(parent);
|
||||||
|
LockStateSelf = false;
|
||||||
|
_LockStateEvents += NotifyListener;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Lock this notion
|
||||||
|
/// </summary>
|
||||||
|
public bool Lock()
|
||||||
|
{
|
||||||
|
Guard();
|
||||||
|
if (m_core.SetState(true))
|
||||||
|
{
|
||||||
|
LockStateSelf = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Unlock this notion.
|
||||||
|
/// </summary>
|
||||||
|
public bool Unlock()
|
||||||
|
{
|
||||||
|
Guard();
|
||||||
|
if (m_core.SetState(false))
|
||||||
|
{
|
||||||
|
LockStateSelf = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
if (m_core.Target == null)
|
||||||
|
throw new InvalidOperationException("Can not dispose a disposed Resource Notion!");
|
||||||
|
|
||||||
|
m_core.SetState(false);
|
||||||
|
_LockStateEvents -= NotifyListener;
|
||||||
|
LockStateSelf = false;
|
||||||
|
m_core.Dispose();
|
||||||
|
m_core = default;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void NotifyListener(ResLock target, uint id, bool selfState)
|
||||||
|
{
|
||||||
|
if (target == Parent)
|
||||||
|
{
|
||||||
|
OnStateChanged?.Invoke(target.LockState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Guard()
|
||||||
|
{
|
||||||
|
if (m_core.Target == null)
|
||||||
|
throw new InvalidOperationException("Can not operate a disposed Resource Notion!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static event ResLockStateChanged _LockStateEvents
|
||||||
|
#if DEBUG
|
||||||
|
= (locker, id, selfState) =>
|
||||||
|
{
|
||||||
|
var name = locker.FriendlyName;
|
||||||
|
var state = locker.LockState;
|
||||||
|
|
||||||
|
using (StringBuilderPool.Get(out var sb))
|
||||||
|
{
|
||||||
|
sb.AppendFormat(
|
||||||
|
"Resource Notion '{0}' changes to {1} made Locker '{2}' state changed to {3} ",
|
||||||
|
id,
|
||||||
|
selfState ? "True" : "False",
|
||||||
|
name,
|
||||||
|
state ? "True" : "False");
|
||||||
|
|
||||||
|
sb.AppendFormat("(limit {0}:, used: {1})", locker.m_resCount, locker.m_resNotions.Count);
|
||||||
|
|
||||||
|
Debug.Log(sb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
;
|
||||||
|
|
||||||
|
private uint m_resCount;
|
||||||
|
|
||||||
|
private HashSet<uint> m_resNotions = new ();
|
||||||
|
|
||||||
|
public ResLock(uint resCount = 0, string friendlyName = default)
|
||||||
|
{
|
||||||
|
m_resCount = resCount;
|
||||||
|
FriendlyName = friendlyName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// User friendly name for ResLock
|
||||||
|
/// </summary>
|
||||||
|
public string FriendlyName { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// State of this lock itself
|
||||||
|
/// </summary>
|
||||||
|
public bool LockState => m_resNotions.Count > m_resCount;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Do locking on this locker
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="requireLockStateIsFree">Should require this lock is free</param>
|
||||||
|
/// <returns>Locker Notion can be used in using block</returns>
|
||||||
|
/// <exception cref="InvalidOperationException">Lock can not being operated.</exception>
|
||||||
|
public LiteResourceNotion Lock(bool requireLockStateIsFree = true)
|
||||||
|
{
|
||||||
|
if (requireLockStateIsFree && LockState)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(FriendlyName)) throw new InvalidOperationException(
|
||||||
|
"Can not lock Resource Lock due to free state is required.");
|
||||||
|
else throw new InvalidOperationException(
|
||||||
|
$"Can not lock Resource Lock '{FriendlyName}' due to free state is required.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return new LiteResourceNotion(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取一个锁注解
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="initialLock">该注解的起始锁定状态</param>
|
||||||
|
public ResourceNotion GetNotion(bool initialLock = false)
|
||||||
|
{
|
||||||
|
var n = new ResourceNotion(this);
|
||||||
|
if (initialLock) n.Lock();
|
||||||
|
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
3
Assets/Toolkit/Toolkit/Scripts/ResLock.cs.meta
Normal file
3
Assets/Toolkit/Toolkit/Scripts/ResLock.cs.meta
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 28e7e62b954e414f80499b70d8e3dcf3
|
||||||
|
timeCreated: 1719992451
|
||||||
18
Assets/Toolkit/Toolkit/Scripts/StringBuilderPool.cs
Normal file
18
Assets/Toolkit/Toolkit/Scripts/StringBuilderPool.cs
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
using System.Text;
|
||||||
|
using UnityEngine.Pool;
|
||||||
|
|
||||||
|
namespace Ca2d.Toolkit
|
||||||
|
{
|
||||||
|
public static class StringBuilderPool
|
||||||
|
{
|
||||||
|
private static readonly ObjectPool<StringBuilder> s_Pool = new (
|
||||||
|
() => new StringBuilder(),
|
||||||
|
sb => sb.Clear());
|
||||||
|
|
||||||
|
public static StringBuilder Get() => s_Pool.Get();
|
||||||
|
|
||||||
|
public static PooledObject<StringBuilder> Get(out StringBuilder value) => s_Pool.Get(out value);
|
||||||
|
|
||||||
|
public static void Release(StringBuilder toRelease) => s_Pool.Release(toRelease);
|
||||||
|
}
|
||||||
|
}
|
||||||
11
Assets/Toolkit/Toolkit/Scripts/StringBuilderPool.cs.meta
Normal file
11
Assets/Toolkit/Toolkit/Scripts/StringBuilderPool.cs.meta
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 41341c104f749b437ad0e367dd9a0d0e
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@ -1,40 +0,0 @@
|
|||||||
using System;
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
namespace Ca2d.Toolkit
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// An utility which allows you to reference an <see cref="UnityEngine.Object"/> via it's interface.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T">The type of class which you are willing to reference as.</typeparam>
|
|
||||||
[Serializable]
|
|
||||||
public struct UnityObjectWarp<T> where T : class
|
|
||||||
{
|
|
||||||
[SerializeField] private UnityEngine.Object m_referencedObject;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Is this warp reference to a valid target?
|
|
||||||
/// </summary>
|
|
||||||
public bool Is => m_referencedObject is T;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Trying to get the actual object of this reference.
|
|
||||||
/// </summary>
|
|
||||||
public T As => m_referencedObject as T;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Is this warp reference to a valid target? If this is valid, give the casting result.
|
|
||||||
/// </summary>
|
|
||||||
public bool IsAs(out T val)
|
|
||||||
{
|
|
||||||
if (m_referencedObject is T referenced)
|
|
||||||
{
|
|
||||||
val = referenced;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
val = null;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 94c950f0a2014abc9e3f97281d149318
|
|
||||||
timeCreated: 1713286510
|
|
||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "xyz.ca2didi.unity.toolkit",
|
"name": "xyz.ca2didi.unity.toolkit",
|
||||||
"version": "0.1.0",
|
"version": "0.1.1",
|
||||||
"displayName": "Ca2D Toolkit",
|
"displayName": "Ca2D Toolkit",
|
||||||
"description": "Set of toolkits which can boost your develop experience and speed in Unity.",
|
"description": "Set of toolkits which can boost your develop experience and speed in Unity.",
|
||||||
"unity": "2021.3",
|
"unity": "2021.3",
|
||||||
|
|||||||
@ -4,6 +4,7 @@
|
|||||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=assets_005Cpackage/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=assets_005Cpackage/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=assets_005Cpackage_005Ctoolkit/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=assets_005Cpackage_005Ctoolkit/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=assets_005Cpackage_005Ctoolkit_005Cscripts/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=assets_005Cpackage_005Ctoolkit_005Cscripts/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=assets_005Ctoolkit_005Ctoolkit_005Ceditor_005Cscripts/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=assets_005Ctoolkit_005Ctoolkit_005Cscripts/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=assets_005Ctoolkit_005Ctoolkit_005Cscripts/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=assets_005Ctoolkit_005Ctoolkit/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=assets_005Ctoolkit_005Ctoolkit/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=assets_005Ctoolkit/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
|
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=assets_005Ctoolkit/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
|
||||||
Loading…
x
Reference in New Issue
Block a user