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);
default:
return new int[0];
}
MaZiFAU
committed
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
200
201
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
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
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++)
{
//yield return null;
List<Fact> new_list = ParsingDictionary.parseFactDictionary[pushoutFacts[i].getType()]
(pushoutFacts[i].MapURIs(oldt_to_new));
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)
{
//yield return null;
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);
}
}
}
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 =
ParsingDictionary.parseFactDictionary[rendered.requiredFacts[i].getType()]
.Invoke(rendered.requiredFacts[i]);
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
);