//-------------------------------------------------------------- #region Methods //-------------------------------------------------------------- private static async Task<Tuple<bool, List<Error>>> BuildMonoGameAsync( ServiceContainer services, string applicationName, TextDocument document, DelegateCommand<Error> goToLocationCommand) { string errorMessage = await Task.Run(() => { using (var tempDirectoryHelper = new TempDirectoryHelper(applicationName, "ShaderDocument")) { var contentBuilder = new GameContentBuilder(services) { IntermediateFolder = tempDirectoryHelper.TempDirectoryName + "\\obj", OutputFolder = tempDirectoryHelper.TempDirectoryName + "\\bin", }; string message; contentBuilder.Build(document.Uri.LocalPath, null, "EffectProcessor", null, out message); return message; } }); List<Error> errors = null; if (!string.IsNullOrEmpty(errorMessage)) { errorMessage = errorMessage.TrimEnd(' ', '\r', '\n'); errors = new List<Error>(); // Use regular expression to parse the MSBuild output lines. // Example: "X:\DigitalRune\Samples\DigitalRune.Graphics.Content\DigitalRune\Billboard.fx(22,3) : Unexpected token 'x' found. Expected CloseBracket" var regex = new Regex(@"(?<file>[^\\/]*)\((?<line>\d+),(?<column>\d+)\) : (?<message>.*)"); var match = regex.Match(errorMessage); if (match.Success) { string lineText = match.Groups["line"].Value; string columnText = match.Groups["column"].Value; string message = match.Groups["message"].Value; bool isWarning = match.Groups["warning"].Success; var error = new Error( isWarning ? ErrorType.Warning : ErrorType.Error, $"[MonoGame] {message}", match.Groups["file"].Value, int.Parse(lineText), int.Parse(columnText)); error.UserData = document; error.GoToLocationCommand = goToLocationCommand; errors.Add(error); } else { errors.Add(new Error(ErrorType.Error, errorMessage)); } } return Tuple.Create(string.IsNullOrEmpty(errorMessage), errors); }
public bool Run(TextDocument document) { Debug.Assert(document.Uri != null, "The document needs to be saved before NVShaderPerf can be run."); Logger.Info(CultureInfo.InvariantCulture, "Running NVShaderPerf.exe for \"{0}\".", Path.GetFileName(document.Uri.LocalPath)); string programFilesPath = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86); string shaderPerfFileName = Path.Combine(programFilesPath, @"NVIDIA Corporation\NVIDIA ShaderPerf\NVShaderPerf.exe"); if (!File.Exists(shaderPerfFileName)) { string message = "NVIDIA ShaderPerf (NVShaderPerf.exe) not found."; Logger.Error(message); _outputService.WriteLine(message); return false; } using (var processRunner = new ProcessRunner()) { processRunner.OutputDataReceived += (s, e) => _outputService.WriteLine(e.Data); processRunner.ErrorDataReceived += (s, e) => _outputService.WriteLine(e.Data); // Analyze the passes in the effect. var shaderParser = new ShaderParser(new HlslIntelliSense()); var techniquesAndPasses = shaderParser.GetTechniquesAndPasses(document.AvalonEditDocument.CreateSnapshot()); foreach (var techniqueAndPasses in techniquesAndPasses) { string technique = techniqueAndPasses.Item1; foreach (string pass in techniqueAndPasses.Item2) { _outputService.WriteLine(string.Format(CultureInfo.InvariantCulture, "NVShaderPerf.exe -g G80 -t {0} -p {1} {2}\n", technique, pass, Path.GetFileName(document.Uri.LocalPath))); processRunner.Start(shaderPerfFileName, string.Format(CultureInfo.InvariantCulture, "-g G80 -t {0} -p {1} -include \"{2}\" \"{3}\"", technique, pass, Path.GetDirectoryName(document.Uri.LocalPath), document.Uri.LocalPath)); processRunner.WaitForExit(); if (processRunner.ExitCode != 0) { // Break on error. Logger.Info("Failed."); //_outputService.WriteLine(); return false; } } } Logger.Info("Success."); //_outputService.WriteLine(); return true; } }
private void RemoveErrors(TextDocument document) { List <Error> errors; if (_errorLists.TryGetValue(document, out errors)) { document.ErrorMarkers.Clear(); foreach (var error in errors) { _errorService?.Errors.Remove(error); } _errorLists.Remove(document); } }
//-------------------------------------------------------------- #region Methods //-------------------------------------------------------------- private static async Task<Tuple<bool, List<Error>>> BuildXnaAsync( IServiceLocator services, TextDocument document, DelegateCommand<Error> goToLocationCommand) { var xnaContentBuilder = services.GetInstance<XnaContentBuilder>().ThrowIfMissing(); xnaContentBuilder.Clear(); xnaContentBuilder.Add(document.Uri.AbsolutePath, Path.GetFileNameWithoutExtension(document.Uri.LocalPath), null, "EffectProcessor"); var result = await xnaContentBuilder.BuildAsync(); // TODO: Asynchronously parse errors. List<Error> errors = null; if (result.Item2?.Count > 0) { // Use regular expression to parse the MSBuild output lines. // Example: "X:\DigitalRune\Samples\DigitalRune.Graphics.Content\DigitalRune\Billboard.fx(101,10): error : (101,10): error X3089: 'x': invalid shader target/usage [C:\Users\MartinG\AppData\Local\Temp\EditorApp\15812\XnaContentBuilder-0000\content.contentproj]" var regex = new Regex(@"(?<file>[^\\/]*)\((?<line>\d+),(?<column>\d+)\): (([eE]rror)|([wW]arning)) : (\((?<line2>\d+),(?<column2>\d+)\): )?.*(?<message>(((?<error>error )|(?<warning>warning ))).*?)(:? \[.*\])"); errors = new List<Error>(); foreach (var line in result.Item2) { var match = regex.Match(line); if (match.Success) { var lineText = match.Groups["line"].Value; if (match.Groups["line2"].Success) lineText = match.Groups["line2"].Value; var columnText = match.Groups["column"].Value; if (match.Groups["column2"].Success) columnText = match.Groups["column2"].Value; var message = match.Groups["message"].Value; bool isWarning = match.Groups["warning"].Success; var error = new Error( isWarning ? ErrorType.Warning : ErrorType.Error, $"[XNA] {message}", match.Groups["file"].Value, int.Parse(lineText), int.Parse(columnText)); error.UserData = document; error.GoToLocationCommand = goToLocationCommand; errors.Add(error); } } } return Tuple.Create(result.Item1, errors); }
private void AddErrors(TextDocument document, List <Error> newErrors, bool success) { if (success && (newErrors == null || newErrors.Count == 0)) { return; } List <Error> errors; if (!_errorLists.TryGetValue(document, out errors)) { errors = new List <Error>(); _errorLists.Add(document, errors); } bool foundErrorMessage = false; foreach (var error in newErrors) { _errorService?.Errors.Add(error); errors.Add(error); MarkError(error); if (error.ErrorType == ErrorType.Error) { foundErrorMessage = true; } } // If we did not find a useful error message we write a generic one. if (!success && !foundErrorMessage) { var error = new Error( ErrorType.Error, "Could not build effect. See Output window for more information.", DocumentHelper.GetName(document)); _errorService?.Errors.Add(error); errors.Add(error); } _errorLists[document] = errors; _errorService?.Show(); }
//-------------------------------------------------------------- #region Methods //-------------------------------------------------------------- private static async Task<Tuple<bool, List<Error>>> BuildFxcAsync( ServiceContainer services, TextDocument document, DelegateCommand<Error> goToLocationCommand) { var fxc = services.GetInstance<Fxc>().ThrowIfMissing(); var result = await fxc.BuildAsync(document.Uri.LocalPath); // TODO: Asynchronously parse errors. List<Error> errors = null; if (result.Item2?.Count > 0) { // Use regular expression to parse the MSBuild output lines. // Example: "X:\DigitalRune\Samples\DigitalRune.Graphics.Content\DigitalRune\Billboard.fx(100,3): error X3000: unrecognized identifier 'x'" var regex = new Regex(@"(?<file>[^\\/]*)\((?<line>\d+),(?<column>\d+)\): (?<message>(((?<error>error )|(?<warning>warning ))).*)"); errors = new List<Error>(); foreach (var line in result.Item2) { var match = regex.Match(line); if (match.Success) { string lineText = match.Groups["line"].Value; string columnText = match.Groups["column"].Value; string message = match.Groups["message"].Value; bool isWarning = match.Groups["warning"].Success; var error = new Error( isWarning ? ErrorType.Warning : ErrorType.Error, $"[FXC] {message}", match.Groups["file"].Value, int.Parse(lineText), int.Parse(columnText)); error.UserData = document; error.GoToLocationCommand = goToLocationCommand; errors.Add(error); } } } return Tuple.Create(result.Item1, errors); }
//-------------------------------------------------------------- /// <inheritdoc/> protected override Document OnCreate(DocumentType documentType) { var document = new TextDocument(_editor, documentType); TextIntelliSense.EnableIntelliSense(document); return document; }
//-------------------------------------------------------------- #region Methods //-------------------------------------------------------------- #region ----- Initialization ----- public static void EnableIntelliSense(TextDocument document) { // Register event handler that enables IntelliSense on every view which is // added to the document. ((INotifyCollectionChanged)document.ViewModels).CollectionChanged += OnViewModelsChanged; }
protected override Document OnCreate(DocumentType documentType) { // Create a text document. var document = new TextDocument(_editor, documentType) { FileDialogFilter = _filter, }; switch (documentType.FileExtensions.First()) { case ".fx": case ".fxh": document.FileDialogFilterIndex = 1; break; case ".cg": case ".cgh": document.FileDialogFilterIndex = 2; break; case ".cgfx": document.FileDialogFilterIndex = 3; break; default: document.FileDialogFilterIndex = 1; break; } // Register event handler that enables IntelliSense on every view which is // added to the document. ((INotifyCollectionChanged)document.ViewModels).CollectionChanged += OnViewModelsChanged; return document; }
private void RemoveErrors(TextDocument document) { List<Error> errors; if (_errorLists.TryGetValue(document, out errors)) { document.ErrorMarkers.Clear(); foreach (var error in errors) _errorService?.Errors.Remove(error); _errorLists.Remove(document); } }
private void AddErrors(TextDocument document, List<Error> newErrors, bool success) { if (success && (newErrors == null || newErrors.Count == 0)) return; List<Error> errors; if (!_errorLists.TryGetValue(document, out errors)) { errors = new List<Error>(); _errorLists.Add(document, errors); } bool foundErrorMessage = false; foreach (var error in newErrors) { _errorService?.Errors.Add(error); errors.Add(error); MarkError(error); if (error.ErrorType == ErrorType.Error) foundErrorMessage = true; } // If we did not find a useful error message we write a generic one. if (!success && !foundErrorMessage) { var error = new Error( ErrorType.Error, "Could not build effect. See Output window for more information.", DocumentHelper.GetName(document)); _errorService?.Errors.Add(error); errors.Add(error); } _errorLists[document] = errors; _errorService?.Show(); }