Skip to content
Snippets Groups Projects
ScrollDetails.cs 11.4 KiB
Newer Older
  • Learn to ignore specific revisions
  • using System.Collections;
    using System.Collections.Generic;
    
    using UnityEngine;
    
    using TMPro;
    
    using UnityEngine.Networking;
    
    using Newtonsoft.Json;
    
    using System.Linq;
    
    MaZiFAU's avatar
    MaZiFAU committed
    using static CommunicationEvents;
    
    using static SOMDocManager;
    
    
    public class ScrollDetails : MonoBehaviour
    {
    
    Richard Marcus's avatar
    Richard Marcus committed
        public WorldCursor cursor;
    
        public GameObject parameterDisplayPrefab;
    
        public Scroll ActiveScroll;
    
        public GameObject mmtAnswerPopUp;
    
    MaZiFAU's avatar
    MaZiFAU committed
        private PopupBehavior Popup;
    
    MaZiFAU's avatar
    MaZiFAU committed
        public static List<RenderedScrollFact> ParameterDisplays;
    
        private static List<Scroll.ScrollAssignment> LatestCompletions;
    
        private static List<Fact> LatestRenderedHints;
    
    MaZiFAU's avatar
    MaZiFAU committed
        public bool DynamicScrollDescriptionsActive = true;
        public bool AutomaticHintGenerationActive = true;
    
    
    MaZiFAU's avatar
    MaZiFAU committed
        void Awake()
    
    MaZiFAU's avatar
    MaZiFAU committed
            if (cursor == null)
                cursor = FindObjectOfType<WorldCursor>();
    
            (Popup = mmtAnswerPopUp.GetComponent<PopupBehavior>())
                .hidePopUp();
    
    Richard Marcus's avatar
    Richard Marcus committed
    
    
        private void OnEnable()
        {
    
            ScrollFactHintEvent.AddListener(animateHint);
    
    MaZiFAU's avatar
    MaZiFAU committed
            NewAssignmentEvent.AddListener(NewAssignmentTrigger);
    
            RemoveFactEvent.AddListener(removeFactFromAssignment);
    
        private void OnDisable()
        {
            ScrollFactHintEvent.RemoveListener(animateHint);
    
    MaZiFAU's avatar
    MaZiFAU committed
            NewAssignmentEvent.RemoveListener(NewAssignmentTrigger);
    
            RemoveFactEvent.RemoveListener(removeFactFromAssignment);
    
    MaZiFAU's avatar
    MaZiFAU committed
        public void SetScroll(Scroll scroll_to_set)
    
    BenniHome's avatar
    BenniHome committed
        {
    
    MaZiFAU's avatar
    MaZiFAU committed
            ActiveScroll = scroll_to_set;
    
            Transform originalScroll = gameObject.transform.GetChild(1);
    
            Transform originalScrollView = originalScroll.GetChild(1);
            Transform originalViewport = originalScrollView.GetChild(0);
    
    
            //Clear all current ScrollFacts
    
            originalViewport.GetChild(0).gameObject.DestroyAllChildren();
    
    MaZiFAU's avatar
    MaZiFAU committed
            originalScroll.GetChild(0).GetComponent<TextMeshProUGUI>().text = ActiveScroll.description;
    
            //ParameterDisplays.ForEach(gameObj => Destroy(gameObj));
            ParameterDisplays = new();
            for (int i = 0; i < ActiveScroll.requiredFacts.Count; i++)
    
    BenniHome's avatar
    BenniHome committed
            {
    
    MaZiFAU's avatar
    MaZiFAU committed
                GameObject originalObj =
                    Instantiate(parameterDisplayPrefab, originalViewport.GetChild(0));
    
    MaZiFAU's avatar
    MaZiFAU committed
                RenderedScrollFact originalRSF =
                    originalObj.GetComponentInChildren<RenderedScrollFact>();
    
    MaZiFAU's avatar
    MaZiFAU committed
                ParameterDisplays.Add(originalRSF);
    
                originalRSF.Populate(ActiveScroll, i);
    
            foreach (int i in PrePopulateActiveScroll())
                ParameterDisplays[i].gameObject.SetActive(false);
    
    
            //set active scroll for ErrorMessagePopup
    
    MaZiFAU's avatar
    MaZiFAU committed
            Popup.setScroll(ActiveScroll);
            Popup.setParameterDisplays(ParameterDisplays.Select(RSF => RSF.gameObject).ToList());
    
        /// <summary>
        /// Secretly populates <see cref="Scroll"/>s
        /// </summary>
        /// <returns><c>Array</c> containing indicis of <see cref="Scroll.requiredFacts"/> to be hidden.</returns>
        private int[] PrePopulateActiveScroll()
        {
            switch (ActiveScroll.@ref)
            {
                case MMT_OMS_URI.ScrollAngleSum:
                    return new int[0];
    
                default:
                    return new int[0];
            }
        }
    
    
    MaZiFAU's avatar
    MaZiFAU committed
        public void MagicButtonTrigger()
    
    MaZiFAU's avatar
    MaZiFAU committed
            StartCoroutine(_MagicButton());
    
    MaZiFAU's avatar
    MaZiFAU committed
            IEnumerator _MagicButton()
    
    BenniHome's avatar
    BenniHome committed
            {
    
    MaZiFAU's avatar
    MaZiFAU committed
                yield return SendView("/scroll/apply");
    
    
                if (currentMmtAnswer == null)
                {
    
    MaZiFAU's avatar
    MaZiFAU committed
                    Debug.LogError("Magic FAILED");
    
                    PushoutFactFailEvent.Invoke(null, null);
                }
                else
                {
    
    MaZiFAU's avatar
    MaZiFAU committed
                    if (VerboseURI)
                        Debug.Log("Magic answers:\n" + currentMmtAnswer);
    
    
                    Scroll.ScrollApplicationInfo pushout = JsonConvert.DeserializeObject<Scroll.ScrollApplicationInfo>(currentMmtAnswer);
    
    MaZiFAU's avatar
    MaZiFAU committed
    
    
                    if (pushout.acquiredFacts.Count == 0)
                        PushoutFactFailEvent.Invoke(null, pushout);
    
    MaZiFAU's avatar
    MaZiFAU committed
    
                    ReadPushout(pushout.acquiredFacts);
    
    John Schihada's avatar
    John Schihada committed
    
    
    MaZiFAU's avatar
    MaZiFAU committed
        public void NewAssignmentTrigger()
    
    MaZiFAU's avatar
    MaZiFAU committed
            if (AutomaticHintGenerationActive || DynamicScrollDescriptionsActive)
                StartCoroutine(_NewAssignment());
    
    MaZiFAU's avatar
    MaZiFAU committed
            IEnumerator _NewAssignment()
    
                //Non blocking wait till sendView() is finished
    
    MaZiFAU's avatar
    MaZiFAU committed
                yield return SendView("/scroll/dynamic");
    
    
                if (currentMmtAnswer == null)
                {
    
    MaZiFAU's avatar
    MaZiFAU committed
                    Debug.LogError("Dynamic Scroll FAILED");
    
                }
                else
                {
                    Scroll.ScrollDynamicInfo scrollDynamicInfo = JsonConvert.DeserializeObject<Scroll.ScrollDynamicInfo>(currentMmtAnswer);
                    processScrollDynamicInfo(scrollDynamicInfo);
                }
    
    MaZiFAU's avatar
    MaZiFAU committed
        private IEnumerator SendView(string endpoint)
    
    BenniHome's avatar
    BenniHome committed
        {
    
            while (ParameterDisplays == null) // Wait for server
    
    MaZiFAU's avatar
    MaZiFAU committed
                yield return null;
    
    
            string body = prepareScrollAssignments();
    
    BenniHome's avatar
    BenniHome committed
    
    
            using UnityWebRequest www = UnityWebRequest.Put(ServerAdress + endpoint, body);
    
    BenniHome's avatar
    BenniHome committed
            www.method = UnityWebRequest.kHttpVerbPOST;
    
            www.SetRequestHeader("Content-Type", "application/json");
    
    MaZiFAU's avatar
    MaZiFAU committed
            System.DateTime sendTime = System.DateTime.UtcNow;
            yield return www.SendWebRequest();
            if (VerboseURI)
                Debug.LogFormat("Server answerd in : {0}ms"
                    , (System.DateTime.UtcNow - sendTime).TotalMilliseconds);
    
    BenniHome's avatar
    BenniHome committed
    
    
            if (www.result == UnityWebRequest.Result.ConnectionError
    
             || www.result == UnityWebRequest.Result.ProtocolError)
    
    BenniHome's avatar
    BenniHome committed
            {
                Debug.Log(www.error);
    
    Benjamin Bösl's avatar
    Benjamin Bösl committed
            }
    
                string answer = www.downloadHandler.text;
    
    MaZiFAU's avatar
    MaZiFAU committed
            string prepareScrollAssignments()
            {
                List<Scroll.ScrollAssignment> assignmentList = new();
    
    MaZiFAU's avatar
    MaZiFAU committed
                for (int i = 0; i < ParameterDisplays.Count; i++)
                {
                    Fact tempFact = ParameterDisplays[i].Fact;
                    if (tempFact != null)
                        assignmentList.Add(new Scroll.ScrollAssignment(ActiveScroll.requiredFacts[i].@ref.uri, tempFact.Id));
                }
    
    MaZiFAU's avatar
    MaZiFAU committed
                return JsonConvert.SerializeObject(new Scroll.FilledScroll(ActiveScroll.@ref, assignmentList));
    
    MaZiFAU's avatar
    MaZiFAU committed
        private void ReadPushout(List<MMTDeclaration> pushoutFacts)
    
    MaZiFAU's avatar
    MaZiFAU committed
            Popup.hidePopUp(); //close error Window
    
    MaZiFAU's avatar
    MaZiFAU committed
            for (int i = 0; i < pushoutFacts.Count; i++)
    
            {
                Fact newFact = ParsingDictionary.parseFactDictionary[pushoutFacts[i].getType()].Invoke(pushoutFacts[i]);
    
                if (newFact != null)
    
    MaZiFAU's avatar
    MaZiFAU committed
                {
    
                    AnimateExistingFactEvent.Invoke
                        (FactManager.AddFactIfNotFound(newFact, out _, samestep, null, ActiveScroll.label).Id
                        , FactWrapper.FactMaterials.Solution);
    
    MaZiFAU's avatar
    MaZiFAU committed
    
                    samestep = true;
                }
    
                    Debug.Log("Parsing on pushout-fact returned null -> One of the dependent facts does not exist");
    
    MaZiFAU's avatar
    MaZiFAU committed
        private void processScrollDynamicInfo(Scroll.ScrollDynamicInfo scrollDynamicInfo)
    
    MaZiFAU's avatar
    MaZiFAU committed
            LatestCompletions = scrollDynamicInfo.completions.Count > 0
                ? scrollDynamicInfo.completions[0]
    
                : new List<Scroll.ScrollAssignment>();
    
    MaZiFAU's avatar
    MaZiFAU committed
            List<string> hintUris = LatestCompletions
                .Select(completion => completion.fact.uri)
                .ToList();
    
            //Update Scroll, process data for later hints and update Uri-List for which hints are available
    
    MaZiFAU's avatar
    MaZiFAU committed
            _processRenderedScroll(scrollDynamicInfo.rendered, hintUris);
    
    MaZiFAU's avatar
    MaZiFAU committed
            if (AutomaticHintGenerationActive)
    
                //Show that Hint is available for ScrollParameter
                HintAvailableEvent.Invoke(hintUris);
    
    MaZiFAU's avatar
    MaZiFAU committed
            return;
    
    MaZiFAU's avatar
    MaZiFAU committed
            void _processRenderedScroll(Scroll rendered, List<string> hintUris)
    
    MaZiFAU's avatar
    MaZiFAU committed
                if (DynamicScrollDescriptionsActive)
                { // Update scroll-description
                    Transform scroll = gameObject.transform.GetChild(1).transform;
                    scroll.GetChild(0).GetComponent<TextMeshProUGUI>().text = rendered.description;
    
    MaZiFAU's avatar
    MaZiFAU committed
                LatestRenderedHints = new();
                for (int i = 0; i < rendered.requiredFacts.Count; i++)
    
    MaZiFAU's avatar
    MaZiFAU committed
                    RenderedScrollFact RenderedScrollFact = ParameterDisplays
    
                        .Find(RSF => RSF.ScrollFactURI == rendered.requiredFacts[i].@ref.uri);
    
    MaZiFAU's avatar
    MaZiFAU committed
                    if (DynamicScrollDescriptionsActive)
                        //Update ScrollParameter label
                        RenderedScrollFact.Scroll = rendered;
    
    MaZiFAU's avatar
    MaZiFAU committed
                    //If ScrollFact is assigned -> No Hint
                    if (RenderedScrollFact.Fact == null)
    
                        Fact HintFact =
                            ParsingDictionary.parseFactDictionary[rendered.requiredFacts[i].getType()]
                            .Invoke(rendered.requiredFacts[i]);
    
    MaZiFAU's avatar
    MaZiFAU committed
    
                        //If the fact could not be parsed -> Therefore not all dependent Facts exist -> No Hint
    
                        if (HintFact != null)
                        {
    
    MaZiFAU's avatar
    MaZiFAU committed
                            hintUris.Add(HintFact.Id);
                            LatestRenderedHints.Add(HintFact);
                        }
    
    MaZiFAU's avatar
    MaZiFAU committed
                return;
            }
    
        public void animateHint(ImageHintAnimation scrollHintImage, string scrollParameterUri)
    
            if (FactOrganizer.AllFacts.ContainsKey(scrollParameterUri))
                AnimateExistingFactEvent.Invoke(
                        scrollParameterUri,
                        FactWrapper.FactMaterials.Hint
                    );
    
            Scroll.ScrollAssignment suitableCompletion =
                LatestCompletions.Find(x => x.fact.uri == scrollParameterUri);
    
            Fact fact;
    
            if (suitableCompletion != null)
            {
    
    MaZiFAU's avatar
    MaZiFAU committed
                if (FactOrganizer.AllFacts.ContainsKey(suitableCompletion.assignment.uri))
    
                    AnimateExistingFactEvent.Invoke(
                        suitableCompletion.assignment.uri,
                        FactWrapper.FactMaterials.Hint
                    );
    
            else if (null !=
                (fact = LatestRenderedHints.Find(x => x.Id == scrollParameterUri)))
    
                if (FactOrganizer.AllFacts.ContainsKey(fact.Id))
                    // existing fact -> Animate that
                    AnimateExistingFactEvent.Invoke(
                        fact.Id,
                        FactWrapper.FactMaterials.Hint
                    );
    
                    // Generate new FactRepresentation and animate it
    
                    AnimateNonExistingFactEvent.Invoke(fact);
    
                    AnimateExistingFactEvent.Invoke(
                        scrollParameterUri,
                        FactWrapper.FactMaterials.Hint
                    );
    
        //this is called whenever a Fact is Deleted in the world, to make sure it is removed from the scroll
        public void removeFactFromAssignment(Fact fact)
    
            Transform originalScroll = gameObject.transform.GetChild(1).transform;
            Transform originalScrollView = originalScroll.GetChild(1);
            Transform originalViewport = originalScrollView.GetChild(0);
    
            for (int i = 0; i < originalViewport.GetChild(0).childCount; i++)
            {
                RenderedScrollFact scrollFact = originalViewport.GetChild(0).transform.GetChild(i).GetChild(0).gameObject.GetComponent<RenderedScrollFact>();
    
    MaZiFAU's avatar
    MaZiFAU committed
                if (scrollFact.ScrollFactLabel == fact.Label)
                    scrollFact.OnPointerClick(null);