diff --git a/Assets/Scripts/InteractionEngine/CommunicationEvents.cs b/Assets/Scripts/InteractionEngine/CommunicationEvents.cs index 53045b795ddbdbc885919179bc8c123eafa56728..94bede147666faa83d7ea399a347b354b92525ad 100644 --- a/Assets/Scripts/InteractionEngine/CommunicationEvents.cs +++ b/Assets/Scripts/InteractionEngine/CommunicationEvents.cs @@ -4,6 +4,7 @@ using UnityEngine; using UnityEngine.Events; using System; +using static Scroll; public static class CommunicationEvents { @@ -14,7 +15,8 @@ public static class CommunicationEvents public static UnityEvent<Fact> AddFactEvent = new(); public static UnityEvent<Fact> RemoveFactEvent = new(); - public static UnityEvent<Fact, Scroll.ScrollApplicationInfo> PushoutFactFailEvent = new(); + public static UnityEvent<ScrollApplicationCheckingError[]> ScrollApplicationCheckingErrorEvent = new(); + public static UnityEvent PushoutFactFailEvent = new(); public static UnityEvent gameSucceededEvent = new(); public static UnityEvent gameNotSucceededEvent = new(); diff --git a/Assets/Scripts/InteractionEngine/FactHandling/FactOrganizer.cs b/Assets/Scripts/InteractionEngine/FactHandling/FactOrganizer.cs index 0654b7823d7462d96feeb8ec584f0bca28f1d36b..0fe2e8059c7e78037f3f5de49813f38b896435c5 100644 --- a/Assets/Scripts/InteractionEngine/FactHandling/FactOrganizer.cs +++ b/Assets/Scripts/InteractionEngine/FactHandling/FactOrganizer.cs @@ -1060,7 +1060,8 @@ public static bool FindEquivalent(IReadOnlyDictionary<string, Fact> FactSpace, F foreach (var entry in FactSpace) { - if (entry.Value.Equivalent(search)) + if ((allow_exact || entry.Key != search.Id) + && entry.Value.Equivalent(search)) { found_key = entry.Key; found_value = entry.Value; diff --git a/Assets/Scripts/InteractionEngine/FactHandling/FactWrapper/FactObject.cs b/Assets/Scripts/InteractionEngine/FactHandling/FactWrapper/FactObject.cs index 79908ec30e7c839c5df0bf150914bf4e91101b9f..cd0ae95831636a700c7952696a1200b7768bc396 100644 --- a/Assets/Scripts/InteractionEngine/FactHandling/FactWrapper/FactObject.cs +++ b/Assets/Scripts/InteractionEngine/FactHandling/FactWrapper/FactObject.cs @@ -10,7 +10,6 @@ /// <summary> /// <see cref="Fact.Id"/>/ <c>MonoBehaviour</c> wrapper to be attached to <see cref="Fact.WorldRepresentation"/> /// </summary> -//[DisallowMultipleComponent] public abstract class FactObject : FactWrapper, ISerializationCallbackReceiver { [SerializeField] protected List<TMP_Text> FactText; @@ -19,7 +18,7 @@ public abstract class FactObject : FactWrapper, ISerializationCallbackReceiver [NonSerialized] public Material[] Materials; protected Material[] MaterialsToChange; - [NonSerialized] + protected List<FactObject> AllSiblings; protected List<FactObject> AllChildren; #region Unity Serialization @@ -79,8 +78,10 @@ protected override void _Awake() { base._Awake(); - AllChildren = transform.GetComponentsInChildren<FactObject>(includeInactive: true).ToList(); - AllChildren.Remove(this); + AllSiblings = GetComponents<FactObject>().ToList(); + AllChildren = GetComponentsInChildren<FactObject>(includeInactive: true) + .Where(fO => !AllSiblings.Contains(fO)) + .ToList(); FactText ??= new(); StringLabelFormats ??= new(); diff --git a/Assets/Scripts/InteractionEngine/FactHandling/FactWrapper/FactObject3D.cs b/Assets/Scripts/InteractionEngine/FactHandling/FactWrapper/FactObject3D.cs index 027670ddbcc40dca4c1b15643a840bdef52a0918..d30f65d070dc34f1a7e492ffcd0a9cec7d59a568 100644 --- a/Assets/Scripts/InteractionEngine/FactHandling/FactWrapper/FactObject3D.cs +++ b/Assets/Scripts/InteractionEngine/FactHandling/FactWrapper/FactObject3D.cs @@ -3,7 +3,6 @@ using UnityEngine; using System.Collections; using UnityEditor; -using static GlobalBehaviour; /// <summary> /// <see cref="Fact.Id"/>/ <c>MonoBehaviour</c> wrapper to be attached to <see cref="Fact.WorldRepresentation"/> @@ -42,7 +41,7 @@ protected override void _Awake() { base._Awake(); - MaterialsToChange ??= renderer.SelectMany(r => r.materials).ToArray(); + MaterialsToChange ??= renderer?.SelectMany(r => r.materials).ToArray(); } protected override void _CustomReLabel() diff --git a/Assets/Scripts/InteractionEngine/FactHandling/FactWrapper/FactObjectUI.cs b/Assets/Scripts/InteractionEngine/FactHandling/FactWrapper/FactObjectUI.cs index 592a3a522140f55457410ac6cbad8ae133ff4217..52163edd4601751872f07f6fe4864c6beb55837f 100644 --- a/Assets/Scripts/InteractionEngine/FactHandling/FactWrapper/FactObjectUI.cs +++ b/Assets/Scripts/InteractionEngine/FactHandling/FactWrapper/FactObjectUI.cs @@ -1,4 +1,3 @@ -using MoreLinq; using System.Linq; using UnityEngine.UI; @@ -19,6 +18,8 @@ protected override void _Awake() { base._Awake(); + Images ??= new Image[0]; + if(MaterialsToChange == null) { MaterialsToChange = new UnityEngine.Material[Images.Length]; diff --git a/Assets/Scripts/InteractionEngine/FactHandling/FactWrapper/RenderedScrollFact.cs b/Assets/Scripts/InteractionEngine/FactHandling/FactWrapper/RenderedScrollFact.cs index be4926cb100392f34b8844de23cd669512032b83..d7bec1639417afb12215b4fbbc6c8f38161c0c45 100644 --- a/Assets/Scripts/InteractionEngine/FactHandling/FactWrapper/RenderedScrollFact.cs +++ b/Assets/Scripts/InteractionEngine/FactHandling/FactWrapper/RenderedScrollFact.cs @@ -4,7 +4,7 @@ using UnityEngine.EventSystems; using static CommunicationEvents; -public class RenderedScrollFact : FactObjectUI, IDropHandler, IPointerClickHandler +public class RenderedScrollFact : FactObjectUI, IDropHandler { #region Serializable public TextMeshProUGUI LabelMesh; @@ -34,6 +34,9 @@ public Scroll Scroll } private Scroll _Scroll; + public bool IsSet + => ScrollFactURI != URI; + public string ScrollFactURI => Scroll.requiredFacts[ID].@ref.uri; @@ -43,7 +46,7 @@ public string ScrollFactLabel protected override void FactUpdated() { - Destroy(RenderedFactObject); + Destroy(_Payload); NewAssignmentEvent.Invoke(); @@ -89,24 +92,31 @@ public void OnHintAvailable(List<string> uris) } #region DropHandling - private GameObject RenderedFactObject; + public FactObjectUI Payload + => _Payload == null ? null : _Payload.GetComponent<FactObjectUI>(); + + private GameObject _Payload; public void OnDrop(PointerEventData eventData) { - Fact = eventData.pointerDrag.GetComponent<FactObject>().Fact; + if (eventData.pointerDrag.TryGetComponent(out FactObjectUI factObject)) + SetByFactObject(factObject); + } + + public void SetByFactObject(FactObjectUI fOUI) + { + Fact = fOUI.Fact; if (VerboseURI) Debug.Log(Fact.Label + " was dropped on " + gameObject.name + " " + (ID + 1) + "/" + ScrollDetails.ParameterDisplays.Count + " label: " + ScrollFactLabel); - RenderedFactObject = // has to be: ..., Vector3.zero, Quaternion.identity => SetParent - Instantiate(eventData.pointerDrag, Vector3.zero, Quaternion.identity); + _Payload = // has to be: ..., Vector3.zero, Quaternion.identity => SetParent + Instantiate(fOUI.gameObject, Vector3.zero, Quaternion.identity); - RenderedFactObject.transform.SetParent(gameObject.transform, worldPositionStays: false); + _Payload.transform.SetParent(gameObject.transform, worldPositionStays: false); + _Payload.GetComponent<CanvasGroup>().blocksRaycasts = true; // Reverse drag effect } - - public void OnPointerClick(PointerEventData eventData) - => _DeleteFactEvent(null); #endregion DropHandling } diff --git a/Assets/Scripts/InteractionEngine/ShinyThings.cs b/Assets/Scripts/InteractionEngine/ShinyThings.cs index 5933e36d4c2b2fbe18d170de44fe2abaefc333f3..8701d50dd72bdaa3f852e355199bdf2a1f4e64b2 100644 --- a/Assets/Scripts/InteractionEngine/ShinyThings.cs +++ b/Assets/Scripts/InteractionEngine/ShinyThings.cs @@ -3,6 +3,7 @@ using System.Linq; using UnityEngine; using static FactWrapper; +using static Scroll; public class ShinyThings : MonoBehaviour { @@ -114,11 +115,11 @@ IEnumerator _BlossomAndDie() while (sparks.IsAlive()) yield return null; - GameObject.Destroy(firework); + Destroy(firework); } } - public void LetItRain(Fact startFact, Scroll.ScrollApplicationInfo _) + public void LetItRain() { // check if couroutine is waiting or finished if (!rain_wait.MoveNext() || !rain.MoveNext()) @@ -126,12 +127,12 @@ public void LetItRain(Fact startFact, Scroll.ScrollApplicationInfo _) StopCoroutine(rain); StartCoroutine(rain = _BlossomAndDie()); } - rain_wait = 0f.LerpInTime(0, timerDuration); //reset timer + rain_wait = IEnumeratorExtensions.ClockForSeconds(timerDuration); //reset timer IEnumerator _BlossomAndDie() { Destroy(active_rainwork); - active_rainwork = GameObject.Instantiate(RainPrefab, new Vector3(0, 40, 0), Quaternion.identity); + active_rainwork = Instantiate(RainPrefab, new Vector3(0, 40, 0), Quaternion.identity); Color start = directionalLight.color; // may not be original one for (IEnumerator<float> lerper = MathfExtensions.LerpInTime(0, 1, lerpTime) @@ -151,7 +152,7 @@ IEnumerator _BlossomAndDie() yield return null; } - GameObject.Destroy(active_rainwork); + Destroy(active_rainwork); } } } diff --git a/Assets/Scripts/InventoryStuff/DisplayFacts.cs b/Assets/Scripts/InventoryStuff/DisplayFacts.cs index fc54a78a47d753aa67716877c671a6e5054e54a6..129aa3b07df0d806abc8a09c34571fed3e576222 100644 --- a/Assets/Scripts/InventoryStuff/DisplayFacts.cs +++ b/Assets/Scripts/InventoryStuff/DisplayFacts.cs @@ -128,16 +128,14 @@ public void AddFact(Fact fact) ); display.transform.parent.transform.SetSiblingIndex(siblingIdx); + } - return; - - GameObject CreateDisplay(Fact fact, Transform transform) - { - var spot = Instantiate(FactSpotPrefab, transform); - spot.GetComponent<FactWrapper>().Fact = fact; + public static GameObject CreateDisplay(Fact fact, Transform transform) + { + var spot = Instantiate(FactSpotPrefab, transform); + spot.GetComponent<FactWrapper>().Fact = fact; - return InstantiateDisplay(fact, spot.transform); - } + return InstantiateDisplay(fact, spot.transform); } public static GameObject InstantiateDisplay(Fact fact, Transform transform) diff --git a/Assets/Scripts/InventoryStuff/ScrollDetails.cs b/Assets/Scripts/InventoryStuff/ScrollDetails.cs index eedf91dc552fb5df40e16d6abb8ee1482c291d4c..9da20bfbb9c06b29e63b96bfb3e5306bae9ffbb5 100644 --- a/Assets/Scripts/InventoryStuff/ScrollDetails.cs +++ b/Assets/Scripts/InventoryStuff/ScrollDetails.cs @@ -7,10 +7,24 @@ using System.Linq; using static CommunicationEvents; using static SOMDocManager; -using static GlobalBehaviour; +using System; +using static Scroll; public class ScrollDetails : MonoBehaviour { + public static ScrollDetails Instance + { + get => _Instance; + set + { + if (_Instance == null) + _Instance = value; + else + Destroy(value); + } + } + private static ScrollDetails _Instance; + public WorldCursor cursor; public GameObject parameterDisplayPrefab; public Scroll ActiveScroll; @@ -18,7 +32,7 @@ public class ScrollDetails : MonoBehaviour private PopupBehavior Popup; public static List<RenderedScrollFact> ParameterDisplays; - private static List<Scroll.ScrollAssignment> LatestCompletions; + private static List<ScrollAssignment> LatestCompletions; private static List<Fact> LatestRenderedHints; public string currentMmtAnswer; @@ -26,14 +40,17 @@ public class ScrollDetails : MonoBehaviour public bool DynamicScrollDescriptionsActive = true; public bool AutomaticHintGenerationActive = true; + private bool DynamicScrollDone = true; void Awake() { + Instance = this; + if (cursor == null) cursor = FindObjectOfType<WorldCursor>(); - (Popup = mmtAnswerPopUp.GetComponent<PopupBehavior>()) - .hidePopUp(); + Popup = mmtAnswerPopUp.GetComponent<PopupBehavior>(); + Popup.gameObject.SetActive(true); // force Awake } private void OnEnable() @@ -48,6 +65,11 @@ private void OnDisable() NewAssignmentEvent.RemoveListener(NewAssignmentTrigger); } + private void OnDestroy() + { + _Instance = null; + } + public void SetScroll(Scroll scroll_to_set) { ActiveScroll = scroll_to_set; @@ -84,6 +106,30 @@ public void SetScroll(Scroll scroll_to_set) Popup.ParameterDisplays = ParameterDisplays; } + public bool SetNextEmptyTo(FactObjectUI activator) + { + RenderedScrollFact check = ParameterDisplays + .Find(RSF => RSF != null + && RSF.Payload != null + && RSF.Payload.Equals(activator) + ); + + if (check != null) + { + check.URI = null; + return false; + } + + RenderedScrollFact empty = ParameterDisplays + .Find(RSF => !RSF.IsSet); + + if (empty == null) + return false; + + empty.SetByFactObject(activator); + return true; + } + /// <summary> /// Secretly populates <see cref="Scroll"/>s /// </summary> @@ -106,22 +152,31 @@ public void MagicButtonTrigger() IEnumerator _MagicButton() { + while (!DynamicScrollDone) + yield return null; // Wait for last assignment + + DynamicScrollDone = false; yield return SendView("/scroll/apply"); + DynamicScrollDone = true; if (currentMmtAnswer == null) { Debug.LogError("Magic FAILED"); - PushoutFactFailEvent.Invoke(null, null); + ScrollApplicationCheckingErrorEvent.Invoke(null); } else { if (VerboseURI) Debug.Log("Magic answers:\n" + currentMmtAnswer); - Scroll.ScrollApplicationInfo pushout = JsonConvert.DeserializeObject<Scroll.ScrollApplicationInfo>(currentMmtAnswer); + ScrollApplicationInfo pushout = JsonConvert.DeserializeObject<ScrollApplicationInfo>(currentMmtAnswer); - if (pushout.acquiredFacts.Count == 0) - PushoutFactFailEvent.Invoke(null, pushout); + if (pushout.acquiredFacts.Count == 0 + || pushout.errors.Length > 0) + { + ScrollApplicationCheckingErrorEvent.Invoke(pushout.errors); + PushoutFactFailEvent.Invoke(); + } ReadPushout(pushout.acquiredFacts); } @@ -135,8 +190,12 @@ public void NewAssignmentTrigger() IEnumerator _NewAssignment() { - //Non blocking wait till sendView() is finished + while (!DynamicScrollDone) + yield return null; // if we dont wait => server will crash + + DynamicScrollDone = false; yield return SendView("/scroll/dynamic"); + DynamicScrollDone = true; if (currentMmtAnswer == null) { @@ -144,7 +203,25 @@ IEnumerator _NewAssignment() } else { - Scroll.ScrollDynamicInfo scrollDynamicInfo = JsonConvert.DeserializeObject<Scroll.ScrollDynamicInfo>(currentMmtAnswer); + ScrollDynamicInfo scrollDynamicInfo; + try + { + scrollDynamicInfo = JsonConvert.DeserializeObject<ScrollDynamicInfo>(currentMmtAnswer); + } + catch (JsonSerializationException ex) + { + Debug.LogException(ex); + Debug.LogError("Could not Deserialize MMT aswer for /scroll/dynamic\n" + currentMmtAnswer); + yield break; + } + + ScrollApplicationCheckingError[] errors = scrollDynamicInfo.errors + .Where(err => err.kind != "nonTotal") // expected + .ToArray(); + + if (errors.Length > 0) + ScrollApplicationCheckingErrorEvent.Invoke(errors); + processScrollDynamicInfo(scrollDynamicInfo); } } @@ -181,22 +258,22 @@ private IEnumerator SendView(string endpoint) string prepareScrollAssignments() { - List<Scroll.ScrollAssignment> assignmentList = new(); + List<ScrollAssignment> assignmentList = new(); 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)); + assignmentList.Add(new ScrollAssignment(ActiveScroll.requiredFacts[i].@ref.uri, tempFact.Id)); } - return JsonConvert.SerializeObject(new Scroll.FilledScroll(ActiveScroll.@ref, assignmentList)); + return JsonConvert.SerializeObject(new FilledScroll(ActiveScroll.@ref, assignmentList)); } } private void ReadPushout(List<MMTDeclaration> pushoutFacts) { - Popup.hidePopUp(); //close error Window + Popup.HidePopUp(); //close error Window bool samestep = false; for (int i = 0; i < pushoutFacts.Count; i++) @@ -215,11 +292,11 @@ private void ReadPushout(List<MMTDeclaration> pushoutFacts) } } - private void processScrollDynamicInfo(Scroll.ScrollDynamicInfo scrollDynamicInfo) + private void processScrollDynamicInfo(ScrollDynamicInfo scrollDynamicInfo) { LatestCompletions = scrollDynamicInfo.completions.Count > 0 ? scrollDynamicInfo.completions[0] - : new List<Scroll.ScrollAssignment>(); + : new List<ScrollAssignment>(); List<string> hintUris = LatestCompletions .Select(completion => completion.fact.uri) @@ -253,7 +330,7 @@ void _processRenderedScroll(Scroll rendered, List<string> hintUris) RenderedScrollFact.Scroll = rendered; //If ScrollFact is assigned -> No Hint - if (RenderedScrollFact.Fact == null) + if (!RenderedScrollFact.IsSet) { Fact HintFact = ParsingDictionary.parseFactDictionary[rendered.requiredFacts[i].getType()] @@ -280,10 +357,11 @@ public void animateHint(string scrollParameterUri) FactWrapper.FactMaterials.Hint ); - Scroll.ScrollAssignment suitableCompletion = + Fact hintFact = LatestRenderedHints.Find(x => x.Id == scrollParameterUri); + + ScrollAssignment suitableCompletion = LatestCompletions.Find(x => x.fact.uri == scrollParameterUri); - Fact fact; if (suitableCompletion != null) { if (FactOrganizer.AllFacts.ContainsKey(suitableCompletion.assignment.uri)) @@ -294,10 +372,9 @@ public void animateHint(string scrollParameterUri) ); } } - else if (null != - (fact = LatestRenderedHints.Find(x => x.Id == scrollParameterUri))) + else if (hintFact != null) { - if (FactOrganizer.FindEquivalent(StageStatic.stage.factState.MyFactSpace, fact, out string found_key, out Fact _, out bool _, false)) + if (FactOrganizer.FindEquivalent(StageStatic.stage.factState.MyFactSpace, hintFact, out string found_key, out Fact _, out bool _, false)) // existing fact -> Animate that AnimateExistingFactEvent.Invoke( found_key, @@ -305,9 +382,8 @@ public void animateHint(string scrollParameterUri) ); else - { - // Generate new FactRepresentation and animate it - AnimateNonExistingFactEvent.Invoke(fact); + { // Generate new FactRepresentation and animate it + AnimateNonExistingFactEvent.Invoke(hintFact); AnimateExistingFactEvent.Invoke( scrollParameterUri, FactWrapper.FactMaterials.Hint diff --git a/Assets/Scripts/SOMDocManager.cs b/Assets/Scripts/SOMDocManager.cs index 271b8026a6453c1963e24f9251bc4c5ac456be61..2cc38fefdf94ed082e03da29999f4427aaebb683 100644 --- a/Assets/Scripts/SOMDocManager.cs +++ b/Assets/Scripts/SOMDocManager.cs @@ -313,6 +313,7 @@ private static LambdaExpression MakeArray(LambdaExpression[] args_lamda, Paramet [JsonSubtypes.KnownSubType(typeof(OMC<Vector3>), "OMC<UnityEngine.Vector3>")] [JsonSubtypes.KnownSubType(typeof(OMC<float>), "OMC<System.Single>")] [JsonSubtypes.KnownSubType(typeof(OMC<double>), "OMC<System.Double>")] + [JsonSubtypes.FallBackSubType(typeof(OMS))] // dirty fix for wrong formated ScrollApplicationCheckingError.fact abstract public class SOMDoc { public string kind; diff --git a/Assets/Scripts/UI/FactExplorer/FactExplorer.cs b/Assets/Scripts/UI/FactExplorer/FactExplorer.cs index 789f07de1c31e29362d1bb662db848a7f8ce44c2..34f39f3add6159f42246266e30fea5f99b7ddb3f 100644 --- a/Assets/Scripts/UI/FactExplorer/FactExplorer.cs +++ b/Assets/Scripts/UI/FactExplorer/FactExplorer.cs @@ -1,7 +1,4 @@ -using System; -using System.Collections; using System.Collections.Generic; -using System.Reflection; using UnityEngine; using System.Linq; using UnityEngine.UI; @@ -22,7 +19,7 @@ public class FactExplorer : MonoBehaviour #endregion InspectorVariables #region Variables - private Fact mainFact; + public Fact MainFact { get; private set; } private List<Fact> parentFacts; private List<Fact> childFacts; #endregion Variables @@ -35,7 +32,7 @@ private void Update() public void Initialize(Fact fact, Vector3 factPosition) { - mainFact = fact; + MainFact = fact; parentFacts = GetParentFacts(); childFacts = GetChildFacts(); @@ -50,20 +47,21 @@ public void Initialize(Fact fact, Vector3 factPosition) #region Implementation private List<Fact> GetParentFacts() - { - _ = StageStatic.stage.factState.safe_dependencies(mainFact.Id, out var parentFactIds); - return parentFactIds.Distinct().Select(factId => FactOrganizer.AllFacts[factId]).Where(f => f != mainFact).ToList(); + { + StageStatic.stage.factState.safe_dependencies(MainFact.Id, out var parentFactIds); + return parentFactIds.Distinct().Select(factId => FactOrganizer.AllFacts[factId]).Where(f => f != MainFact).ToList(); } private List<Fact> GetChildFacts() - { - return mainFact.DependentFactIds.Distinct().Select(factId => FactOrganizer.AllFacts[factId]).ToList(); - } + => MainFact.DependentFactIds + .Distinct() + .Select(factId => FactOrganizer.AllFacts[factId]) + .ToList(); private void UpdateFactExplorerUI() { SpawnUIFacts(factParentsUI, parentFacts); - SpawnUIFacts(mainFactUI, new List<Fact>() { mainFact }); + SpawnUIFacts(mainFactUI, new List<Fact>() { MainFact }); SpawnUIFacts(factChildrenUI, childFacts); // Force rebuild of FactExplorer layout, since the positions of the factObjects will be wrong otherwise @@ -76,8 +74,9 @@ private void UpdateFactExplorerUI() private void DestroyIfClickedOutside() { // Destroy on tab press or left click outside of FactExplorer - if (Input.GetKeyDown(KeyCode.Tab) - || (Input.GetMouseButtonDown(0) && !RectTransformUtility.RectangleContainsScreenPoint(transform.GetComponent<RectTransform>(), Input.mousePosition, null))) + if (Input.GetKeyDown(KeyCode.Tab) + || (Input.GetMouseButtonDown(0) + && !RectTransformUtility.RectangleContainsScreenPoint(transform.GetComponent<RectTransform>(), Input.mousePosition, null))) { Destroy(gameObject); } @@ -111,13 +110,8 @@ private void SpawnUIFacts(Transform uiParent, List<Fact> toSpawn) uiParent.gameObject.SetActive(false); foreach (Fact fact in toSpawn) - { - var spot = Instantiate(factSpotPrefab, uiParent); - - // TODO: this link to DisplayFacts is not ideal: maybe refactor to SciptableObject or such - var display = DisplayFacts.InstantiateDisplay(fact, spot.transform); - display.transform.localPosition = Vector3.zero; - } + // TODO: SE: this link to DisplayFacts is not ideal: maybe refactor to SciptableObject or such + DisplayFacts.CreateDisplay(fact, uiParent); } private void SpawnParentLines(GameObject parent, Transform mainFactUI) @@ -125,7 +119,7 @@ private void SpawnParentLines(GameObject parent, Transform mainFactUI) var mainTransform = mainFactUI.GetComponent<RectTransform>(); var factWidth = mainTransform.rect.width; // transform.positions are weird due to LayoutGroups => manually calculate offset - float xOffset = -factParentsUI.GetComponent<RectTransform>().rect.width / 2 + factWidth / 2; + float xOffset = -factParentsUI.GetComponent<RectTransform>().rect.width / 2 + factWidth / 2; float yOffset = transform.GetComponent<VerticalLayoutGroup>().spacing; parent.ForAllChildren(par => { @@ -155,7 +149,7 @@ private void SpawnChildLines(GameObject parent, Transform mainFactUI) var uiLine = line.GetComponent<UILine>(); uiLine.points = new List<Vector2>() { - Vector2.zero, + Vector2.zero, new Vector2(0, -yOffset/2), new Vector2(-xOffset, -yOffset/2), new Vector2(-xOffset, -yOffset) diff --git a/Assets/Scripts/UI/FactExplorer/OpenFactExplorer.cs b/Assets/Scripts/UI/FactExplorer/OpenFactExplorer.cs index 9d9bd45e06ba49f87db1e01c689fdf80d4c6632c..4f1afd71217476405c1192363a2be484336b2112 100644 --- a/Assets/Scripts/UI/FactExplorer/OpenFactExplorer.cs +++ b/Assets/Scripts/UI/FactExplorer/OpenFactExplorer.cs @@ -1,8 +1,6 @@ -using System; -using System.Collections; -using System.Collections.Generic; using UnityEngine; using UnityEngine.EventSystems; +using static UnityEngine.EventSystems.PointerEventData; [RequireComponent(typeof(FactWrapper), typeof(RectTransform), typeof(DragHandling))] public class OpenFactExplorer : MonoBehaviour, IPointerClickHandler @@ -13,23 +11,30 @@ public class OpenFactExplorer : MonoBehaviour, IPointerClickHandler private static Transform factExplorer; private float pressTime = 0f; private const float LONG_PRESS_DURATION = 0.5f; + private bool beganTouch = false; private DragHandling CachedDragHandling; + private FactWrapper CachedFactWrapper; #endregion Variables #region UnityMethods public void OnPointerClick(PointerEventData eventData) - { - // open FactExplorer on right click on PC - if (eventData.button == PointerEventData.InputButton.Right) - { + { // Handles PC clicks + if (eventData.dragging) + return; + + if (eventData.button == InputButton.Right) DoOpenFactExplorer(); - } + else + if (eventData.button == InputButton.Left + )//&& eventData.clickCount >= 2) + DoSetActive(); } private void Awake() { CachedDragHandling = GetComponent<DragHandling>(); + CachedFactWrapper = GetComponent<FactWrapper>(); } private void Update() @@ -57,31 +62,54 @@ private void HandleTouches() switch (touch.phase) { - case TouchPhase.Moved: case TouchPhase.Began: + beganTouch = true; + pressTime = 0; + break; + case TouchPhase.Ended: + if (beganTouch + && pressTime < LONG_PRESS_DURATION) + DoSetActive(); + goto case TouchPhase.Canceled; + + case TouchPhase.Moved: case TouchPhase.Canceled: + beganTouch = false; pressTime = 0; break; case TouchPhase.Stationary: pressTime += Time.deltaTime; if (pressTime >= LONG_PRESS_DURATION) + { DoOpenFactExplorer(); + goto case TouchPhase.Canceled; + } break; } } private void DoOpenFactExplorer() { - Destroy(factExplorer != null ? factExplorer.gameObject : null); + if (factExplorer != null + && factExplorer.GetComponent<FactExplorer>().MainFact.Id == CachedFactWrapper.URI) + { + Destroy(factExplorer.gameObject); + return; + } + + if (factExplorer != null) + Destroy(factExplorer.gameObject); var parent = transform.GetComponentInParent<Canvas>().transform; - var fact = transform.GetComponent<FactWrapper>().Fact; factExplorer = Instantiate(factExplorerPrefab.transform, Input.mousePosition, Quaternion.identity, parent); - factExplorer.GetComponent<FactExplorer>().Initialize(fact, transform.position); + factExplorer.GetComponent<FactExplorer>().Initialize(CachedFactWrapper.Fact, transform.position); } + + private bool DoSetActive() + => ScrollDetails.Instance.SetNextEmptyTo(CachedFactWrapper as FactObjectUI); #endregion Implementation } diff --git a/Assets/Scripts/UI/InGame/PopupBehavior.cs b/Assets/Scripts/UI/InGame/PopupBehavior.cs index 7228809397fcf048b620afb1b8c027ae488b08b8..bf528da2bd147f840710446bc1a63c49a24a659e 100644 --- a/Assets/Scripts/UI/InGame/PopupBehavior.cs +++ b/Assets/Scripts/UI/InGame/PopupBehavior.cs @@ -5,6 +5,7 @@ using UnityEngine.UI; using System.Linq; using static SOMDocManager; +using static Scroll; public class PopupBehavior : MonoBehaviour { @@ -12,6 +13,11 @@ public class PopupBehavior : MonoBehaviour [SerializeField] GameObject canvas; [SerializeField] Button CloseButton; [SerializeField] TMP_Text message; + public string MessageText + { + get => message.text; + set => message.text = value; + } public Scroll ActiveScroll { private get; set; } public List<RenderedScrollFact> ParameterDisplays { private get; set; } @@ -21,59 +27,56 @@ public class PopupBehavior : MonoBehaviour public string UnknownErrorMessage = "Unkown error - did you apply all facts?"; public string InvalidAssignmentMessage = "Invalid Assignment"; - private string errorMessage = ""; - // Start is called before the first frame update + private string errorMessage; + + #region UnityMethods void Awake() { - CommunicationEvents.PushoutFactFailEvent.AddListener(onFailedScrollInput); + CommunicationEvents.ScrollApplicationCheckingErrorEvent.AddListener(OnFailedScrollInput); CloseButton.onClick.RemoveAllListeners(); - CloseButton.onClick.AddListener(hidePopUp); - } + CloseButton.onClick.AddListener(HidePopUp); - public void setMessage(string errorMessage) - { - this.message.text = errorMessage; + HidePopUp(); } + #endregion UnityMethods - public void showPopUp() + public void ShowTimedPopUp() { canvas.SetActive(true); - StartCoroutine(hideAfter5sec()); + StartCoroutine(_BlossomAndDie()); - IEnumerator hideAfter5sec() + IEnumerator _BlossomAndDie() { - yield return new WaitForSeconds(5); - hidePopUp(); + yield return new WaitForSeconds(GlobalBehaviour.HintAnimationDuration); + HidePopUp(); } } - public void hidePopUp() - { - canvas.SetActive(false); - } + public void HidePopUp() + => canvas.SetActive(false); /// <summary> /// this method creates a helpful error message and shows the popup. For it to work properly, the setScroll and setParameterDisplays must have been set. /// </summary> /// <param name="startfact"></param> /// <param name="errorInfo"></param> - public void onFailedScrollInput(Fact startfact, Scroll.ScrollApplicationInfo errorInfo) + public void OnFailedScrollInput(ScrollApplicationCheckingError[] errorInfo) { - setMessage(generateHelpfulMessageAndAnimateScrollParam(errorInfo)); - showPopUp(); + MessageText = generateHelpfulMessageAndAnimateScrollParam(errorInfo); + ShowTimedPopUp(); } - private string generateHelpfulMessageAndAnimateScrollParam(Scroll.ScrollApplicationInfo errorInfo) + private string generateHelpfulMessageAndAnimateScrollParam(ScrollApplicationCheckingError[] errorInfo) { if (errorInfo == null) return ServerErrorMessage; int invAssCount = 0; errorMessage = ""; - for (int i = 0; i < errorInfo.errors.Length; i++) + for (int i = 0; i < errorInfo.Length; i++) { - Scroll.ScrollApplicationCheckingError error = errorInfo.errors[i]; + ScrollApplicationCheckingError error = errorInfo[i]; //check which error ocurred and set Message to a helpful error message. if (error.kind == "nonTotal") @@ -120,11 +123,11 @@ private string generateHelpfulMessageAndAnimateScrollParam(Scroll.ScrollApplicat } //this should be changed, the Fact Object should be parsed by JSON. This is a workaround because the MMT servers JSON serialization contains a bug - private MMTDeclaration parseFactFromError(Scroll.ScrollApplicationCheckingError error) + private MMTDeclaration parseFactFromError(ScrollApplicationCheckingError error) { if (error == null || error.msg == null) return null; - + string message = error.msg; //cut start of string @@ -145,6 +148,6 @@ private MMTDeclaration parseFactFromError(Scroll.ScrollApplicationCheckingError //find the required fact in the active scroll thats invalidly assigned return ActiveScroll?.requiredFacts - .FirstOrDefault(decl => decl.@ref.uri.Equals(factUri)); + .Find(decl => decl.@ref.uri == (error.fact as OMS).uri); } }