// Можем импортнуть файл кода или библиотеку, в котором есть конфиг. Надо пересобрать библиотеку.
        // Можем удалить файл кода или библиотеку, в котором есть конфиг. Надо пересобрать библиотеку.


        // Можем переместить импортнуть ассет, который попадает в источник. Надо пересобрать все машруты с этим ассетом.
        // Можем удалить ассет, который попадает в источник. Надо пересобрать все машруты с этим ассетом.
        // Можем переместить ассет, который попадает в источник. Надо проверить, что исходный и конечный источник тот же. Если тот же - игнорировать. Если изменился - надо пересобрать все маршруты.
        // Можем импортнуть новый источник. Надо пересобрать все его маршруты.
        // Можем удалить источник. Надо пересобрать все маршруты, которые он затрагивал.
        // Можем переместить источни. Надо пересобрать его маршруты.
        // Можем импортнуть новое хранилище. Надо пересобрать все его маршруты.

        // Можем переместить файл кода или библиотеку, в котором есть конфиг. Ничего не делать.
        // Можем удалить хранилище. Ничего не делать.
        // Можем переместить хранилище. Ничего не делать.
        private static void ProcessAssets(YamlyPostprocessAssetsContext ctx)
        {
            var assemblies = GetAssemblies();

            InitRoots(assemblies);

            if (!_rebuildAssemblyAfterReloadScriptsPending)
            {
                if (assemblies.ProxyAssembly == null ||
                    assemblies.IsProxyAssemblyInvalid ||
                    string.IsNullOrEmpty(assemblies.ProxyAssembly.Location))
                {
                    if (_roots.Any())
                    {
                        BuildAssembly(assemblies);
                    }
                    return;
                }
            }

            var codeAssets = AssetDatabase.FindAssets($"t:{nameof(TextAsset)}")
                             .Select(AssetDatabase.GUIDToAssetPath)
                             .Where(p => p.EndsWith(".cs"))
                             .Select(AssetDatabase.LoadAssetAtPath <TextAsset>)
                             .ToArray();

            var codeFilePaths = _roots.SelectMany(r => GetCodeFiles(r, codeAssets))
                                .Distinct()
                                .ToList();

            var exludedAssemblies = new List <string>
            {
                CodeGenerationUtility.GetUtilityAssemblySystemPath().ToAssetsPath()
            };

            var proxyAssemblyLocation = assemblies.ProxyAssembly?.Location.ToAssetsPath();

            if (!string.IsNullOrEmpty(proxyAssemblyLocation))
            {
                exludedAssemblies.Add(proxyAssemblyLocation);
            }

            var rebuildAssembly = false;

            foreach (var assetPath in ctx.ChangedAndDeletedAssets)
            {
                if (assetPath.EndsWith(".cs"))
                {
                    if (codeFilePaths.Contains(assetPath))
                    {
                        rebuildAssembly = true;
                    }
                }

                if (assetPath.EndsWith(".dll"))
                {
                    if (!exludedAssemblies.Contains(assetPath))
                    {
                        rebuildAssembly = true;
                    }
                }
            }

            if (rebuildAssembly ||
                _rebuildAssemblyAfterReloadScriptsPending)
            {
                if (!_rebuildAssemblyAfterReloadScriptsPending)
                {
                    YamlyEditorPrefs.IsAssemblyBuildPending = true;
                }
                YamlyEditorPrefs.AssetImportContext = new YamlyPostprocessAssetsContext
                {
                    ImportedAssets      = ctx.ImportedAssets.Where(p => !IsCodeFilePath(p)).ToArray(),
                    DeletedAssets       = ctx.DeletedAssets.Where(p => !IsCodeFilePath(p)).ToArray(),
                    MovedAssets         = ctx.MovedAssets.Where(p => !IsCodeFilePath(p)).ToArray(),
                    MovedFromAssetPaths = ctx.MovedFromAssetPaths.Where(p => !IsCodeFilePath(p)).ToArray()
                };
                return;
            }

            if (_roots.Count == 0)
            {
                return;
            }

            var sourceDefinitions = AssetUtility.LoadAll <FolderSource>()
                                    .Cast <SourceBase>()
                                    .Concat(AssetUtility.LoadAll <SingleSource>())
                                    .ToList();

            if (sourceDefinitions.Count == 0)
            {
                return;
            }

            var groups = _roots.SelectMany(r => r.Attributes)
                         .Select(a => a.Group)
                         .Distinct()
                         .ToArray();
            var storageDefinitions = AssetUtility.LoadAll <Storage>().ToList();

            for (var i = 0; i < storageDefinitions.Count; i++)
            {
                var storage = storageDefinitions[i];
                storage.ExcludedGroups.RemoveAll(g => !groups.Contains(g));
                foreach (var s in storage.Storages)
                {
                    if (s == null ||
                        !storage.Includes(s.Group))
                    {
                        Object.DestroyImmediate(s, true);

                        EditorUtility.SetDirty(storage);
                    }
                }

                storage.Storages.RemoveAll(s => s == null);

                var assets         = AssetDatabase.LoadAllAssetsAtPath(storage.GetAssetPath());
                var haveNullAssets = false;
                foreach (var asset in assets)
                {
                    if (asset == storage)
                    {
                        continue;
                    }

                    if (storage.Storages.Contains(asset))
                    {
                        continue;
                    }

                    if (asset == null)
                    {
                        haveNullAssets = true;
                    }

                    Object.DestroyImmediate(asset, true);
                }

                if (haveNullAssets)
                {
                    var assetPath   = storage.GetAssetPath();
                    var storages    = storage.Storages.ToArray();
                    var storageName = storage.name;
                    storage      = Object.Instantiate(storage);
                    storage.name = storageName;
                    storage.Storages.Clear();
                    foreach (var storageBase in storages)
                    {
                        var instance = Object.Instantiate(storageBase);
                        instance.name = storageBase.name;

                        storage.Storages.Add(instance);
                    }

                    if (Settings.VerboseLogs)
                    {
                        Debug.Log($"Storage at path ${assetPath} contains missing storage instances and will be overwritten.", storage);
                    }

                    AssetDatabase.DeleteAsset(assetPath);

                    AssetDatabase.StartAssetEditing();
                    {
                        AssetDatabase.CreateAsset(storage, assetPath);
                        foreach (var storageBase in storage.Storages)
                        {
                            AssetDatabase.AddObjectToAsset(storageBase, assetPath);
                        }
                    }
                    AssetDatabase.StopAssetEditing();

                    AssetDatabase.ImportAsset(assetPath);

                    storageDefinitions[i] = storage;
                }
            }

            var routes = new List <DataRoute>();

            foreach (var d in _roots)
            {
                var codePaths = GetCodeFiles(d, codeAssets);
                routes.AddRange(d.Attributes.Select(a => CreateRoute(d, a, sourceDefinitions, storageDefinitions, codePaths)));
            }

            var routesToRebuild = new List <DataRoute>();

            foreach (var assetPath in ctx.All)
            {
                foreach (var route in routes)
                {
                    if (routesToRebuild.Contains(route))
                    {
                        continue;
                    }

                    if (route.ContainsAsset(assetPath) ||
                        route.ContainsSource(assetPath) ||
                        route.ContainsStorage(assetPath))
                    {
                        routesToRebuild.Add(route);
                    }
                }
            }

            var context = new YamlyProjectContext
            {
                ProxyAssembly = assemblies.ProxyAssembly,
                Storages      = storageDefinitions,
                Sources       = sourceDefinitions,
                Roots         = _roots
            };

            foreach (var route in routesToRebuild)
            {
                Rebuild(route, context);
            }

            AssetDatabase.Refresh();
        }
Beispiel #2
0
        private static void ProcessAssets(YamlyPostprocessAssetsContext ctx)
        {
            Context.Init();
            Context.ClearAssetsCache();

            var assemblies = Context.Assemblies;
            var roots      = Context.Roots;

            if (!_rebuildAssemblyAfterReloadScriptsPending)
            {
                if (assemblies.ProxyAssembly == null ||
                    assemblies.IsProxyAssemblyInvalid ||
                    string.IsNullOrEmpty(assemblies.ProxyAssembly.Location))
                {
                    if (roots.Any())
                    {
                        BuildAssembly(assemblies);
                    }
                    return;
                }
            }

            var exludedAssemblies = new List <string>
            {
                CodeGenerationUtility.GetUtilityAssemblySystemPath().ToAssetsPath()
            };

            var proxyAssemblyLocation = assemblies.ProxyAssembly?.Location.ToAssetsPath();

            if (!string.IsNullOrEmpty(proxyAssemblyLocation))
            {
                exludedAssemblies.Add(proxyAssemblyLocation);
            }

            var rebuildAssembly = false;

            foreach (var assetPath in ctx.ChangedAndDeletedAssets)
            {
                if (roots.Any(r => IsCodeFile(r, assetPath)))
                {
                    rebuildAssembly = true;
                    break;
                }
            }

            if (rebuildAssembly ||
                _rebuildAssemblyAfterReloadScriptsPending)
            {
                if (!_rebuildAssemblyAfterReloadScriptsPending)
                {
                    YamlyEditorPrefs.IsAssemblyBuildPending = true;
                }
                YamlyEditorPrefs.AssetImportContext = new YamlyPostprocessAssetsContext
                {
                    ImportedAssets      = ctx.ImportedAssets.Where(p => !IsCodeFilePath(p)).ToArray(),
                    DeletedAssets       = ctx.DeletedAssets.Where(p => !IsCodeFilePath(p)).ToArray(),
                    MovedAssets         = ctx.MovedAssets.Where(p => !IsCodeFilePath(p)).ToArray(),
                    MovedFromAssetPaths = ctx.MovedFromAssetPaths.Where(p => !IsCodeFilePath(p)).ToArray()
                };
                return;
            }

            if (roots.Count == 0)
            {
                LogUtils.Verbose("Stop processing: no roots found.");
                return;
            }

            var sources = Context.Sources;

            if (sources.Count == 0)
            {
                LogUtils.Verbose("Stop processing: no sources found.");
                return;
            }

            var groups   = Context.Groups;
            var storages = Context.Storages;

            CleanupStorages(storages, groups);

            var routes = new List <DataRoute>();

            foreach (var d in roots)
            {
                routes.AddRange(d.ValidAttributes.Select(a => CreateRoute(d, a, sources, storages)));
            }

            var routesToRebuild = new List <DataRoute>();

            foreach (var assetPath in ctx.All)
            {
                foreach (var route in routes)
                {
                    if (routesToRebuild.Contains(route))
                    {
                        continue;
                    }

                    if (route.ContainsAsset(assetPath) ||
                        route.ContainsSource(assetPath) ||
                        route.ContainsStorage(assetPath))
                    {
                        routesToRebuild.Add(route);
                    }
                }
            }

            foreach (var route in routesToRebuild)
            {
                Rebuild(route);
            }

            foreach (var route in routesToRebuild)
            {
                PostProcess(route);
            }

            AssetDatabase.Refresh();
        }