You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
CrowdControl/Assets/3rd/D2D_Scripts/Utilities/ExtremeCodeSugar/SmartScriptAlloc.cs

137 lines
4.2 KiB
C#

3 months ago
using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Runtime.Serialization.Formatters.Binary;
using D2D;
using D2D.Gameplay;
using D2D.Utilities;
using static D2D.Utilities.SettingsFacade;
using static D2D.Utilities.CommonLazyFacade;
using static D2D.Utilities.CommonGameplayFacade;
namespace D2D.Utilities
{
public class SmartScriptAlloc : MonoBehaviour
{
protected bool IsAllocationEnabled => _coreData.allocationEnabled && _isAlloc;
private Dictionary<Type, Component> _getCache;
private Dictionary<Type, Component[]> _getsCache;
private Dictionary<Type, Component> _parentGetCache;
private Dictionary<Type, Component[]> _parentGetsCache;
private Dictionary<Type, Component> _childrenGetCache;
private Dictionary<Type, Component[]> _childrenGetsCache;
private Dictionary<Type, Component> _findCache;
private Dictionary<Type, Component[]> _findsCache;
private bool _canBeNull = false;
private bool _isAlloc = true;
public SmartScriptAlloc NoAlloc()
{
_isAlloc = false;
return this;
}
public SmartScriptAlloc CanBeNull()
{
_canBeNull = true;
return this;
}
private void ResetParameters()
{
_canBeNull = false;
_isAlloc = true;
}
public T Get<T>(bool canBeNull = false) where T : Component =>
Single(_getCache, GetComponent<T>, canBeNull);
public T[] Gets<T>(bool canBeNull = false) where T : Component =>
Many(_getsCache, GetComponents<T>, canBeNull);
public T ChildrenGet<T>(bool canBeNull = false) where T : Component =>
Single(_childrenGetCache, GetComponentInChildren<T>, canBeNull);
public T[] ChildrenGets<T>(bool canBeNull = false) where T : Component =>
Many(_childrenGetsCache, GetComponentsInChildren<T>, canBeNull);
public T ParentGet<T>(bool canBeNull = false) where T : Component =>
Single(_parentGetCache, GetComponentInParent<T>, canBeNull);
public T[] ParentGets<T>(bool canBeNull = false) where T : Component =>
Many(_parentGetsCache, GetComponentsInParent<T>, canBeNull);
public T Find<T>(bool canBeNull = false) where T : Component =>
Single(_findCache, FindObjectOfType<T>, canBeNull);
public T[] Finds<T>(bool canBeNull = false) where T : Component =>
Many(_findsCache, FindObjectsOfType<T>, canBeNull);
private T Single<T>(Dictionary<Type, Component> storage, Func<T> getComponentMethod, bool canBeNull)
where T : Component
{
if (IsAllocationEnabled)
{
storage ??= new Dictionary<Type, Component>();
if (storage.TryGetValue(typeof(T), out var cached))
{
ResetParameters();
return (T) cached;
}
}
var result = getComponentMethod?.Invoke();
if (!canBeNull && result == null)
throw new Exception("Component was not found!");
if (IsAllocationEnabled)
{
storage.Add(typeof(T), result);
}
ResetParameters();
return result;
}
private T[] Many<T>(Dictionary<Type, Component[]> storage, Func<T[]> getComponentMethod, bool canBeNull)
where T : Component
{
if (IsAllocationEnabled)
{
storage ??= new Dictionary<Type, Component[]>();
if (storage.TryGetValue(typeof(T), out var cached))
{
ResetParameters();
return (T[]) cached;
}
}
var result = getComponentMethod?.Invoke();
if (!canBeNull && result == null)
throw new Exception("Component was not found!");
if (IsAllocationEnabled)
{
storage.Add(typeof(T), result);
}
ResetParameters();
return result;
}
}
}