Newer
Older
using System.Collections;
using System.Collections.Generic;
using Newtonsoft.Json;
public class ScrollDetails : MonoBehaviour
{
public static ScrollDetails Instance
{
get => _Instance;
set
{
if (_Instance == null)
_Instance = value;
else
Destroy(value);
}
}
private static ScrollDetails _Instance;
public GameObject parameterDisplayPrefab;
public static Scroll ActiveScroll { get; private set; }
public GameObject mmtAnswerPopUp;
public static List<RenderedScrollFact> ParameterDisplays { get; private set; }
private static List<ScrollAssignment> LatestBackwartsCompletions;
private static List<Fact> LatestRenderedHints;
John Schihada
committed
public string currentMmtAnswer;
public bool DynamicScrollDescriptionsActive = true;
public bool AutomaticHintGenerationActive = true;
MaZiFAU
committed
private bool SendingViewDone = true;
MaZiFAU
committed
private bool MagicInQue = false;
MaZiFAU
committed
private readonly IReadOnlyList<string> NoDynamicScroll = new List<string>() {
MMTConstants.ScrollCannonBall2D,
MMTConstants.ScrollCannonBall3D,
};
if (cursor == null)
cursor = FindObjectOfType<WorldCursor>();
Popup = mmtAnswerPopUp.GetComponent<PopupBehavior>();
Popup.gameObject.SetActive(true); // force Awake
ScrollFactHintEvent.AddListener(animateHint);
private void OnDisable()
{
ScrollFactHintEvent.RemoveListener(animateHint);
private void OnDestroy()
{
_Instance = null;
}
ActiveScroll = scroll_to_set;
Transform originalScroll = gameObject.transform.GetChild(1);
John Schihada
committed
Transform originalScrollView = originalScroll.GetChild(1);
Transform originalViewport = originalScrollView.GetChild(0);
originalViewport.GetChild(0).gameObject.DestroyAllChildren();
originalScroll.GetChild(0).GetComponent<TextMeshProUGUI>().text = ActiveScroll.description;
//ParameterDisplays.ForEach(gameObj => Destroy(gameObj));
ParameterDisplays = new();
for (int i = 0; i < ActiveScroll.requiredFacts.Count; i++)
if (ActiveScroll.requiredFacts[i] is MMTGeneralFact general
&& general.type is FUNTYPE)
continue;
GameObject originalObj =
Instantiate(parameterDisplayPrefab, originalViewport.GetChild(0));
RenderedScrollFact originalRSF =
originalObj.GetComponentInChildren<RenderedScrollFact>();
John Schihada
committed
ParameterDisplays.Add(originalRSF);
originalRSF.Populate(ActiveScroll, i);
foreach (int i in PrePopulateActiveScroll())
ParameterDisplays[i].transform.parent.gameObject.SetActive(false);
John Schihada
committed
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>
/// <returns><c>Array</c> containing indicis of <see cref="Scroll.requiredFacts"/> to be hidden.</returns>
private int[] PrePopulateActiveScroll()
{
MaZiFAU
committed
case MMTConstants.ScrollCannonBall2D:
string lid_override = StageStatic.stage.solution.MyFactSpace.Values
.FirstOrDefault(sol => sol is ListFact lf
&& lf.ListType is OMA tpOMA
&& tpOMA.arguments[0] is OMA tupelOMA_a
&& tupelOMA_a.arguments[0] is OMA tupelOMA_b
&& tupelOMA_b.applicant is OMS tupelOMS
&& tupelOMS.uri == MMTConstants.Product)
?.Id;
return CaseCanonBall(lid_override);
case MMTConstants.ScrollCannonBall3D:
lid_override = StageStatic.stage.solution.MyFactSpace.Values
.FirstOrDefault(sol => sol is ListFact lf
&& lf.ListType is OMA tpOMA
&& tpOMA.arguments[0] is OMA tupelOMA
&& tupelOMA.applicant is OMS tupelOMS
&& tupelOMS.uri == MMTConstants.Product)
?.Id;
MaZiFAU
committed
return CaseCanonBall(lid_override);
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
case MMTConstants.ScrollCannonBallT3D:
lid_override = StageStatic.stage.solution.MyFactSpace.Values
.FirstOrDefault(sol => sol is ListFact lf
&& lf.ListType is OMA tpOMA
&& tpOMA.arguments[0] is OMS triOMS
&& triOMS.uri == MMTConstants.Triangle)
?.Id;
//List<TriangleFact> TriList = StageBehaviour.GenerateMMTCollider();
//string[] list = new string[TriList.Count];
//for (int i = 0; i < 100; i++)
//{
// list[i] = FactAdder.AddFactIfNotFound(TriList[i], out _, false, null, null).Id;
//}
//lid_override = FactAdder.AddFactIfNotFound(
// new ListFact(list, null, new OMS(MMTConstants.TYPE_TO_OMS[typeof(TriangleFact)]), StageStatic.stage.factState)
// , out _, false, null, null).Id;
//lid_override = FactAdder.AddFactIfNotFound(
// new DynamicListFact(
// TriList.ConvertAll(t => (object)t),
// SOMDoc.MakeShallowList(TriList.Select(t => t.Defines()).ToArray()),
// new OMS(MMTConstants.TYPE_TO_OMS[typeof(TriangleFact)]),
// StageStatic.stage.factState
// ),
// out _, false, null, null).Id;
return CaseCanonBall(lid_override);
MaZiFAU
committed
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
static int[] CaseCanonBall(string ListId)
{
if (ListId == null)
return new int[0];
RealLitFact[] reals = StageStatic.stage.solution.MyFactSpace.Values
.Select(sol => sol as RealLitFact)
.Where(sol => sol != null)
.ToArray();
PointFact[] points = StageStatic.stage.solution.MyFactSpace.Values
.Select(sol => sol as PointFact)
.Where(sol => sol != null)
.ToArray();
string
pid_ball = points[0].Id,
pid_vect = points[1].Id,
pid_grav = points[2].Id;
ParameterDisplays[0].URI = pid_ball;
ParameterDisplays[1].URI = pid_vect;
ParameterDisplays[2].URI = pid_grav;
ParameterDisplays[3].URI = reals[0].Id;
ParameterDisplays[4].URI = ListId;
return new int[] { 0, 1, 2, 3, 4 };
}
MaZiFAU
committed
if (MagicInQue)
yield break; // only need next in que to finish
MagicInQue = true;
while (!SendingViewDone || DynamicScrollInQue)
MaZiFAU
committed
MagicInQue = false;
if (currentMmtAnswer == null)
{
if (VerboseURI)
Debug.Log("Magic answers:\n" + currentMmtAnswer);
ScrollApplicationInfo pushout = JsonConvert.DeserializeObject<ScrollApplicationInfo>(currentMmtAnswer);
if (pushout.acquiredFacts.Count == 0
|| pushout.errors.Length > 0)
{
ScrollApplicationCheckingErrorEvent.Invoke(pushout.errors);
PushoutFactFailEvent.Invoke();
}
else
Popup.HidePopUp(); //close error Window
MaZiFAU
committed
yield return __GeneratePushoutFacts(pushout.acquiredFacts);
MaZiFAU
committed
IEnumerator __GeneratePushoutFacts(List<MMTFact> pushoutFacts)
{
List<Fact> new_facts = new();
Dictionary<string, string> oldt_to_new = new();
System.DateTime parseTime = System.DateTime.UtcNow;
bool samestep = false;
for (int i = 0; i < pushoutFacts.Count; i++)
{
List<Fact> new_list = new();
yield return ParsingDictionary.parseFactDictionary[pushoutFacts[i].getType()]
(new_list, pushoutFacts[i].MapURIs(oldt_to_new));
MaZiFAU
committed
if (new_list.Count == 0)
{
Debug.LogWarning("Parsing on pushout-fact returned empty List -> One of the dependent facts does not exist or parsing failed");
continue;
}
foreach (Fact new_fact in new_list)
{
Fact added = FactAdder.AddFactIfNotFound(new_fact, out bool exists, samestep, null, ActiveScroll.label);
if (!exists)
{
new_facts.Add(added);
AnimateExistingFactEvent.Invoke(added.Id, FactWrapper.FactMaterials.Solution);
samestep = true;
}
else
{
// AnimateExistingFactEvent.Invoke(_new, FactWrapper.FactMaterials.Hint); // Automaticly done in FactRecorder
oldt_to_new.Add(new_fact.Id, added.Id);
}
MaZiFAU
committed
}
}
Debug.Log($"Facts parsed within {(System.DateTime.UtcNow - parseTime).TotalMilliseconds}ms");
yield break;
}
if (ActiveScroll?.ScrollReference == null
|| NoDynamicScroll.Contains(ActiveScroll.ScrollReference))
return;
if (AutomaticHintGenerationActive || DynamicScrollDescriptionsActive)
StartCoroutine(_NewAssignment());
yield break; // only need next in que to finish
DynamicScrollInQue = true;
MaZiFAU
committed
while (!SendingViewDone)
yield return null; // if we dont wait => server will crash
if (currentMmtAnswer == null)
{
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);
}
MaZiFAU
committed
SendingViewDone = false;
while (ParameterDisplays == null) // Wait for server
string body = prepareScrollAssignments();
Marco Zimmer
committed
using UnityWebRequest www = UnityWebRequest.Put(ServerAdress + endpoint, body);
www.SetRequestHeader("Content-Type", "application/json");
System.DateTime sendTime = System.DateTime.UtcNow;
yield return www.SendWebRequest();
MaZiFAU
committed
//if (VerboseURI)
Debug.LogFormat("Server answerd in : {0}ms"
, (System.DateTime.UtcNow - sendTime).TotalMilliseconds);
if (www.result == UnityWebRequest.Result.ConnectionError
|| www.result == UnityWebRequest.Result.ProtocolError)
John Schihada
committed
currentMmtAnswer = null;
yield return null;
currentMmtAnswer = www.downloadHandler.text
.Replace("\"float\":null", "\"float\":0.0"); // cannot convert null to value type
MaZiFAU
committed
SendingViewDone = true;
yield break;
for (int i = 0; i < ParameterDisplays.Count; i++)
{
Fact tempFact = ParameterDisplays[i].Fact;
if (tempFact != null)
assignmentList.Add(new ScrollAssignment(ActiveScroll.requiredFacts[i].@ref.uri, tempFact.Id));
return JsonConvert.SerializeObject(new ScrollApplication(ActiveScroll.ScrollReference, assignmentList));
}
}
private void processScrollDynamicInfo(ScrollDynamicInfo scrollDynamicInfo)
LatestBackwartsCompletions = scrollDynamicInfo.backward_completions.Count > 0
? scrollDynamicInfo.backward_completions[0]
List<string> hintUris = LatestBackwartsCompletions
.Select(completion => completion.fact.uri)
.ToList();
//Update Scroll, process data for later hints and update Uri-List for which hints are available
_processRenderedScroll(scrollDynamicInfo.rendered, hintUris);
//Show that Hint is available for ScrollParameter
HintAvailableEvent.Invoke(hintUris);
void _processRenderedScroll(Scroll rendered, List<string> hintUris)
if (DynamicScrollDescriptionsActive)
{ // Update scroll-description
Transform scroll = gameObject.transform.GetChild(1).transform;
scroll.GetChild(0).GetComponent<TextMeshProUGUI>().text = rendered.description;
LatestRenderedHints = new();
for (int i = 0; i < rendered.requiredFacts.Count; i++)
RenderedScrollFact RenderedScrollFact = ParameterDisplays
.Find(RSF => RSF.ScrollFactURI == rendered.requiredFacts[i].@ref.uri);
if (DynamicScrollDescriptionsActive)
//Update ScrollParameter label
RenderedScrollFact.Scroll = rendered;
List<Fact> HintFactList = new();
ParsingDictionary.parseFactDictionary[rendered.requiredFacts[i].getType()]
.Invoke(HintFactList, rendered.requiredFacts[i])
.FastForward();
foreach (Fact HintFact in HintFactList)
hintUris.Add(HintFact.Id); // == rendered.requiredFacts[i].@ref.uri
public void animateHint(string scrollParameterUri)
AnimateExistingFactEvent.Invoke(
scrollParameterUri,
FactWrapper.FactMaterials.Hint
);
Fact hintFact = LatestRenderedHints.Find(x => x.Id == scrollParameterUri); // "Dictionary"
LatestBackwartsCompletions.Find((ScrollAssignment x) => x.fact.uri == scrollParameterUri); // "Dictionary"
if (suitableCompletion != null && suitableCompletion.assignment is OMS assignment)
if (FactRecorder.FindEquivalent(StageStatic.stage.factState.MyFactSpace, hintFact, out string found_key, out Fact _, out bool _, false))
// existing fact -> Animate that
AnimateExistingFactEvent.Invoke(
{ // Generate new FactRepresentation and animate it
AnimateNonExistingFactEvent.Invoke(hintFact);
AnimateExistingFactEvent.Invoke(
scrollParameterUri,
FactWrapper.FactMaterials.Hint
);