/// <summary>
 /// Write the terminating newline
 /// </summary>
 public void Dispose()
 {
     if (Status != null)
     {
         Status.Dispose();
         Status = null;
     }
 }
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="InMessage">The message to display before the progress percentage</param>
 /// <param name="bInUpdateStatus">Whether to write messages to the console</param>
 public ProgressWriter(string InMessage, bool bInUpdateStatus)
 {
     Message = InMessage;
     if (bInUpdateStatus)
     {
         Status = new LogStatusScope(InMessage);
     }
     Write(0, 100);
 }
        /// <summary>
        /// Main entry point for the command
        /// </summary>
        public override void ExecuteBuild()
        {
            // Build a lookup of flags to set and clear for each identifier
            Dictionary <string, int> IdentifierToIndex = new Dictionary <string, int>();

            for (int Idx = 0; Idx < MacroPairs.GetLength(0); Idx++)
            {
                IdentifierToIndex[MacroPairs[Idx, 0]] = Idx;
                IdentifierToIndex[MacroPairs[Idx, 1]] = ~Idx;
            }

            // Check if we want to just parse a single file
            string FileParam = ParseParamValue("File");

            if (FileParam != null)
            {
                // Check the file exists
                FileReference File = new FileReference(FileParam);
                if (!FileReference.Exists(File))
                {
                    throw new AutomationException("File '{0}' does not exist", File);
                }
                CheckSourceFile(File, IdentifierToIndex, new object());
            }
            else
            {
                // Add the additional files to be ignored
                foreach (string IgnoreFileName in ParseParamValues("Ignore"))
                {
                    IgnoreFileNames.Add(IgnoreFileName);
                }

                // Create a list of all the root directories
                HashSet <DirectoryReference> RootDirs = new HashSet <DirectoryReference>();
                RootDirs.Add(EngineDirectory);

                // Add the enterprise directory
                DirectoryReference EnterpriseDirectory = DirectoryReference.Combine(RootDirectory, "Enterprise");
                if (DirectoryReference.Exists(EnterpriseDirectory))
                {
                    RootDirs.Add(EnterpriseDirectory);
                }

                // Add the project directories
                string[] ProjectParams = ParseParamValues("Project");
                foreach (string ProjectParam in ProjectParams)
                {
                    FileReference ProjectFile = new FileReference(ProjectParam);
                    if (!FileReference.Exists(ProjectFile))
                    {
                        throw new AutomationException("Unable to find project '{0}'", ProjectFile);
                    }
                    RootDirs.Add(ProjectFile.Directory);
                }

                // Recurse through the tree
                LogInformation("Finding source files...");
                List <FileReference> SourceFiles = new List <FileReference>();
                using (ThreadPoolWorkQueue Queue = new ThreadPoolWorkQueue())
                {
                    foreach (DirectoryReference RootDir in RootDirs)
                    {
                        DirectoryInfo PluginsDir = new DirectoryInfo(Path.Combine(RootDir.FullName, "Plugins"));
                        if (PluginsDir.Exists)
                        {
                            Queue.Enqueue(() => FindSourceFiles(PluginsDir, SourceFiles, Queue));
                        }

                        DirectoryInfo SourceDir = new DirectoryInfo(Path.Combine(RootDir.FullName, "Source"));
                        if (SourceDir.Exists)
                        {
                            Queue.Enqueue(() => FindSourceFiles(SourceDir, SourceFiles, Queue));
                        }
                    }
                    Queue.Wait();
                }

                // Loop through all the source files
                using (ThreadPoolWorkQueue Queue = new ThreadPoolWorkQueue())
                {
                    object LogLock = new object();
                    foreach (FileReference SourceFile in SourceFiles)
                    {
                        Queue.Enqueue(() => CheckSourceFile(SourceFile, IdentifierToIndex, LogLock));
                    }

                    using (LogStatusScope Scope = new LogStatusScope("Checking source files..."))
                    {
                        while (!Queue.Wait(10 * 1000))
                        {
                            Scope.SetProgress("{0}/{1}", SourceFiles.Count - Queue.NumRemaining, SourceFiles.Count);
                        }
                    }
                }
            }
        }