2 using System.Collections.Generic;
14 public event Action<IEnumerable<Package>> OnPackagesChanged = delegate { };
15 public event Action<PackageFilter> OnFilterChanged = delegate { };
17 private readonly Dictionary<string, Package> packages;
19 private PackageFilter filter;
21 private string selectedListPackage;
22 private string selectedSearchPackage;
24 internal string lastUpdateTime;
25 private List<PackageInfo> listPackagesOffline;
26 private List<PackageInfo> listPackages;
27 private List<PackageInfo> searchPackages;
29 private List<PackageError> packageErrors;
31 private int listPackagesVersion;
32 private int listPackagesOfflineVersion;
34 private bool searchOperationOngoing;
35 private bool listOperationOngoing;
36 private bool listOperationOfflineOngoing;
51 Instance.OnPackagesChanged = delegate { };
52 Instance.OnFilterChanged = delegate { };
53 Instance.SearchSignal.ResetEvents();
54 Instance.ListSignal.ResetEvents();
56 Instance.FetchListOfflineCache(
true);
57 Instance.FetchListCache(
true);
58 Instance.FetchSearchCache(
true);
64 Instance.RebuildPackageDictionary();
67 Instance.FetchListOfflineCache(Instance.listOperationOfflineOngoing);
68 Instance.FetchListCache(Instance.listOperationOngoing);
69 Instance.FetchSearchCache(Instance.searchOperationOngoing);
73 public PackageFilter Filter
75 get {
return filter; }
80 var changed = value != filter;
84 OnFilterChanged(filter);
88 public List<PackageInfo> LatestListPackages
90 get {
return listPackagesVersion > listPackagesOfflineVersion? listPackages : listPackagesOffline; }
93 public List<PackageInfo> LatestSearchPackages {
get {
return searchPackages; } }
95 public string SelectedPackage
97 get {
return PackageFilter.All == Filter ? selectedSearchPackage : selectedListPackage; }
100 if (PackageFilter.All == Filter)
101 selectedSearchPackage = value;
103 selectedListPackage = value;
109 packages =
new Dictionary<string, Package>();
111 listPackagesOffline =
new List<PackageInfo>();
112 listPackages =
new List<PackageInfo>();
113 searchPackages =
new List<PackageInfo>();
115 packageErrors =
new List<PackageError>();
117 listPackagesVersion = 0;
118 listPackagesOfflineVersion = 0;
120 searchOperationOngoing =
false;
121 listOperationOngoing =
false;
122 listOperationOfflineOngoing =
false;
124 Filter = PackageFilter.All;
127 public bool SetFilter(PackageFilter value,
bool refresh =
true)
135 UpdatePackageCollection();
140 public void UpdatePackageCollection(
bool rebuildDictionary =
false)
142 if (rebuildDictionary)
144 lastUpdateTime = DateTime.Now.ToString(
"HH:mm");
145 RebuildPackageDictionary();
148 OnPackagesChanged(OrderedPackages());
151 internal void FetchListOfflineCache(
bool forceRefetch =
false)
153 if (!forceRefetch && (listOperationOfflineOngoing || listPackagesOffline.Any()))
return;
154 if (listOperationOffline !=
null)
155 listOperationOffline.Cancel();
156 listOperationOfflineOngoing =
true;
157 listOperationOffline = OperationFactory.Instance.CreateListOperation(
true);
158 listOperationOffline.OnOperationFinalized += () =>
160 listOperationOfflineOngoing =
false;
161 UpdatePackageCollection(
true);
163 listOperationOffline.GetPackageListAsync(
166 var version = listPackagesVersion;
167 UpdateListPackageInfosOffline(infos, version);
169 error => { Debug.LogError(
"Error fetching package list (offline mode)."); });
172 internal void FetchListCache(
bool forceRefetch =
false)
174 if (!forceRefetch && (listOperationOngoing || listPackages.Any()))
return;
175 if (listOperation !=
null)
176 listOperation.Cancel();
177 listOperationOngoing =
true;
178 listOperation = OperationFactory.Instance.CreateListOperation();
179 listOperation.OnOperationFinalized += () =>
181 listOperationOngoing =
false;
182 UpdatePackageCollection(
true);
184 listOperation.GetPackageListAsync(UpdateListPackageInfos,
185 error => { Debug.LogError(
"Error fetching package list."); });
186 ListSignal.SetOperation(listOperation);
189 internal void FetchSearchCache(
bool forceRefetch =
false)
191 if (!forceRefetch && (searchOperationOngoing || searchPackages.Any()))
return;
192 if (searchOperation !=
null)
193 searchOperation.Cancel();
194 searchOperationOngoing =
true;
195 searchOperation = OperationFactory.Instance.CreateSearchOperation();
196 searchOperation.OnOperationFinalized += () =>
198 searchOperationOngoing =
false;
199 UpdatePackageCollection(
true);
201 searchOperation.GetAllPackageAsync(UpdateSearchPackageInfos,
202 error => { Debug.LogError(
"Error searching packages online."); });
203 SearchSignal.SetOperation(searchOperation);
206 private void UpdateListPackageInfosOffline(IEnumerable<PackageInfo> newInfos,
int version)
208 listPackagesOfflineVersion = version;
209 listPackagesOffline = newInfos.Where(p => p.IsUserVisible).ToList();
212 private void UpdateListPackageInfos(IEnumerable<PackageInfo> newInfos)
217 listPackagesVersion++;
218 listPackages = newInfos.Where(p => p.IsUserVisible).ToList();
219 listPackagesOffline = listPackages;
222 private void UpdateSearchPackageInfos(IEnumerable<PackageInfo> newInfos)
224 searchPackages = newInfos.Where(p => p.IsUserVisible).ToList();
227 private IEnumerable<Package> OrderedPackages()
229 return packages.Values.OrderBy(pkg => pkg.Versions.LastOrDefault() ==
null ? pkg.Name : pkg.Versions.Last().DisplayName).AsEnumerable();
232 public Package GetPackageByName(
string name)
235 packages.TryGetValue(name, out package);
239 public Error GetPackageError(
Package package)
241 if (
null == package)
return null;
242 var firstMatchingError = packageErrors.FirstOrDefault(p => p.PackageName == package.Name);
243 return firstMatchingError !=
null ? firstMatchingError.Error :
null;
246 public void AddPackageError(
Package package, Error error)
248 if (
null == package ||
null == error)
return;
249 packageErrors.Add(
new PackageError(package.Name, error));
252 public void RemovePackageErrors(
Package package)
254 if (
null == package)
return;
255 packageErrors.RemoveAll(p => p.PackageName == package.Name);
258 private void RebuildPackageDictionary()
261 var allPackageInfos =
new List<PackageInfo>(LatestListPackages);
262 var installedPackageIds =
new HashSet<string>(allPackageInfos.Select(p => p.PackageId));
263 allPackageInfos.AddRange(searchPackages.Where(p => !installedPackageIds.Contains(p.PackageId)));
265 if (!PackageManagerPrefs.ShowPreviewPackages)
267 allPackageInfos = allPackageInfos.Where(p => !p.IsPreRelease || installedPackageIds.Contains(p.PackageId)).ToList();
272 foreach (var p
in allPackageInfos)
274 var packageName = p.Name;
275 if (packages.ContainsKey(packageName))
278 var packageQuery = from pkg in allPackageInfos where pkg.Name == packageName select pkg;
279 var
package = new Package(packageName, packageQuery);
280 packages[packageName] = package;