// Update is called once per frame void Update() { #if !UNITY_EDITOR // Keep checking the searching Task if (currHelper.academicStatus == MicrosoftAPIHelper.SERVICE_STATUS.PENDING) { //TODO: show animition to avoid confusion. // Note: not always. The app may be just pre-loading. } else if (currHelper.academicStatus == MicrosoftAPIHelper.SERVICE_STATUS.DONE) { // Step 2: Call functions to use this result. string jsonResult = currHelper.academicResult; Debug.Log("Received Academic Search Result, length:" + jsonResult.Length); // Debug; //SearchContent.text = jsonResult.Length.ToString(); currHelper.academicStatus = MicrosoftAPIHelper.SERVICE_STATUS.IDLE; var task = Task.Run(() => ParseJSONResults(jsonResult)); } else if (currHelper.academicStatus == MicrosoftAPIHelper.SERVICE_STATUS.ERROR) { SetErrorInfo(currHelper.academicResult); currHelper.academicStatus = MicrosoftAPIHelper.SERVICE_STATUS.IDLE; } // Keep checking the parsing Task if (parsingStatus == PARSING_STATUS.DONE) { Debug.Log("Received parsing results." + currPageOnUI + "," + currTargetPage); // Step 3: Render the results on the UI (and cancel the waiting info animation) isWaitingResults = false; if (currTargetPage == currPageOnUI && currSearchType == SearchType.ONLINE) { // Need to render. The user is waiting for this page. RenderResults(); UpdateButtonStatus(); } parsingStatus = PARSING_STATUS.IDLE; // Continue pre-loading: keep checking if (currMaxPage < 0 && currTargetPage < currPageOnUI + 2 && currSearchType == SearchType.ONLINE) { // New step 1: if we need to cache the next page (up to 2 pages) // and if we can cache the next page (max page not met) currTargetPage += 1; parsingStatus = PARSING_STATUS.WAITING; var task = Task.Run(() => currHelper.AcademicSearch(onlineSearchContent, RESULTS_PER_PAGE, currResults.Count)); } } #endif }
/// <summary> /// Create a unified logic for jumpping left/right, or clicking page number directly. /// </summary> /// <param name="pageNum">Page Number on UI (starting from 1). </param> /// <param name="pageID">Page ID based on BtnPages (range: 0,1,2). </param> private void JumpToPage(int pageNum, int pageID) { // Hide current focus box based on page ID SetPageButtonColor(currPageID, 0); // Set correct focus box based on page ID SetPageButtonColor(pageID, 255); // Set correct page numbers on UI for (int p = 0; p < BtnPages.Length; ++p) { // Calculate the correct value for page0, then loop over it. SetPageButtonText(p, (pageNum - pageID + p).ToString()); } // Update value currPageID = pageID; currPageOnUI = pageNum; // Update result entries if (Mathf.CeilToInt(currResults.Count / (float)RESULTS_PER_PAGE) >= pageNum) { // Update from cache RenderResults(); UpdateButtonStatus(); } else if (currTargetPage >= currPageOnUI) { // Already processing in the background. Need to play animation // TODO. // For the values, just need to wait. } // Need to resume pre-loading process // Continue pre-loading: keep checking if (currSearchType == SearchType.ONLINE && parsingStatus == PARSING_STATUS.IDLE && currMaxPage < 0 && currTargetPage < currPageOnUI + 2) { // New step 1: if we need to cache the next page (up to 2 pages) // and if we can cache the next page (max page not met) currTargetPage += 1; parsingStatus = PARSING_STATUS.WAITING; #if !UNITY_EDITOR var task = Task.Run(() => currHelper.AcademicSearch(onlineSearchContent, RESULTS_PER_PAGE, currResults.Count)); #endif } }
/// <summary> /// Helper function: parse the json string and turn it into ARDocument List. /// Note: this is slow, and the caller needs to put it into a separate Task. /// </summary> /// <param name="jsonResult"></param> /// <returns></returns> //private IEnumerator ParseJSONResults(string jsonResult) public void ParseJSONResults(string jsonResult) { parsingStatus = PARSING_STATUS.PENDING; List <ARDocument> parsedResults = new List <ARDocument>(); //academicResult.Clear(); // Parse to output the result. var result = JsonConvert.DeserializeObject <JSONAcademic.RootObject>(jsonResult); int counter = 0; string title = ""; var authorNames = new List <string>(); string majorLastName = ""; int year = 0; string source = ""; string pdfUrl = ""; //yield return null; foreach (var entity in result.entities) { //Debug.Log(string.Format("----------{0}----------", counter)); var dict = JsonConvert.DeserializeObject <Dictionary <string, dynamic> >(entity.E); //yield return null; // Names in "E" is well-organized. But they are not guranteed. title = ""; authorNames.Clear(); majorLastName = ""; year = entity.Y; source = ""; pdfUrl = ""; if (dict.ContainsKey("DN")) { title = dict["DN"]; } else { //Debug.LogWarning("DisplayName not exist. Have to manulay create them."); var titleWords = entity.Ti.Split(' '); foreach (var tw in titleWords) { title += tw[0].ToString().ToUpper() + tw.Substring(1) + " "; } } //Debug.Log("Title: " + title); if (dict.ContainsKey("ANF")) { dynamic authors = dict["ANF"]; majorLastName = authors[0]["LN"]; foreach (var author in authors) { // FN, LN, S authorNames.Add(string.Format("{0} {1}", author["FN"], author["LN"])); } } else { //Debug.LogWarning("ANF not exist. Have to manulay create them."); foreach (var author in entity.AA) { string lowerName = author.AuN; var authorWords = lowerName.Split(' '); var currAuthorName = ""; foreach (var aw in authorWords) { currAuthorName += aw[0].ToString().ToUpper() + aw.Substring(1) + " "; } authorNames.Add(currAuthorName); } majorLastName = authorNames[0].Split(' ').Last(); var titleWords = entity.Ti.Split(' '); foreach (var tw in titleWords) { title += tw[0].ToString().ToUpper() + tw.Substring(1) + " "; } } //Debug.Log("Authors: " + string.Join(" ", authorNames)); if (dict.ContainsKey("VSN") && dict["VSN"].Length > 0) { // short conf/journal name source = dict["VSN"]; } else if (dict.ContainsKey("PB") && dict["PB"].Length > 0) { // short journal name source = dict["PB"]; } else if (entity.C != null && entity.C.CN.Length > 0) { source = entity.C.CN.ToUpper(); } else if (entity.J != null && entity.J.JN.Length > 0) { source = entity.J.JN.ToUpper(); } else if (dict.ContainsKey("VFN") && dict["VFN"].Length > 0) { // full conf name source = dict["VFN"]; } else if (dict.ContainsKey("BV") && dict["BV"].Length > 0) { // full journal name source = dict["BV"]; } else { //Debug.LogWarning("Source not available."); } // Cut string idea from Stack overflow: https://stackoverflow.com/a/16236570/4762924 if (source.Length == 0) { source = "N/A"; } else if (source.Length >= 50) { // Try to cut at space int pos = source.LastIndexOf(" ", 40); // No space to space is too soon, just cut without thinking. if (pos <= 40) { pos = 50; } source = source.Substring(0, pos) + "..."; } //Debug.Log(string.Format("Source: {0}-({1})", source, year)); // S.Ty Source Type(1:HTML, 2:Text, 3:PDF, 4:DOC, 5:PPT, 6:XLS, 7:PS) // Sometimes I found type 0 also points to pdf link if (dict.ContainsKey("S")) { foreach (var urlDict in dict["S"]) { int urlType = urlDict["Ty"]; string urlContent = urlDict["U"]; if (urlType == 3) { pdfUrl = urlContent; break; } else if (urlType == 0 && urlContent.Contains("pdf")) { pdfUrl = urlContent; } else { //Debug.Log(string.Format("----{0}; {1}", urlType, urlContent)); } } } if (pdfUrl.Length > 0) { //Debug.Log("PDF available:" + pdfUrl); } // Last name of first author + last two digits of year string fileName = string.Format("{0}{1}", majorLastName, (year % 100).ToString("D2")); //Debug.Log("Named as:" + fileName); ARDocument doc = new ARDocument(fileName, title, authorNames.ToArray(), source, year, pdfUrl); parsedResults.Add(doc); ++counter; } Debug.Log(string.Format("Got {0} new results. Old results: {1}.", parsedResults.Count, currResults.Count)); currResults.AddRange(parsedResults); parsingStatus = PARSING_STATUS.DONE; }