예제 #1
0
        internal static void Rebuild(DataRoute route, YamlyProjectContext ctx)
        {
            var groupName = route.Group;

            if (route.Sources.Count == 0)
            {
                Debug.LogWarning($"Group {groupName} have no sources.");
                return;
            }

            if (route.Storages.Count == 0)
            {
                Debug.LogWarning($"Group {groupName} have no storages.");
                return;
            }

            if (Settings.VerboseLogs)
            {
                Debug.Log($"Rebuild group {groupName} from {route.Sources.Count} sources to {route.Storages.Count} storages.");
            }

            var result = ctx.AssetProcessor.Rebuild(route);

            foreach (var e in result.Errors)
            {
                Debug.LogError(e.Error, e.TextAsset);
            }
        }
예제 #2
0
        internal static void Rebuild(string groupName, YamlyProjectContext ctx)
        {
            if (ctx == null)
            {
                ctx = GetContext();
            }

            var root      = ctx.Roots.Find(r => r.Contains(groupName));
            var attribute = root.Attributes.Find(a => a.Group == groupName);
            var route     = CreateRoute(root, attribute, ctx.Sources, ctx.Storages);

            Rebuild(route, ctx);
        }
예제 #3
0
        internal static void Validate(string groupName, YamlyProjectContext ctx)
        {
            if (ctx == null)
            {
                ctx = GetContext();
            }

            if (ctx.Sources.Count == 0)
            {
                Debug.LogWarning("No source definitions exist! Validation canceled!");
                return;
            }

            var targetRoot = _roots.Find(r => r.Contains(groupName));
            var attribute  = targetRoot.Attributes.Find(a => a.Group == groupName);
            var route      = CreateRoute(targetRoot, attribute, ctx);

            if (route.Sources.Count == 0)
            {
                Debug.LogWarning($"Group {groupName} have no sources.");
                return;
            }

            Debug.Log($"Validate {groupName} with {ctx.Sources.Count} sources and {ctx.Storages.Count} storages");

            var result = ctx.AssetProcessor.Validate(route);

            if (result.Errors.Any())
            {
                foreach (var e in result.Errors)
                {
                    Debug.LogError(e.Error, e.TextAsset);
                }
            }
            else
            {
                Debug.Log($"Group {groupName} have no errors!");
            }
        }
예제 #4
0
        internal static void CreateDefaultAssetOnSelection(string group, YamlyProjectContext ctx)
        {
            if (ctx == null)
            {
                ctx = GetContext();
            }

            var root       = ctx.Roots.Find(r => r.Contains(group));
            var assetPath  = Selection.activeObject.GetAssetPath();
            var folderPath = string.IsNullOrEmpty(System.IO.Path.GetExtension(assetPath))
                ? assetPath
                : assetPath.GetAssetPathFolder();
            var fileName   = root.Root.Name;
            var targetPath = $"{folderPath}{fileName}.yaml";
            var index      = 1;

            while (System.IO.File.Exists(targetPath.ToSystemPath()))
            {
                targetPath = $"{folderPath}{fileName}{index}.yaml";
                index++;
            }

            object instance;

            var constructors = root.Root.GetConstructors(BindingFlags.Public | BindingFlags.NonPublic).ToList();

            if (constructors.Count == 0)
            {
                instance = Activator.CreateInstance(root.Root);
            }
            else
            {
                var parameterlessConstructor = constructors.Find(c => c.GetParameters().Length == 0);
                if (parameterlessConstructor != null)
                {
                    instance = Activator.CreateInstance(root.Root);
                }
                else
                {
                    var constructor     = constructors.OrderBy(c => c.GetParameters().Length).First();
                    var parameters      = constructor.GetParameters();
                    var parameterValues = new object[parameters.Length];
                    for (int i = 0; i < parameters.Length; i++)
                    {
                        var parameterType = parameters[i].ParameterType;
                        if (parameterType.IsValueType)
                        {
                            parameterValues[i] = Activator.CreateInstance(parameterType);
                        }
                        else
                        {
                            parameterValues[i] = null;
                        }
                    }

                    instance = Activator.CreateInstance(root.Root, parameterValues);
                }
            }

            var serializer = new SerializerBuilder().EmitDefaults().Build();
            var text       = serializer.Serialize(instance);

            System.IO.File.WriteAllText(targetPath.ToSystemPath(), text);
            AssetDatabase.Refresh();
        }
예제 #5
0
 private static DataRoute CreateRoute(RootDefinition d,
                                      AssetDeclarationAttributeBase a,
                                      YamlyProjectContext c)
 {
     return(CreateRoute(d, a, c.Sources, c.Storages));
 }
예제 #6
0
        // Можем импортнуть файл кода или библиотеку, в котором есть конфиг. Надо пересобрать библиотеку.
        // Можем удалить файл кода или библиотеку, в котором есть конфиг. Надо пересобрать библиотеку.


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

        // Можем переместить файл кода или библиотеку, в котором есть конфиг. Ничего не делать.
        // Можем удалить хранилище. Ничего не делать.
        // Можем переместить хранилище. Ничего не делать.
        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();
        }