// ---------[ ACCESSOR FUNCTIONS ]--------- /// <summary>Requests an individual ModStatistics by id.</summary> public virtual void RequestModStatistics(int modId, Action <ModStatistics> onSuccess, Action <WebRequestError> onError) { ModStatistics stats = null; if (!this.cache.TryGetValue(modId, out stats)) { stats = CacheClient.LoadModStatistics(modId); this.cache.Add(modId, stats); } if (this.IsValid(stats)) { onSuccess(stats); } else { APIClient.GetModStats(modId, (s) => { if (this != null) { this.cache[modId] = s; } onSuccess(s); }, onError); } }
// ---------[ UPDATE VIEW ]--------- public void DisplayMod(ModProfile profile, ModStatistics statistics, IEnumerable <ModTagCategory> tagCategories, bool isModSubscribed, bool isModEnabled) { // TODO(@jackson): Remove if (profile == null) { return; } this.profile = profile; this.statistics = statistics; this.isModSubscribed = isModSubscribed; this.isModEnabled = isModEnabled; if (modView != null) { modView.DisplayMod(profile, statistics, tagCategories, isModSubscribed, isModEnabled); if (modView.mediaContainer != null) { ModMediaCollection media = profile.media; bool hasMedia = media != null; hasMedia &= ((media.youTubeURLs != null && media.youTubeURLs.Length > 0) || (media.galleryImageLocators != null && media.galleryImageLocators.Length > 0)); modView.mediaContainer.gameObject.SetActive(hasMedia); } } if (selectedMediaPreview != null) { selectedMediaPreview.DisplayLogo(profile.id, profile.logoLocator); } // - version history - if (versionHistoryContainer != null && versionHistoryItemPrefab != null) { foreach (Transform t in versionHistoryContainer) { GameObject.Destroy(t.gameObject); } RequestFilter modfileFilter = new RequestFilter(); modfileFilter.sortFieldName = ModIO.API.GetAllModfilesFilterFields.dateAdded; modfileFilter.isSortAscending = false; APIClient.GetAllModfiles(profile.id, modfileFilter, new APIPaginationParameters() { limit = 20 }, (r) => PopulateVersionHistory(profile.id, r.items), WebRequestError.LogAsWarning); } }
public void DisplayMod(ModProfile profile, ModStatistics statistics, IEnumerable <ModTagCategory> tagCategories, bool isModSubscribed, bool isModEnabled) { Debug.Assert(profile != null); this.modId = profile.id; }
// ---------[ UI FUNCTIONALITY ]------------ /// <summary>Displays the profiles in the mod container.</summary> protected virtual void DisplayProfiles(IList <ModProfile> profiles) { Debug.Assert(this.modContainer != null); if (profiles == null) { profiles = new ModProfile[0]; } // init vars int displayCount = profiles.Count; ModProfile[] displayProfiles = new ModProfile[displayCount]; ModStatistics[] displayStats = new ModStatistics[displayCount]; // build arrays for (int i = 0; i < displayCount; ++i) { ModProfile profile = profiles[i]; ModStatistics stats = null; if (profile != null) { stats = profile.statistics; } displayProfiles[i] = profile; displayStats[i] = stats; } // display this.modContainer.DisplayMods(displayProfiles, displayStats); }
// ---------[ UI FUNCTIONALITY ]--------- public override void DisplayStatistics(ModStatistics statistics) { Debug.Assert(statistics != null); ModStatisticsDisplayData statsData = ModStatisticsDisplayData.CreateFromStatistics(statistics); m_data = statsData; PresentData(); }
public void DisplayMod(ModProfile profile, ModStatistics statistics, IEnumerable <ModTagCategory> tagCategories, bool isSubscribed, bool isModEnabled, ModRatingValue userRating = ModRatingValue.None) { this.profile = profile; this.statistics = statistics; }
// ---------[ UI FUNCTIONALITY ]--------- /// <summary>Displays the appropriate field of a given statistics.</summary> public void DisplayStatistics(ModStatistics statistics) { this.m_statistics = statistics; // display object fieldValue = this.reference.GetValue(this.m_statistics); string displayString = ValueFormatting.FormatValue(fieldValue, this.formatting.method, this.formatting.toStringParameter); this.m_textComponent.text = displayString; }
// ---------[ ACCESSOR FUNCTIONS ]--------- /// <summary>Requests an individual ModStatistics by id.</summary> public virtual void RequestModStatistics(int modId, Action <ModStatistics> onSuccess, Action <WebRequestError> onError) { Debug.Assert(onSuccess != null); // check loaded cache ModStatistics cachedStats = null; if (this.cache.TryGetValue(modId, out cachedStats) && this.IsValid(cachedStats)) { onSuccess.Invoke(cachedStats); return; } CacheClient.LoadModStatistics(modId, (stats) => { if (this == null) { return; } if (this.IsValid(stats)) { this.cache.Add(modId, stats); if (onSuccess != null) { onSuccess.Invoke(stats); } } else { APIClient.GetModStats(modId, (s) => { if (this != null) { this.cache[modId] = s; } if (onSuccess != null) { onSuccess(s); } }, onError); } }); }
/// <summary>Returns the a ModStatistics if the object is cached and valid.</summary> public virtual ModStatistics TryGetValid(int modId) { ModStatistics stats = null; this.cache.TryGetValue(modId, out stats); if (this.IsValid(stats)) { return(stats); } else { return(null); } }
public static ModStatisticsDisplayData CreateFromStatistics(ModStatistics statistics) { ModStatisticsDisplayData statisticsData = new ModStatisticsDisplayData() { modId = statistics.modId, popularityRankPosition = statistics.popularityRankPosition, popularityRankModCount = statistics.popularityRankModCount, downloadCount = statistics.downloadCount, subscriberCount = statistics.subscriberCount, ratingCount = statistics.ratingCount, ratingPositiveCount = statistics.ratingPositiveCount, ratingNegativeCount = statistics.ratingNegativeCount, ratingWeightedAggregate = statistics.ratingWeightedAggregate, ratingDisplayText = statistics.ratingDisplayText, dateExpires = statistics.dateExpires, }; return(statisticsData); }
protected virtual void UpdateStatisticsDisplays(IEnumerable <ModStatistics> statsData) { if (statsData == null) { return; } List <ModStatistics> statsList = new List <ModStatistics>(statsData); foreach (ModView view in this.m_modViews) { if (view != null) { ModDisplayData data = view.data; ModStatistics stats = null; for (int i = 0; i < statsList.Count && stats == null; ++i) { stats = statsList[i]; if (stats.modId == data.profile.modId) { statsList.RemoveAt(i); } else { stats = null; } } if (stats != null) { data.statistics = ModStatisticsDisplayData.CreateFromStatistics(stats); view.data = data; } } } }
/// <summary>Requests a collection of ModStatistcs by id.</summary> public virtual void RequestModStatistics(IList <int> orderedIdList, Action <ModStatistics[]> onSuccess, Action <WebRequestError> onError) { ModStatistics[] results = new ModStatistics[orderedIdList.Count]; List <int> missingIds = new List <int>(orderedIdList.Count); // grab from cache for (int i = 0; i < orderedIdList.Count; ++i) { int modId = orderedIdList[i]; ModStatistics stats = null; this.cache.TryGetValue(modId, out stats); results[i] = stats; if (!this.IsValid(stats)) { missingIds.Add(modId); } } // check disk for any missing stats int missingIndex = 0; while (missingIndex < missingIds.Count) { int id = missingIds[missingIndex]; ModStatistics stats = CacheClient.LoadModStatistics(id); if (this.IsValid(stats)) { int resultIndex = orderedIdList.IndexOf(id); results[resultIndex] = stats; missingIds.RemoveAt(missingIndex); } else { ++missingIndex; } } // if no missing profiles, early out if (missingIds.Count == 0) { onSuccess(results); return; } // fetch missing statistics Action <List <ModStatistics> > onFetchStats = (modStatistics) => { if (this != null) { foreach (ModStatistics stats in modStatistics) { this.cache[stats.modId] = stats; } } foreach (ModStatistics stats in modStatistics) { int i = orderedIdList.IndexOf(stats.modId); if (i >= 0) { results[i] = stats; } } onSuccess(results); }; this.StartCoroutine(this.FetchAllModStatistics(missingIds.ToArray(), onFetchStats, onError)); }
// ---------[ UPDATE VIEW ]--------- public void Refresh() { Debug.Assert(this.m_isInitialized); Debug.Assert(this.modView != null); ModProfile profile = null; ModStatistics stats = null; // set initial values this.SetLoadingDisplay(true); this.modView.DisplayLoading(); if (this.selectedMediaPreview != null) { this.selectedMediaPreview.DisplayLoading(); } // early out if NULL_ID if (this.m_modId == ModProfile.NULL_ID) { return; } // delegate for pushing changes to mod view Action pushToView = () => { bool isModSubscribed = ModManager.GetSubscribedModIds().Contains(this.m_modId); bool isModEnabled = ModManager.GetEnabledModIds().Contains(this.m_modId); ModRatingValue rating = ModBrowser.instance.GetModRating(this.m_modId); if (profile != null) { modView.DisplayMod(profile, stats, this.m_tagCategories, isModSubscribed, isModEnabled, rating); // media container if (modView.mediaContainer != null) { ModMediaCollection media = profile.media; bool hasMedia = media != null; hasMedia &= ((media.youTubeURLs != null && media.youTubeURLs.Length > 0) || (media.galleryImageLocators != null && media.galleryImageLocators.Length > 0)); modView.mediaContainer.gameObject.SetActive(hasMedia); } // media preview if (selectedMediaPreview != null) { selectedMediaPreview.DisplayLogo(profile.id, profile.logoLocator); } } }; // profile ModProfileRequestManager.instance.RequestModProfile(this.m_modId, (p) => { if (this == null) { return; } this.SetLoadingDisplay(false); profile = p; pushToView(); }, WebRequestError.LogAsWarning); // statistics ModStatisticsRequestManager.instance.RequestModStatistics(this.m_modId, (s) => { if (this == null) { return; } stats = s; pushToView(); }, WebRequestError.LogAsWarning); // version history if (versionHistoryContainer != null && versionHistoryItemPrefab != null) { RequestFilter modfileFilter = new RequestFilter(); modfileFilter.sortFieldName = ModIO.API.GetAllModfilesFilterFields.dateAdded; modfileFilter.isSortAscending = false; APIClient.GetAllModfiles(this.m_modId, modfileFilter, new APIPaginationParameters() { limit = 10 }, (r) => { this.m_versionHistory = r.items; PopulateVersionHistory(); }, WebRequestError.LogAsWarning); } }
private void DisplayProfiles(IEnumerable <ModProfile> profileCollection, RectTransform pageTransform) { #if DEBUG if (!Application.isPlaying) { return; } #endif foreach (Transform t in pageTransform) { ModView view = t.GetComponent <ModView>(); if (view != null) { m_modViews.Remove(view); } GameObject.Destroy(t.gameObject); } List <int> missingStatsData = new List <int>(); List <ModView> pageModViews = new List <ModView>(); if (profileCollection != null) { IList <int> subscribedModIds = ModManager.GetSubscribedModIds(); IList <int> enabledModIds = ModManager.GetEnabledModIds(); foreach (ModProfile profile in profileCollection) { if (pageModViews.Count >= itemsPerPage) { Debug.LogWarning("[mod.io] ProfileCollection contained more profiles than " + "can be displayed per page", this.gameObject); break; } GameObject itemGO = GameObject.Instantiate(itemPrefab, pageTransform); itemGO.name = "Mod Tile [" + pageModViews.Count.ToString() + "]"; // initialize item ModView view = itemGO.GetComponent <ModView>(); if (profile == null) { view.DisplayLoading(); } else { // add listeners view.onClick += (v) => ViewManager.instance.InspectMod(v.data.profile.modId); view.subscribeRequested += (v) => ModBrowser.instance.SubscribeToMod(v.data.profile.modId); view.unsubscribeRequested += (v) => ModBrowser.instance.UnsubscribeFromMod(v.data.profile.modId); view.enableModRequested += (v) => ModBrowser.instance.EnableMod(v.data.profile.modId); view.disableModRequested += (v) => ModBrowser.instance.DisableMod(v.data.profile.modId); view.ratePositiveRequested += (v) => ModBrowser.instance.AttemptRateMod(v.data.profile.modId, ModRatingValue.Positive); view.rateNegativeRequested += (v) => ModBrowser.instance.AttemptRateMod(v.data.profile.modId, ModRatingValue.Negative); // display ModStatistics stats = ModStatisticsRequestManager.instance.TryGetValid(profile.id); bool isModSubscribed = subscribedModIds.Contains(profile.id); bool isModEnabled = enabledModIds.Contains(profile.id); ModRatingValue ratingValue = ModBrowser.instance.GetModRating(profile.id); view.DisplayMod(profile, stats, m_tagCategories, isModSubscribed, isModEnabled, ratingValue); if (stats == null) { missingStatsData.Add(profile.id); } } pageModViews.Add(view); } if (pageModViews.Count > 0) { for (int i = pageModViews.Count; i < itemsPerPage; ++i) { GameObject spacer = new GameObject("Spacing Tile [" + i.ToString("00") + "]", typeof(RectTransform)); spacer.transform.SetParent(pageTransform); } } } m_modViews.AddRange(pageModViews); if (missingStatsData.Count > 0) { ModStatisticsRequestManager.instance.RequestModStatistics(missingStatsData, (statsArray) => { if (this != null) { UpdateStatisticsDisplays(statsArray); } }, WebRequestError.LogAsWarning); } // fix layouting if (this.isActiveAndEnabled) { LayoutRebuilder.MarkLayoutForRebuild(pageTransform); } }
public abstract void DisplayStatistics(ModStatistics statistics);
protected virtual void DisplayProfiles(IList <ModProfile> profileCollection, ModContainer modContainer) { Debug.Assert(modContainer != null); if (profileCollection == null) { profileCollection = new ModProfile[0]; } // init vars int displayCount = profileCollection.Count; ModProfile[] displayProfiles = new ModProfile[displayCount]; ModStatistics[] displayStats = new ModStatistics[displayCount]; List <int> missingStatsData = new List <int>(displayCount); // build arrays for (int i = 0; i < displayCount; ++i) { ModProfile profile = profileCollection[i]; ModStatistics stats = null; if (profile != null) { stats = ModStatisticsRequestManager.instance.TryGetValid(profile.id); if (stats == null) { missingStatsData.Add(profile.id); } } displayProfiles[i] = profile; displayStats[i] = stats; } // display modContainer.DisplayMods(displayProfiles, displayStats); // fetch missing stats if (missingStatsData.Count > 0) { ModStatisticsRequestManager.instance.RequestModStatistics(missingStatsData, (statsArray) => { if (this != null && modContainer != null) { // verify still valid bool doPushStats = (displayProfiles.Length == modContainer.modProfiles.Length); for (int i = 0; doPushStats && i < displayProfiles.Length; ++i) { // check profiles match ModProfile profile = displayProfiles[i]; doPushStats = (profile == modContainer.modProfiles[i]); if (doPushStats && profile != null && displayStats[i] == null) { // get missing stats foreach (ModStatistics stats in statsArray) { if (stats != null && stats.modId == profile.id) { displayStats[i] = stats; break; } } } } // push display data if (doPushStats) { modContainer.DisplayMods(displayProfiles, displayStats); } } }, WebRequestError.LogAsWarning); } }
// ---------[ UI FUNCTIONALITY ]------------ public void DisplayProfiles(IEnumerable <ModProfile> profileCollection) { #if DEBUG if (!Application.isPlaying) { return; } #endif // sort lists List <ModProfile> orderedProfileList = new List <ModProfile>(); List <int> removedProfiles = new List <int>(m_viewMap.Keys); if (profileCollection != null) { foreach (ModProfile profile in profileCollection) { if (profile != null) { orderedProfileList.Add(profile); removedProfiles.Remove(profile.id); } } } // ensure there are enough game objects int excessProfileCount = orderedProfileList.Count - m_viewMap.Count; for (int i = 0; i < excessProfileCount; ++i) { // create GameObject GameObject viewGO = GameObject.Instantiate(itemPrefab, scrollView.content); ModView view = viewGO.GetComponent <ModView>(); // add listeners view.onClick += (v) => ViewManager.instance.InspectMod(v.data.profile.modId); view.subscribeRequested += (v) => ModBrowser.instance.SubscribeToMod(v.data.profile.modId); view.unsubscribeRequested += (v) => ModBrowser.instance.UnsubscribeFromMod(v.data.profile.modId); view.enableModRequested += (v) => ModBrowser.instance.EnableMod(v.data.profile.modId); view.disableModRequested += (v) => ModBrowser.instance.DisableMod(v.data.profile.modId); view.ratePositiveRequested += (v) => ModBrowser.instance.AttemptRateMod(v.data.profile.modId, ModRatingValue.Positive); view.rateNegativeRequested += (v) => ModBrowser.instance.AttemptRateMod(v.data.profile.modId, ModRatingValue.Negative); // register in map int fakeModId = -i - 1; m_viewMap.Add(fakeModId, view); removedProfiles.Add(fakeModId); } // order the game objects and display new mods var enabledMods = ModManager.GetEnabledModIds(); List <int> missingStatsData = new List <int>(); for (int i = 0; i < orderedProfileList.Count; ++i) { ModProfile profile = orderedProfileList[i]; ModView view; if (!m_viewMap.TryGetValue(profile.id, out view)) { // collect unused view int oldModId = removedProfiles[0]; removedProfiles.RemoveAt(0); view = m_viewMap[oldModId]; m_viewMap.Remove(oldModId); m_viewMap.Add(profile.id, view); // display mod ModStatistics stats = ModStatisticsRequestManager.instance.TryGetValid(profile.id); view.DisplayMod(orderedProfileList[i], stats, this.m_tagCategories, true, // assume subscribed enabledMods.Contains(profile.id), ModBrowser.instance.GetModRating(profile.id)); if (stats == null) { missingStatsData.Add(profile.id); } } view.transform.SetSiblingIndex(i); } // remove unused profiles foreach (int removedId in removedProfiles) { GameObject.Destroy(m_viewMap[removedId].gameObject); m_viewMap.Remove(removedId); } // result count if (resultCount != null) { resultCount.text = m_viewMap.Count.ToString(); } // no results int subCountTotal = ModManager.GetSubscribedModIds().Count; if (noSubscriptionsDisplay != null) { noSubscriptionsDisplay.SetActive(subCountTotal == 0); } if (noResultsDisplay != null) { noResultsDisplay.SetActive(subCountTotal > 0 && m_viewMap.Count == 0); } if (missingStatsData.Count > 0) { ModStatisticsRequestManager.instance.RequestModStatistics(missingStatsData, (statsArray) => { if (this != null) { UpdateStatisticsDisplays(statsArray); } IList <int> subbedIds = ModManager.GetSubscribedModIds(); foreach (ModStatistics stats in statsArray) { if (subbedIds.Contains(stats.modId)) { CacheClient.SaveModStatistics(stats); } } }, // TODO(@jackson): something null); } // fix layouting if (this.isActiveAndEnabled) { LayoutRebuilder.MarkLayoutForRebuild(scrollView.GetComponent <RectTransform>()); } }
public void DisplayMod(ModProfile profile, ModStatistics statistics, IEnumerable <ModTagCategory> tagCategories, bool isSubscribed, bool isModEnabled, ModRatingValue userRating = ModRatingValue.None) { Debug.Assert(profile != null); if (this.m_displayDelegates == null) { CollectDelegates(); } m_data = new ModDisplayData(); foreach (DisplayProfileDelegate displayDelegate in m_displayDelegates) { displayDelegate(profile); } foreach (ProfileParserDelegate parserDelegate in m_missingDisplayParsers) { parserDelegate(profile, ref m_data); } // - tags - if (tagsDisplay != null) { tagsDisplay.DisplayTags(profile, tagCategories); } else { m_data.tags = ModTagDisplayData.GenerateArray(profile.tagNames, tagCategories); } // - stats - ModStatisticsDisplayData statsData; if (statistics == null) { statsData = new ModStatisticsDisplayData() { modId = profile.id, }; } else { statsData = ModStatisticsDisplayData.CreateFromStatistics(statistics); } if (statisticsDisplay != null) { statisticsDisplay.data = statsData; } else { m_data.statistics = statsData; } // - download - FileDownloadInfo downloadInfo = DownloadClient.GetActiveModBinaryDownload(m_data.profile.modId, m_data.currentBuild.modfileId); DisplayDownload(downloadInfo); // - subscribed - if (subscriptionDisplay != null) { subscriptionDisplay.isOn = isSubscribed; } m_data.isSubscribed = isSubscribed; // - enabled - if (modEnabledDisplay != null) { modEnabledDisplay.isOn = isModEnabled; } m_data.isModEnabled = isModEnabled; // - rating - if (userRatingDisplay.positive != null) { userRatingDisplay.positive.isOn = (userRating == ModRatingValue.Positive); } if (userRatingDisplay.negative != null) { userRatingDisplay.negative.isOn = (userRating == ModRatingValue.Negative); } m_data.userRating = userRating; #if UNITY_EDITOR if (Application.isPlaying) { // updates for inspection convenience GetData(); } #endif }
// ---------[ UTILITY ]--------- /// <summary>A convenience function for checking if a stats object should be refetched.</summary> protected virtual bool IsValid(ModStatistics statistics) { return(statistics != null && (!this.refetchIfExpired || ServerTimeStamp.Now < statistics.dateExpires)); }