using System; using System.Linq; using System.Collections.Generic; using UnityEngine; using System.Collections; /// <summary> /// <see cref="Fact.Id"/>/ <c>MonoBehaviour</c> wrapper to be attached to <see cref="Fact.Representation"/> /// </summary> public class FactObject : MonoBehaviour, ISerializationCallbackReceiver { /// <summary> /// <see cref="Fact.Id"/> to identify arbitrary <see cref="Fact"/> by its <see cref="Fact.Representation"/> /// </summary> public string URI; /// <summary> /// Shorthand and Cache for <see cref="Fact.TryGetGlobalFact(string, out Fact)"/>. /// </summary> public Fact Fact { get { if (_Fact == null) Fact.TryGetGlobalFact(URI, out _Fact); return _Fact; } set { _Fact = value; URI = value.Id; } } private Fact _Fact; public enum FactMaterials { Default = 0, Selected = 1, Hint = 2, Solution = 3, } public Material[] materials; public new Renderer[] renderer; public List<FactObject> cascade; #region Unity Serialization public Material Default; public Material Selected; public Material Hint; public Material Solution; void ISerializationCallbackReceiver.OnBeforeSerialize() { if (materials == null) return; Default = materials[(int)FactMaterials.Default]; Selected = materials[(int)FactMaterials.Selected]; Hint = materials[(int)FactMaterials.Hint]; Solution = materials[(int)FactMaterials.Solution]; } void ISerializationCallbackReceiver.OnAfterDeserialize() { materials = new Material[4]; materials[(int)FactMaterials.Default] = Default; materials[(int)FactMaterials.Selected] = Selected; materials[(int)FactMaterials.Hint] = Hint; materials[(int)FactMaterials.Solution] = Solution; } #endregion private void Awake() { cascade = new() { this, }; cascade.AddRange(transform.GetComponentsInChildren<FactObject>(includeInactive: true)); } public void CascadeForChildren(Action<FactObject> func) { foreach (FactObject fo in cascade) func(fo); } public void ForAllRenderer(Action<Renderer> func) { foreach (Renderer ren in renderer) func(ren); } public void CoroutineCascadeForChildrenAllRenderer(Func<FactObject, Renderer, IEnumerator> func) { this.StopAllCoroutines(); foreach (FactObject fo in cascade) foreach (Renderer ren in fo.renderer) StartCoroutine(func(fo, ren)); } }