/// <summary> /// Enumerates a hard reference. /// </summary> /// <param name="hardReference">Hard reference.</param> protected void EnumerateHardReference(ItemReference hardReference) { List <ItemReference> localEnumeratedReferences = new List <ItemReference>(); List <string> packageListFile; if (hardReference.PackageGroup.PackageListfiles.TryGetValue(hardReference.PackageName, out packageListFile)) { IEnumerable <string> strippedListfile = packageListFile.Where(s => s.StartsWith(hardReference.ItemPath, true, new CultureInfo("en-GB"))); foreach (string FilePath in strippedListfile) { string childPath = Regex.Replace(FilePath, "^(?-i)" + Regex.Escape(hardReference.ItemPath), ""); int slashIndex = childPath.IndexOf('\\'); string topDirectory = childPath.Substring(0, slashIndex + 1); if (!String.IsNullOrEmpty(topDirectory)) { ItemReference directoryReference = new ItemReference(hardReference.PackageGroup, hardReference, topDirectory); if (!hardReference.ChildReferences.Contains(directoryReference)) { hardReference.ChildReferences.Add(directoryReference); localEnumeratedReferences.Add(directoryReference); } } else if (String.IsNullOrEmpty(topDirectory) && slashIndex == -1) { ItemReference fileReference = new ItemReference(hardReference.PackageGroup, hardReference, childPath); if (!hardReference.ChildReferences.Contains(fileReference)) { // Files can't have any children, so it will always be enumerated. hardReference.State = ReferenceState.Enumerated; hardReference.ChildReferences.Add(fileReference); localEnumeratedReferences.Add(fileReference); } } else { break; } } lock (EnumeratedReferenceQueueLock) { // Add this directory's enumerated files in order as one block this.EnumeratedReferences.AddRange(localEnumeratedReferences); } hardReference.State = ReferenceState.Enumerated; EnumerationFinishedArgs = new ItemEnumeratedEventArgs(hardReference); RaiseEnumerationFinished(); } else { throw new InvalidDataException("No listfile was found for the package referenced by this item reference."); } }
/// <summary> /// Loads all packages in the currently selected game directory. This function does not enumerate files /// and directories deeper than one to keep the UI responsive. /// </summary> protected void Reload_Implementation() { if (HasPackageDirectoryChanged()) { CachedPackageDirectories = GamePathStorage.Instance.GamePaths; this.PackageGroups.Clear(); if (CachedPackageDirectories.Count > 0) { WorkQueue.Clear(); PackageItemNodeMapping.Clear(); PackageNodeItemMapping.Clear(); PackageGroupVirtualNodeMapping.Clear(); VirtualReferenceMappings.Clear(); } foreach (string packageDirectory in CachedPackageDirectories) { if (Directory.Exists(packageDirectory)) { // Create the package group and add it to the available ones string FolderName = Path.GetFileName(packageDirectory); PackageGroup Group = new PackageGroup(FolderName, packageDirectory); // TODO: Creating a package group is real slow. Speed it up this.PackageGroups.Add(FolderName, Group); // Create a virtual item reference that points to the package group VirtualItemReference packageGroupReference = new VirtualItemReference(Group, new ItemReference(Group)); packageGroupReference.State = ReferenceState.Enumerated; // Create a virtual package folder for the individual packages under the package group ItemReference packageGroupPackagesFolderReference = new ItemReference(Group, packageGroupReference, ""); // Add the package folder as a child to the package group node packageGroupReference.ChildReferences.Add(packageGroupPackagesFolderReference); // Send the package group node to the UI this.PackageGroupAddedArgs = new ItemEnumeratedEventArgs(packageGroupReference); RaisePackageGroupAdded(); // Add the packages in the package group as nodes to the package folder foreach (KeyValuePair <string, List <string> > PackageListfile in Group.PackageListfiles) { if (PackageListfile.Value != null) { string PackageName = Path.GetFileName(PackageListfile.Key); ItemReference packageReference = new ItemReference(Group, packageGroupPackagesFolderReference, PackageName, ""); // Send the package node to the UI this.PackageEnumeratedArgs = new ItemEnumeratedEventArgs(packageReference); RaisePackageEnumerated(); // Submit the package as a work order, enumerating the topmost directories SubmitWork(packageReference); } } } } bIsReloading = false; bArePackageGroupsLoaded = true; } }