public BuildTaskManager(BuildEngine engine, uint threads)
        {
            Engine = engine;

            TempFilePath = Path.Combine(engine.Project.Paths.IntermediateRoot, ".__tmp__");

            _tasks = new BuildTask[threads];
            for (uint i = 0; i < threads; ++i)
            {
                _tasks[i] = new BuildTask(this);
            }
        }
Beispiel #2
0
        // Attempts to create an ImporterType out of a passed type, will return null if it is invalid
        public static ImporterType TryCreate(BuildEngine engine, Type type)
        {
            // Check if it is derived from IContentImporter
            if (type.GetInterface(INTERFACE_NAME) == null)
            {
                return(null);
            }

            // Must have the correct attribute
            ContentImporterAttribute attrib =
                (ContentImporterAttribute)type.GetCustomAttributes(ATTRIBUTE_TYPE, false)?.FirstOrDefault();

            if (attrib == null)
            {
                engine.Logger.EngineError($"The type '{type.FullName}' is a ContentImporter but is missing the required attribute.");
                return(null);
            }
            if (!attrib.Enabled)
            {
                engine.Logger.EngineInfo($"Skipping ContentImporter type '{type.FullName}' - it is marked as disabled.");
                return(null);
            }

            // Validate the attribute information
            if (attrib.DefaultProcessor?.GetInterface(ProcessorType.INTERFACE_NAME) == null)
            {
                TypeError(engine, type, $"has an invalid default ContentProcessor type '{attrib.DefaultProcessor?.FullName}'");
                return(null);
            }
            if (attrib.DisplayName == null)
            {
                TypeError(engine, type, "cannot have a null display name.");
                return(null);
            }

            // Ensure some required type info
            if (type.IsAbstract)
            {
                TypeError(engine, type, "is abstract and cannot be instantiated.");
                return(null);
            }
            if (type.GetConstructor(BindingFlags.Instance | BindingFlags.Public, null, CallingConventions.HasThis, new Type[0], null) == null)
            {
                TypeError(engine, type, "does not have a public no-args constructor, and cannot be instantiated.");
                return(null);
            }

            // Good to go
            return(new ImporterType(type, attrib));
        }
Beispiel #3
0
        public StageCache(BuildEngine engine)
        {
            Engine      = engine;
            _importers  = new Dictionary <string, ImporterType>();
            _processors = new Dictionary <string, ProcessorType>();

            // Add the builtin importers
            // TODO: This list must be updated whenever new builtin stages are added, or else they wont appear
            _importers.Add(nameof(PassthroughImporter), ImporterType.TryCreate(engine, typeof(PassthroughImporter)));
            _importers.Add(nameof(TextureImporter), ImporterType.TryCreate(engine, typeof(TextureImporter)));
            _importers.Add(nameof(AudioImporter), ImporterType.TryCreate(engine, typeof(AudioImporter)));

            // Add the builtin processors
            // TODO: This list must be updated whenever new builtin stages are added, or else they wont appear
            _processors.Add(nameof(PassthroughProcessor), ProcessorType.TryCreate(engine, typeof(PassthroughProcessor)));
            _processors.Add(nameof(TextureProcessor), ProcessorType.TryCreate(engine, typeof(TextureProcessor)));
            _processors.Add(nameof(AudioProcessor), ProcessorType.TryCreate(engine, typeof(AudioProcessor)));
        }
Beispiel #4
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);
             }
         }
     }
 }
Beispiel #5
0
        // This is guarenteed to already a valid ContentProcessor type
        public static ProcessorField[] LoadFromType(BuildEngine engine, Type type)
        {
            var valInst = Activator.CreateInstance(type);             // Used to get the default values for all of the fields

            return(type
                   .GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly)
                   .Select(f => (field: f, attrib: (PipelineParameterAttribute)f.GetCustomAttribute(ATTRIBUTE_TYPE, false)))
                   .Where(f => f.attrib != null)
                   .Where(f => {
                if (f.field.IsInitOnly)
                {
                    engine.Logger.EngineWarn($"The ContentProcessor type '{type.Name}' cannot have a readonly pipeline parameter ({f.field.Name}).");
                    return false;
                }
                if (!ConverterCache.CanConvert(f.field.FieldType))
                {
                    engine.Logger.EngineWarn($"The ContentProcessor type '{type.Name}' declared the pipeline parameter '{f.field.Name}' with an invalid type.");
                    return false;
                }
                return true;
            })
                   .Select(f => new ProcessorField(f.field, f.attrib, f.field.GetValue(valInst)))
                   .ToArray());
        }
Beispiel #6
0
        // Attempts to create an ProcessorType out of a passed type, will return null if it is invalid
        public static ProcessorType TryCreate(BuildEngine engine, Type type)
        {
            // Check if it is derived from IContentProcessor
            if (type.GetInterface(INTERFACE_NAME) == null)
            {
                return(null);
            }

            // Must have the correct attribute
            ContentProcessorAttribute attrib =
                (ContentProcessorAttribute)type.GetCustomAttributes(ATTRIBUTE_TYPE, false)?.FirstOrDefault();

            if (attrib == null)
            {
                engine.Logger.EngineError($"The type '{type.FullName}' is a ContentProcessor but is missing the required attribute.");
                return(null);
            }
            if (!attrib.Enabled)
            {
                engine.Logger.EngineInfo($"Skipping ContentProcessor type '{type.FullName}' - it is marked as disabled.");
                return(null);
            }

            // Validate the attribute information
            if (attrib.DisplayName == null)
            {
                TypeError(engine, type, "cannot have a null display name.");
                return(null);
            }

            // Ensure some required type info
            if (type.IsAbstract)
            {
                TypeError(engine, type, "is abstract and cannot be instantiated.");
                return(null);
            }
            if (type.GetConstructor(BindingFlags.Instance | BindingFlags.Public, null, CallingConventions.HasThis, new Type[0], null) == null)
            {
                TypeError(engine, type, "does not have a public no-args constructor, and cannot be instantiated.");
                return(null);
            }

            // Validate the specified content writer
            Type writerType = type.BaseType.GetGenericArguments()[2];

            if (writerType.IsAbstract)
            {
                WriterError(engine, writerType, "is abstract and cannot be instantiated.");
                return(null);
            }
            if (writerType.GetConstructor(BindingFlags.Instance | BindingFlags.Public, null, CallingConventions.HasThis, new Type[0], null) == null)
            {
                WriterError(engine, writerType, "does not have a public no-args constructor, and cannot be instantiated.");
                return(null);
            }

            // Get the fields
            var fields = ProcessorField.LoadFromType(engine, type);

            if (fields == null)
            {
                return(null);
            }

            // Good to go
            return(new ProcessorType(type, fields, attrib));
        }
Beispiel #7
0
 private static void WriterError(BuildEngine engine, Type type, string error) =>
 engine.Logger.EngineError($"The ContentWriter type '{type.FullName}' {error}.");