public EditorContentObject(EditorApplication editor, string relativePath, string basePath, string currentPath) :base(editor) { RelativePath = relativePath; BasePath = basePath; CurrentPath = currentPath; }
public EditorContentFile(EditorApplication editor, string relativePath, string basePath, string currentPath) : base(editor, relativePath, basePath, currentPath) { try { IsValid = File.Exists(currentPath); } catch (Exception ex) { ErrorString = ex.ToString(); IsValid = false; } var properties = GetContentInfo(false); if (properties != null) { processor = properties.Processor; importer = properties.Importer; buildAction = properties.BuildAction; } ResolveDefaultProcessorAndImporter(); }
public PackageBuilder(EditorApplication editor) { if (editor == null) throw new ArgumentNullException("editor"); Editor = editor; }
public EditorContentDirectory(EditorApplication editor, string relativePath, string basePath, string currentPath) :base(editor, relativePath, basePath, currentPath) { try { IsValid = Directory.Exists(currentPath); } catch (Exception ex) { ErrorString = ex.ToString(); IsValid = false; } }
private void Build_WrapBuildProcessTaskAsync(EditorApplication packageCopy, string contextId, Func<bool> buildTask) { Building = true; CanBuild = false; cancellationPending = false; BuildSucceeded = null; Editor.Status = "Building ..."; System.Threading.Tasks.Task.Factory.StartNew(delegate { try { try { XNAContextInit(packageCopy, contextId); BuildSucceeded = buildTask(); } catch (FatalBuildErrorException) { BuildSucceeded = false; } catch (Exception ex) { Build_Message(ex.ToString(), "BuildTask", BuildMessageSeverity.Error); BuildSucceeded = false; } if (BuildSucceeded == true) Build_Message("Build success", "BuildTask", BuildMessageSeverity.Information); else Build_Message("Build failed", "BuildTask", BuildMessageSeverity.Error); } finally { XNAContextDispose(); CanBuild = true; Building = false; Editor.Status = BuildSucceeded == true ? "Build success" : "Build failed"; } }); }
private static string GetOutputBaseDirectory(EditorApplication packageCopy) { var rootDirectory = Path.GetDirectoryName(packageCopy.CurrentPackagePath); var outputBaseDirectory = Path.IsPathRooted(packageCopy.CurrentPackage.OutputDirectory) ? packageCopy.CurrentPackage.OutputDirectory : Path.Combine(rootDirectory, packageCopy.CurrentPackage.OutputDirectory); return outputBaseDirectory; }
/// <summary> /// /// </summary> /// <param name="packageCopy"></param> /// <param name="contextId">contextId is used to isolate sub build configurations of the same package</param> private void XNAContextInit(EditorApplication packageCopy, string contextId) { var outputBaseDirectory = GetOutputBaseDirectory(packageCopy); XNAOutputDirectory = AbsoluteDirectoryConvert(Path.Combine(outputBaseDirectory, GetSafeContentDirectorySuffix(packageCopy))); /* each content has to have an independant intermediate directory, so we generate an unique key for them (approximately) */ var xnaIntermediateSubDir = Path.Combine("obj", GenerateContentSubDirectory(packageCopy.CurrentPackagePath, contextId)); XNAIntermediateDirectory = AbsoluteDirectoryConvert(Path.Combine(outputBaseDirectory, xnaIntermediateSubDir)); if (!String.IsNullOrEmpty(contextId)) { /* Because XNA always clear the content before compiling if it doesn't match its file, * we force a full rebuild when the context is not null (ie. SingleItemBuild) */ try { var xnaContentXmlPath = Path.Combine(XNAIntermediateDirectory, "ContentPipeline.xml"); if (File.Exists(xnaContentXmlPath)) File.Delete(xnaContentXmlPath); } catch { } } XNALogger = new BuildLogger(this); }
private string GetSafeContentDirectorySuffix(EditorApplication packageCopy) { string baseSuffix = packageCopy.CurrentPackage.ContentDirectorySuffix; if (String.IsNullOrEmpty(baseSuffix)) baseSuffix = "Content"; return baseSuffix; }
private string GetOutputPathForFile(EditorApplication packageCopy, EditorContentFile file) { var rootDirectory = Path.GetDirectoryName(packageCopy.CurrentPackagePath); var outputBaseDirectory = Path.IsPathRooted(packageCopy.CurrentPackage.OutputDirectory) ? packageCopy.CurrentPackage.OutputDirectory : Path.Combine(rootDirectory, packageCopy.CurrentPackage.OutputDirectory); outputBaseDirectory += "\\" + GetSafeContentDirectorySuffix(packageCopy); var outputCompletePath = Path.Combine(outputBaseDirectory, file.RelativePath); var normalizedOutputCompletePath = Path.ChangeExtension(new FileInfo(outputCompletePath).FullName, CirrusContentManager.ContentFileExtention); return normalizedOutputCompletePath; }
private bool XNA_Build_Execute(EditorApplication packageCopy, BuildContent build, IList<XNACirrusAsset> sourceAssets) { // the RootDirectory must contain the sourceFile to avoid an "%0" from being appended to the // output file name // var computedRootDirectory = String.IsNullOrEmpty(packageCopy.CurrentPackage.BuildRootRelativeDirectory) ? GetContentBaseDirectory(packageCopy) : Path.Combine(GetContentBaseDirectory(packageCopy), packageCopy.CurrentPackage.BuildRootRelativeDirectory); Environment.CurrentDirectory = build.RootDirectory = computedRootDirectory; build.IntermediateDirectory = XNAIntermediateDirectory; build.LoggerRootDirectory = null; build.SourceAssets = (from sourceAsset in sourceAssets select sourceAsset.TaskItem).ToArray(); for (int i = 0; i < sourceAssets.Count; ++i) { build.SourceAssets[i] = sourceAssets[i].TaskItem; } //const string xnaVersion = ", Version=2.0.0.0, PublicKeyToken=6d5c3888ef60e27d"; // TODO: Why is "Culture" required? //const string xnaVersion = ", Version=3.0.0.0, Culture=neutral, PublicKeyToken=6d5c3888ef60e27d"; // Don't append .dll??? if loading from the GAC build.PipelineAssemblies = (from xnaReference in packageCopy.CurrentPackage.XNAReferences select new TaskItem(ParseReferencePath(packageCopy, xnaReference.Reference))).ToArray(); try { return build.Execute(); } catch (Exception e) { Build_Message(e.Message, e.Source, BuildMessageSeverity.Error); return false; } }
private string GetSourcePathForFile(EditorApplication packageCopy, EditorContentFile file) { var contentBaseDirectory = GetContentBaseDirectory(packageCopy); var inputCompletePath = Path.Combine(contentBaseDirectory, file.RelativePath); var normalizedInputCompletePath = new FileInfo(inputCompletePath).FullName; return normalizedInputCompletePath; }
private bool ProcessPackageReference(EditorApplication packageCopy, string referencePath, string contextId, bool rebuild, bool compress, Predicate<EditorContentFile> filesFilter, List<string> callTree, List<string> builtPackages) { if (cancellationPending) return false; Build_Message(String.Format("--- Begin --- Referenced Package : {0}", referencePath), "PackageReferenceResolve", BuildMessageSeverity.Information); if (callTree.Contains(referencePath)) { Build_Message("Circular reference identified, aborting", "PackageReferenceResolve", BuildMessageSeverity.Error); return false; } else { if (builtPackages.Contains(referencePath)) { Build_Message("--- Package already built. Skipping ...", "PackageReferenceResolve", BuildMessageSeverity.Information); return true; } else { var newCallTree = new List<string>(); newCallTree.AddRange(callTree); EditorApplication referencedPackage; using (var packageReferenceStream = new FileStream(referencePath, FileMode.Open, FileAccess.Read)) { referencedPackage = Editor.LoadAndCreatePackageFromStream(packageReferenceStream, referencePath); } referencedPackage.CurrentPackage.OutputDirectory = GetOutputBaseDirectory(packageCopy); referencedPackage.Builder.build_message_redirection = (msg, src, severity) => { Build_Message(msg, src, severity); referencedPackage.Builder.cancellationPending = cancellationPending; }; var success = referencedPackage.Builder.Build_Sync_Execute(contextId, rebuild, compress, filesFilter, newCallTree, builtPackages); if (success) { Build_Message(String.Format("--- End Success --- Referenced Package : {0}", referencePath), "PackageReferenceResolve", BuildMessageSeverity.Information); return true; } else { Build_Message(String.Format("--- End Failed --- Referenced Package : {0}", referencePath), "PackageReferenceResolve", BuildMessageSeverity.Information); return false; } } } }
private bool Build_Execute(EditorApplication packageCopy, string contextId, bool rebuild, bool compress, Predicate<EditorContentFile> filesFilter = null, List<string> callTree = null, List<string> builtPackages = null) { /* callTree is used to identify circular references */ if (callTree == null) callTree = new List<string>(); /* builtPackages is used to skip the recompilation of an already processed package reference */ if (builtPackages == null) builtPackages = new List<string>(); callTree.Add(packageCopy.CurrentPackagePath); /* first, processes referenced package */ foreach (var packageReference in packageCopy.CurrentPackage.CirrusReferences) { if (!String.IsNullOrEmpty(packageReference.Reference)) { if (packageReference.Build) { var referencePath = ParseReferencePath(packageCopy, packageReference.Reference); if (!ProcessPackageReference(packageCopy, referencePath, contextId, rebuild, compress, filesFilter, callTree, builtPackages)) return false; } else { Build_Message(String.Format("--- Ignore --- The package {0} has been ignored because not marked for Build", packageReference.Reference), "PackageReferenceCondition", BuildMessageSeverity.Information); } } } /* then process the current package*/ var decodedAssets = new List<XNACirrusAsset>(); bool success = Build_ActionForAllFiles(packageCopy, (file) => { if (filesFilter == null || filesFilter(file)) { Build_ProcessFile(decodedAssets, packageCopy, file); } else Build_Message("-- Skipped by filter"); return true; }); if (success) { var build = new BuildContent(); // BuildEngine is used by TaskLoggingHelper, so an implementation must be provided // build.BuildEngine = new BuildEngine(this); build.RebuildAll = rebuild; build.CompressContent = compress; build.TargetProfile = GraphicsProfile.HiDef.ToString(); build.BuildConfiguration = "Debug"; build.TargetPlatform = TargetPlatform.Windows.ToString(); build.OutputDirectory = XNAOutputDirectory; if (decodedAssets.Count > 0) { success = XNA_Build_Execute(packageCopy, build, decodedAssets); } builtPackages.Add(packageCopy.CurrentPackagePath); } return success; }
private string ParseReferencePath(EditorApplication packageCopy, string referenceName) { /* check to see if the reference is a local file */ try { var fi = new FileInfo(Path.Combine(Path.GetDirectoryName(packageCopy.CurrentPackagePath), referenceName)); if (fi.Exists) return fi.FullName; } catch { } /* nope */ return referenceName; }
public EditorPackageContainerObject(EditorApplication editor) : base(editor) { AvailableXNATypes = new ObservableCollection<XNAAssemblyDescription>(); }
private void Build_ProcessFile(List<XNACirrusAsset> decodedAssets, EditorApplication packageCopy, EditorContentFile file) { var src = GetSourcePathForFile(packageCopy, file); var dst = GetOutputPathForFile(packageCopy, file); switch (file.BuildAction) { default: case Sora.GameEngine.Cirrus.Design.Packages.XmlBuildAction.None: { Build_Message("Ignored", "ProcessFile"); break; } case Sora.GameEngine.Cirrus.Design.Packages.XmlBuildAction.Compile: { var importer = file.Importer; var processor = file.Processor; if (String.IsNullOrEmpty(importer) && String.IsNullOrEmpty(processor)) { Build_Message("No importer or processor specified, copying to output"); goto case Sora.GameEngine.Cirrus.Design.Packages.XmlBuildAction.CopyToOutput; } else { //Build_Message(String.Format("Compiling {0} to {1}", src, dst), "ProcessFile"); //XNAFileCompile(packageCopy, file, src, dst); decodedAssets.Add(new XNACirrusAsset(packageCopy, file)); } break; } case Sora.GameEngine.Cirrus.Design.Packages.XmlBuildAction.CopyToOutput: { Build_Message(String.Format("Copying {0} to {1}", src, dst), "ProcessFile"); var outDirectory = Path.GetDirectoryName(dst); if (!Directory.Exists(outDirectory)) Directory.CreateDirectory(outDirectory); File.Copy(src, dst, true); break; } } }
public EditorPackageReferencesObject(EditorApplication editor) :base(editor) { Title = "Package References"; }
private bool Build_ActionForAllFiles(EditorApplication buildPackageApplication, Func<EditorContentFile, bool> action) { if (action != null) { /* We process files using depth traversal to ensure that lower level files will be evaluated before all * high level files * * This allows to build Levels depending on sub components placed below in the graph */ var enumeratorStack = new Stack<EditorContentObject>(); /* we add the root files */ enumeratorStack.Push(from obj in buildPackageApplication.PackageContainer[0].Content where obj is EditorContentFile select (EditorContentFile)obj); /* root directories */ enumeratorStack.Push(from obj in buildPackageApplication.PackageContainer[0].Content where obj is EditorContentDirectory select (EditorContentDirectory)obj); /* and here we go */ while (enumeratorStack.Count > 0) { var current = enumeratorStack.Pop(); var as_file = current as EditorContentFile; var as_directory = current as EditorContentDirectory; if (as_directory != null) { Build_Message(String.Format("Directory - {0}", as_directory.RelativePath), "Build_EnumFiles", BuildMessageSeverity.Information); /* sub files */ enumeratorStack.Push(from element in as_directory.Content where element is EditorContentFile select (EditorContentObject)element); /* sub directories */ enumeratorStack.Push(from element in as_directory.Content where element is EditorContentDirectory orderby ((EditorContentDirectory)element).BuildOrder select (EditorContentObject)element); if (!as_directory.IsValid) Build_Message(String.Format("Directory {0} was marked as invalid", as_directory.RelativePath), "Build_EnumFiles", BuildMessageSeverity.Warning); } else if (as_file != null) { Build_Message(String.Format("File - {0}", as_file.RelativePath), "Build_EnumFiles", BuildMessageSeverity.Information); if (cancellationPending) { Build_Message("Compilation aborted", "Build_EnumFiles", BuildMessageSeverity.Error); return false; } if (!as_file.IsValid) Build_Message(String.Format("File {0} was marked as invalid", as_file.RelativePath), "Build_EnumFiles", BuildMessageSeverity.Warning); else { var process_result = action(as_file); if (!process_result) { Build_Message(String.Format("File {0} aborted the compilation", as_file.RelativePath), "Build_EnumFiles", BuildMessageSeverity.Error); return false; } } } if (cancellationPending) { Build_Message("Compilation aborted", "Build_EnumFiles", BuildMessageSeverity.Error); return false; } } return true; } else return true; }