internal ProjectDirectory(ProjectDirectory parent, string name) { Parent = parent; Name = name; FullName = MakeFullName(parent, name); Directories = new ProjectDirectoryCollection(); Resources = new ProjectResourceCollection(); }
public static async Task <ProjectExplorer> LoadAsync(string projectPath, ImportPipeline importPipeline) { string bprojPath = null; if (projectPath.EndsWith(".bproj")) { bprojPath = projectPath; projectPath = new DirectoryInfo(projectPath).Parent.FullName; } else { foreach (string rootFile in Directory.EnumerateFiles(projectPath, "*.bproj")) { bprojPath = rootFile; break; } } var sourceArchive = new FileSystemArchive(new DirectoryInfo(projectPath)); var resources = new Dictionary <string, ProjectResource>(); var rootDirectiory = new ProjectDirectory(null, null); var projectExplorer = new ProjectExplorer { Archive = sourceArchive, Definition = ProjectDefinition.Load(bprojPath), Resources = new ProjectResourceCollection(resources), RootDirectory = rootDirectiory, ImportPipeline = importPipeline }; // Organise temporary directory var tempDirectory = new DirectoryInfo(Path.Combine(projectPath, "../temp")); tempDirectory.Create(); var tempArchive = new FileSystemArchive(tempDirectory, false); void ApplyUpdate(ProjectResourceUpdate update) { string[] elements = update.ProjectKey.Split(new char[] { '/' }); var placementDirectory = rootDirectiory; for (int i = 0; i < elements.Length - 1; i++) { string element = elements[i]; var parent = placementDirectory; placementDirectory = placementDirectory.Directories[element]; if (placementDirectory == null) { placementDirectory = new ProjectDirectory(placementDirectory, element); parent.Directories.Add(placementDirectory); } } string fileName = elements[elements.Length - 1]; // Locate or create resource to apply updates to. if (!placementDirectory.Resources.TryGetResource(fileName, out var projectResource)) { projectResource = new ProjectResource(projectExplorer, placementDirectory, update.ProjectKey); projectExplorer.Resources.Add(projectResource.FullName, projectResource); placementDirectory.Resources.Add(projectResource.Name, projectResource); } // Apply updates to resource projectResource.Tags.importerTags.AddRange(update.ImporterTags); foreach (var importerDependency in update.Dependencies) { projectResource.Dependencies.dependencies.Add( new ProjectResourceDependency(projectExplorer, importerDependency.Resource, importerDependency.Metadata)); } if (update.FileContent != null) { projectResource.Content = new ProjectResourceContent(update.FileContent); } if (update.DeferredContent != null) { string tempId = Guid.NewGuid().ToString(); var tempFile = tempArchive.RootDirectory.Files.GetOrCreateFile(tempId); using (var tempOutput = tempFile.OpenWrite()) { update.DeferredContent.WriteContentAsync(tempOutput).Wait(); } projectResource.Content = new ProjectResourceContent(tempFile); } } // Import resources foreach (var update in importPipeline.ImportDirectory(projectExplorer, sourceArchive.RootDirectory)) { ApplyUpdate(update); } // Attach dependencies foreach (var resource in projectExplorer.Resources) { foreach (var dependency in resource.Dependencies) { var dependencyResource = dependency.Resource; if (dependencyResource == null) { Console.WriteLine($"ERROR: Unable to resolve dependency for \"{dependency.Key}\""); } else { dependencyResource.Dependants.dependencies.Add(new ProjectResourceDependency(projectExplorer, resource.FullName, dependency.metdadata)); } } } // Process Resoures var importProcessorContext = new ImportProcessorContext() { Explorer = projectExplorer }; foreach (var processor in importPipeline.importProcessors) { var preExistingResources = new List <ProjectResource>(); foreach (var resource in projectExplorer.Resources) { preExistingResources.Add(resource); } foreach (var resource in preExistingResources) { var maxThread = new SemaphoreSlim(32); var tasks = new List <Task>(); if (processor.CanProcess(resource)) { maxThread.Wait(); tasks.Add(Task.Factory.StartNew(() => { var updates = processor.ProcessImport(importProcessorContext, resource); if (updates != null) { foreach (var update in updates) { ApplyUpdate(update); } } }, TaskCreationOptions.LongRunning) .ContinueWith((task) => { tasks.Remove(task); return(maxThread.Release()); })); } Task.WaitAll(tasks.ToArray()); } } // Size Calculation long uncompressedSize = 0; foreach (var resource in projectExplorer.Resources) { uncompressedSize += resource.Content.UncompressedSize; } projectExplorer.UncompressedSize = uncompressedSize; // Tag Indexing var tags = new Dictionary <string, IResourceCollection>(); foreach (var resource in projectExplorer.Resources) { foreach (string tag in resource.Tags) { if (!tags.TryGetValue(tag, out var taggedResourcesCollection)) { taggedResourcesCollection = new ProjectResourceCollection(); tags[tag] = taggedResourcesCollection; } var taggedResources = (ProjectResourceCollection)taggedResourcesCollection; taggedResources.Add(resource.FullName, resource); } } projectExplorer.Tags = new ProjectTagsCollection(tags); return(projectExplorer); }
public ProjectResourceCollectionDebugView(ProjectResourceCollection source) { this.source = source; }