Esempio n. 1
0
        public static void Init()
        {
            if (_init)
            {
                return;
            }

            LogUtils.Verbose("Context.Init");

            _init = true;

            foreach (var source in Sources)
            {
                _assets[source.GetAssetPath()] = source;
            }

            foreach (var storage in Storages)
            {
                _assets[storage.GetAssetPath()] = storage;
            }

            var assemblies = Assemblies;

            if (assemblies.ProxyAssembly == null)
            {
                return;
            }

            try
            {
                var roots            = Roots;
                var wellLocatedRoots = new List <RootDefinition>();
                foreach (var r in roots.All)
                {
                    if (!assemblies.IsAssemblyValidForRoot(r.Assembly))
                    {
                        LogUtils.Warning($"Config root {r.Root.FullName} is defined in assembly {r.Assembly.FullName}. This is not supported - please put it into separate assembly with AssemblyDefinition or manually.");
                        continue;
                    }

                    wellLocatedRoots.Add(r);
                }

                var validGroups     = new List <string>();
                var validAttributes = new List <AssetDeclarationAttributeBase>();

                var attributes = wellLocatedRoots.SelectMany(r => r.Attributes)
                                 .ToList();
                var groups = attributes.Select(a => a.Group)
                             .ToList();
                foreach (var attribute in attributes)
                {
                    if (groups.Count(g => g == attribute.Group) > 1)
                    {
                        var duplicateRoots = wellLocatedRoots.Where(r => r.Contains(attribute.Group));

                        var log = new StringBuilder();
                        log.AppendFormat("Group name \"{0}\" is declared multiple times. This is not supported.",
                                         attribute.Group)
                        .AppendLine();
                        log.AppendLine("Declarations found in these types:");
                        foreach (var root in duplicateRoots)
                        {
                            log.AppendFormat("{0} ({1})", root.Root.Name, root.Root.AssemblyQualifiedName)
                            .AppendLine();
                        }

                        log.AppendLine("These group will be ignored until duplication is fixed.");

                        LogUtils.Error(log);
                        continue;
                    }

                    if (!CodeGenerationUtility.IsValidGroupName(attribute.Group))
                    {
                        LogUtils.Error($"Group {attribute.Group} name is not valid! Group will be ignored.");
                        continue;
                    }

                    validAttributes.Add(attribute);
                    validGroups.Add(attribute.Group);
                }

                _groups    = validGroups;
                Attributes = validAttributes;
            }
            catch (Exception e)
            {
                LogUtils.Verbose(e);
            }

            try
            {
                var postprocessorType  = typeof(IPostProcessAssets);
                var postprocessorTypes = assemblies.All
                                         .SelectMany(a => a.GetTypes())
                                         .Where(t => !t.IsAbstract && !t.IsInterface)
                                         .Where(t => postprocessorType.IsAssignableFrom(t))
                                         .ToList();

                PostProcessors = new List <IPostProcessAssets>();
                var ordered      = new Dictionary <int, List <IPostProcessAssets> >();
                var orders       = new Dictionary <IPostProcessAssets, PostProcessOrderAttribute>();
                var defaultOrder = new PostProcessOrderAttribute();
                Func <int, List <IPostProcessAssets> > getGroup = i =>
                {
                    List <IPostProcessAssets> g;
                    if (ordered.TryGetValue(i, out g))
                    {
                        return(g);
                    }
                    g = new List <IPostProcessAssets>();

                    ordered[i] = g;

                    return(g);
                };
                Func <IPostProcessAssets, PostProcessOrderAttribute> getOrder = a =>
                {
                    PostProcessOrderAttribute o;
                    if (!orders.TryGetValue(a, out o) ||
                        o == null)
                    {
                        o = defaultOrder;
                    }

                    return(o);
                };
                foreach (var type in postprocessorTypes)
                {
                    try
                    {
                        var instance = Activator.CreateInstance(type, type.IsNotPublic) as IPostProcessAssets;
                        PostProcessors.Add(instance);

                        var order = type.GetSingle <PostProcessOrderAttribute>()
                                    ?? defaultOrder;

                        orders[instance] = order;

                        getGroup(order.Group).Add(instance);
                    }
                    catch (Exception e)
                    {
                        LogUtils.Verbose(e);
                    }
                }

                foreach (var p in ordered)
                {
                    p.Value.Sort((a1, a2) => getOrder(a1).Order.CompareTo(getOrder(a1).Order));
                }

                OrderedPostProcessors = new IPostProcessAssets[ordered.Count][];
                var index = 0;
                foreach (var groupIndex in ordered.Keys.OrderBy(k => k))
                {
                    var g = ordered[groupIndex];
                    if (g == null || g.Count == 0)
                    {
                        continue;
                    }
                    OrderedPostProcessors[index] = g.ToArray();
                    index++;
                }
            }
            catch (Exception e)
            {
                LogUtils.Verbose(e);
            }
        }