Ejemplo n.º 1
0
 // Called by BuildTask instances to get the next available content item to start building
 //   Returns false when no items are left
 internal bool GetTaskItem(out BuildEvent item)
 {
     lock (_taskLock)
     {
         if (_itemEnumerator.MoveNext())
         {
             var ci = _itemEnumerator.Current.Value;
             item = BuildEvent.FromItem(Engine, ci, _itemIndex++);
             return(true);
         }
         else
         {
             item = null;
             return(false);
         }
     }
 }
Ejemplo n.º 2
0
 // Resets all settable fields back to default, and sets the ones that are included in the item args
 //  If the parse from the content project string fails, then the field takes on its default value
 public void UpdateFields(BuildEngine engine, BuildEvent evt)
 {
     foreach (var field in Type.Fields)
     {
         var idx = evt.Item.ProcessorArgs.FindIndex(arg => arg.Key == field.ParamName);
         if (idx == -1)
         {
             field.Info.SetValue(Instance, field.DefaultValue);
         }
         else
         {
             if (ConverterCache.Convert(field.FieldType, evt.Item.ProcessorArgs[idx].Value, out object parsed))
             {
                 field.Info.SetValue(Instance, parsed);
             }
             else
             {
                 engine.Logger.EngineError($"The content item '{evt.Item.ItemPath}' specified an invalid value for the parameter" +
                                           $" '{field.ParamName}'.");
                 field.Info.SetValue(Instance, field.DefaultValue);
             }
         }
     }
 }
Ejemplo n.º 3
0
        // The function that runs on the thread
        private void _thread_func(bool rebuild)
        {
            Stopwatch      _timer  = new Stopwatch();
            PipelineLogger _logger = new PipelineLogger(Engine);

            Results.Reset();

            // Create the content stream
            var cStream = new ContentStream();

            // Iterate over the tasks
            while (!Manager.ShouldStop && Manager.GetTaskItem(out BuildEvent current))
            {
                // Report start
                Engine.Logger.ItemStart(current);
                _timer.Restart();
                _logger.UseEvent(current);
                Results.UseItem(current);

                // Check the source file exists
                if (current.InputTime == BuildEvent.ERROR_TIME)
                {
                    Engine.Logger.ItemFailed(current, "Could not find the source file for the item");
                    continue;
                }

                // Check for the requested importer and processor
                if (!_importers.ContainsKey(current.ImporterName))
                {
                    if (Engine.StageCache.Importers.ContainsKey(current.ImporterName))
                    {
                        _importers.Add(current.ImporterName, new ImporterInstance(Engine.StageCache.Importers[current.ImporterName]));
                    }
                    else
                    {
                        Engine.Logger.ItemFailed(current, "The item requested an importer type that does not exist");
                        continue;
                    }
                }
                if (!_processors.ContainsKey(current.ProcessorName))
                {
                    if (Engine.StageCache.Processors.ContainsKey(current.ProcessorName))
                    {
                        _processors.Add(current.ProcessorName, new ProcessorInstance(Engine.StageCache.Processors[current.ProcessorName]));
                    }
                    else
                    {
                        Engine.Logger.ItemFailed(current, "The item requested an processor type that does not exist");
                        continue;
                    }
                }
                var importer  = _importers[current.ImporterName];
                var processor = _processors[current.ProcessorName];

                // Validate stage compatibility
                if (!processor.Type.InputType.IsAssignableFrom(importer.Type.OutputType))
                {
                    Engine.Logger.ItemFailed(current, "The item specified incompatible stages");
                    continue;
                }

                // Compare the current and cached build events to see if we can skip the build
                //   If we are forcing a rebuild we have to build so we can skip the check
                bool compress =
                    (processor.Policy == CompressionPolicy.Always) ||
                    (processor.Policy == CompressionPolicy.ReleaseOnly && Engine.IsRelease) ||
                    (processor.Policy == CompressionPolicy.Default && Engine.Compress) ||
                    false;                     // policy is never, compress = false
                if (!rebuild)
                {
                    var cached = BuildEvent.FromCacheFile(Engine, current.Item);
                    if (!current.NeedsBuild(cached, processor, compress))
                    {
                        Engine.Logger.ItemSkipped(current);
                        Results.PassItem(cached.UCSize, true);
                        if (compress)
                        {
                            Results.UpdatePreviousItem(current.RealSize);                             // Update with the real (compressed) size of the data
                        }
                        continue;
                    }
                }

                // Early stop check
                if (Manager.ShouldStop)
                {
                    Engine.Logger.ItemFailed(current, "The build process was stopped while the item was being built");
                    break;
                }

                // Run the importer
                FileStream importStream = null;
                FileInfo   importInfo   = null;
                try
                {
                    importInfo   = new FileInfo(current.Paths.SourcePath);
                    importStream = importInfo.Open(FileMode.Open, FileAccess.Read, FileShare.Read);
                }
                catch (Exception e)
                {
                    Engine.Logger.ItemFailed(current, $"The item source file could not be opened, {e.Message}");
                    continue;
                }
                object importedData = null;
                try
                {
                    _logger.UpdateStageName(current.ImporterName);
                    ImporterContext ctx = new ImporterContext(this, _logger, importInfo);
                    importedData = importer.Instance.Import(importStream, ctx);
                    if (importedData == null)
                    {
                        Engine.Logger.ItemFailed(current, "The importer for the item did not produce any data");
                        continue;
                    }

                    // Save the dependencies to the event
                    if (ctx.Dependencies.Count > 0)
                    {
                        foreach (var ed in ctx.Dependencies)
                        {
                            current.ExternalDependencies.Add((ed, File.GetLastWriteTimeUtc(ed)));
                        }
                    }
                }
                catch (Exception e)
                {
                    int    pos = e.StackTrace.IndexOf(" at ");
                    string loc = e.StackTrace.Substring(pos + 4).Split('\n')[0];
                    Engine.Logger.ItemFailed(current, $"Unhandled exception in importer, {e.Message} ({e.GetType().Name})\n Source: {loc}");
                    if (e.InnerException != null)
                    {
                        Engine.Logger.ItemFailed(current, $"Inner Exception ({e.InnerException.GetType().Name}): {e.InnerException.Message}");
                    }
                    continue;
                }
                finally
                {
                    importStream.Dispose();
                }

                // Early stop check
                if (Manager.ShouldStop)
                {
                    Engine.Logger.ItemFailed(current, "The build process was stopped while the item was being built");
                    break;
                }

                // Run the processor
                Engine.Logger.ItemContinue(current, BuildLogger.ContinueStage.Processing);
                object processedData = null;
                try
                {
                    _logger.UpdateStageName(current.ProcessorName);
                    ProcessorContext ctx = new ProcessorContext(this, _logger, importInfo);
                    processor.UpdateFields(Engine, current);
                    processedData = processor.Instance.Process(importedData, ctx);
                    if (processedData == null)
                    {
                        Engine.Logger.ItemFailed(current, "The processor for the item did not produce any data");
                        continue;
                    }
                }
                catch (Exception e)
                {
                    int    pos = e.StackTrace.IndexOf(" at ");
                    string loc = e.StackTrace.Substring(pos + 4).Split('\n')[0];
                    Engine.Logger.ItemFailed(current, $"Unhandled exception in processor, {e.Message} ({e.GetType().Name})\n Source: {loc}");
                    if (e.InnerException != null)
                    {
                        Engine.Logger.ItemFailed(current, $"Inner Exception ({e.InnerException.GetType().Name}): {e.InnerException.Message}");
                    }
                    continue;
                }

                // Early stop check
                if (Manager.ShouldStop)
                {
                    Engine.Logger.ItemFailed(current, "The build process was stopped while the item was being built");
                    break;
                }

                // Delete the output and cache files
                try
                {
                    if (File.Exists(current.Paths.OutputPath))
                    {
                        File.Delete(current.Paths.OutputPath);
                    }
                    if (File.Exists(current.CachePath))
                    {
                        File.Delete(current.CachePath);
                    }
                }
                catch
                {
                    Engine.Logger.ItemFailed(current, "Could not delete the output file to rebuild the item");
                    continue;
                }

                // Run the writer
                Engine.Logger.ItemContinue(current, BuildLogger.ContinueStage.Writing);
                try
                {
                    _logger.UpdateStageName(processor.Type.WriterType.Name);
                    uint lastRealSize = cStream.Reset(current.Paths.OutputPath, compress);
                    if (lastRealSize != 0)
                    {
                        Results.UpdatePreviousItem(lastRealSize);
                    }
                    WriterContext ctx = new WriterContext(this, _logger, importInfo);
                    processor.WriterInstance.Write(processedData, cStream, ctx);
                    cStream.Flush();
                }
                catch (Exception e)
                {
                    int    pos = e.StackTrace.IndexOf(" at ");
                    string loc = e.StackTrace.Substring(pos + 4).Split('\n')[0];
                    Engine.Logger.ItemFailed(current, $"Unhandled exception in writer, {e.Message} ({e.GetType().Name})\n Source: {loc}");
                    if (e.InnerException != null)
                    {
                        Engine.Logger.ItemFailed(current, $"Inner Exception ({e.InnerException.GetType().Name}): {e.InnerException.Message}");
                    }
                    continue;
                }

                // Save the cache
                current.SaveCache(Engine, cStream.OutputSize, compress);

                // Report end
                Engine.Logger.ItemFinished(current, _timer.Elapsed);
                Results.PassItem(cStream.OutputSize, false);
            }

            // Wait for the final output to be complete
            uint realsize = cStream.Reset(null, false);

            if (realsize != 0)
            {
                Results.UpdatePreviousItem(realsize);
            }
            Results.UseItem(null);             // In the case that the last item fails
        }
Ejemplo n.º 4
0
 internal void ItemStats(BuildEvent evt, string message) =>
 _messages.Enqueue(new Message(MessageType.ItemStats, _startTime + _timer.Elapsed, evt.Item, evt.Index, message));
Ejemplo n.º 5
0
 internal void ItemInfo(BuildEvent evt, string message, bool important = false) =>
 _messages.Enqueue(new Message(MessageType.ItemInfo, _startTime + _timer.Elapsed, evt.Item, evt.Index, message, important));
Ejemplo n.º 6
0
 internal void ItemSkipped(BuildEvent evt) =>
 _messages.Enqueue(new Message(MessageType.ItemSkipped, _startTime + _timer.Elapsed, evt.Item, evt.Index));
Ejemplo n.º 7
0
 internal void ItemFinished(BuildEvent evt, TimeSpan elapsed) =>
 _messages.Enqueue(new Message(MessageType.ItemFinished, _startTime + _timer.Elapsed, evt.Item, evt.Index, elapsed));
Ejemplo n.º 8
0
 internal void ItemContinue(BuildEvent evt, ContinueStage stage) =>
 _messages.Enqueue(new Message(MessageType.ItemContinued, _startTime + _timer.Elapsed, evt.Item, evt.Index, stage));