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 _getCache; private Dictionary _getsCache; private Dictionary _parentGetCache; private Dictionary _parentGetsCache; private Dictionary _childrenGetCache; private Dictionary _childrenGetsCache; private Dictionary _findCache; private Dictionary _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(bool canBeNull = false) where T : Component => Single(_getCache, GetComponent, canBeNull); public T[] Gets(bool canBeNull = false) where T : Component => Many(_getsCache, GetComponents, canBeNull); public T ChildrenGet(bool canBeNull = false) where T : Component => Single(_childrenGetCache, GetComponentInChildren, canBeNull); public T[] ChildrenGets(bool canBeNull = false) where T : Component => Many(_childrenGetsCache, GetComponentsInChildren, canBeNull); public T ParentGet(bool canBeNull = false) where T : Component => Single(_parentGetCache, GetComponentInParent, canBeNull); public T[] ParentGets(bool canBeNull = false) where T : Component => Many(_parentGetsCache, GetComponentsInParent, canBeNull); public T Find(bool canBeNull = false) where T : Component => Single(_findCache, FindObjectOfType, canBeNull); public T[] Finds(bool canBeNull = false) where T : Component => Many(_findsCache, FindObjectsOfType, canBeNull); private T Single(Dictionary storage, Func getComponentMethod, bool canBeNull) where T : Component { if (IsAllocationEnabled) { storage ??= new Dictionary(); 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(Dictionary storage, Func getComponentMethod, bool canBeNull) where T : Component { if (IsAllocationEnabled) { storage ??= new Dictionary(); 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; } } }