Skip to content
Snippets Groups Projects
FactObject.cs 4.62 KiB
Newer Older
  • Learn to ignore specific revisions
  • using System;
    using System.Linq;
    using System.Collections.Generic;
    using UnityEngine;
    using System.Collections;
    
    using UnityEditor;
    
    Richard Marcus's avatar
    Richard Marcus committed
    
    
    /// <summary>
    /// <see cref="Fact.Id"/>/ <c>MonoBehaviour</c> wrapper to be attached to <see cref="Fact.Representation"/>
    /// </summary>
    
    MaZiFAU's avatar
    MaZiFAU committed
    [DisallowMultipleComponent]
    public class FactObject : FactWrapper, ISerializationCallbackReceiver
    
    Richard Marcus's avatar
    Richard Marcus committed
    {
    
        public enum FactMaterials
        {
            Default = 0,
            Selected = 1,
            Hint = 2,
            Solution = 3,
        }
    
    
        [SerializeField] protected List<TMP_Text> FactText;
        [SerializeField] protected List<string> StringLabelFormats;
    
        public Material[] materials;
        public new Renderer[] renderer;
    
        protected List<FactObject> AllChildren;
    
    
        #region Unity Serialization
        public Material Default;
        public Material Selected;
        public Material Hint;
        public Material Solution;
    
        void ISerializationCallbackReceiver.OnBeforeSerialize()
        {
    
            if (FactText == null || FactText.Count() == 0)
            {
                FactText = transform
    
                    .GetComponentsInChildren<TMP_Text>(includeInactive: true)
    
                    .ToList();
            }
    
            {
                StringLabelFormats ??= new();
    
                int i = StringLabelFormats.Count();
                int end = FactText.Count();
    
    
                for (; i < end; i++)
                    StringLabelFormats.Add("{" + (i + 1) + "}");
            }
    
            if (materials != null)
            {
                Default = materials[(int)FactMaterials.Default];
                Selected = materials[(int)FactMaterials.Selected];
                Hint = materials[(int)FactMaterials.Hint];
                Solution = materials[(int)FactMaterials.Solution];
            }
    
    
    #if UNITY_EDITOR // not working
            if (EditorApplication.isPlaying)
                return;
    
            foreach (Collider collider in transform.GetComponentsInChildren<Collider>(includeInactive: true))
            {
                if (!collider.gameObject.GetComponent<FactObject>())
                    try
                    {
                        collider.gameObject.AddComponent<FactObject>();
                    }
                    catch(Exception) { }
            }
    #endif
    
        }
    
        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()
        {
    
            AllChildren = transform.GetComponentsInChildren<FactObject>(includeInactive: true).ToList();
            AllChildren.Remove(this);
        }
    
    
    MaZiFAU's avatar
    MaZiFAU committed
        protected override void FactUpdated()
    
        {
            Awake();
    
            ReLabel();
    
            foreach (FactObject childObject in AllChildren)
            {
                childObject._URI = _URI;
                childObject._Fact = null;
    
    MaZiFAU's avatar
    MaZiFAU committed
                childObject.ReLabel();
    
        public void ReLabel()
        {
            string[] mother_child_labels =
                new[] { URI }.ShallowCloneAppend(Fact.DependentFactIds)
    
                .Select(fid =>
                    FactOrganizer.AllFacts.TryGetValue(fid, out Fact fact)
                    ? fact.Label
                    : "N/A")
    
                .ToArray();
    
            string indexoverflow = "{" + mother_child_labels.Length.ToString() + "}";
    
            for (int i = 0; i < Math.Min(FactText.Count(), StringLabelFormats.Count()); i++)
            {
                if (StringLabelFormats[i].Contains(indexoverflow))
                {
                    Debug.LogWarning("Format contains illegal Argument and will be ignored: " + indexoverflow);
                    continue;
                }
                FactText[i].text = string.Format(StringLabelFormats[i], mother_child_labels);
            }
    
    
            switch (Fact) // for highly customized labels
            {
                case TestFact testFact:
                    //FactText[0].text = testFact.Label;
                    break;
                default:
                    break;
            }
    
        public void CascadeForMeAndChildren(Action<FactObject> func)
    
            func(this);
            foreach (FactObject fo in AllChildren)
    
                func(fo);
        }
    
        public void ForAllRenderer(Action<Renderer> func)
        {
            foreach (Renderer ren in renderer)
                func(ren);
        }
    
    
        public void CoroutineCascadeForMeAndChildrenAllRenderer(Func<FactObject, Renderer, IEnumerator> func)
    
        {
            this.StopAllCoroutines();
    
    
            CascadeForMeAndChildren((FactObject fo) =>
                fo.ForAllRenderer((Renderer ren) =>
    
                    this.StartCoroutine(func(fo, ren))
    
    Richard Marcus's avatar
    Richard Marcus committed
    }