using System.IO; using System.Collections.Generic; using UnityEditor; using UnityEditor.SceneManagement; using UnityEngine.SceneManagement; using Codice.Client.BaseCommands; using Codice.Client.Common; using Unity.PlasticSCM.Editor.AssetUtils.Processor; namespace Unity.PlasticSCM.Editor.AssetUtils { internal static class SaveAssets { internal static void UnderWorkspaceWithConfirmation( string wkPath, WorkspaceOperationsMonitor workspaceOperationsMonitor, out bool isCancelled) { ForPaths( wkPath, null, true, workspaceOperationsMonitor, out isCancelled); } internal static void ForChangesWithConfirmation( string wkPath, List changes, WorkspaceOperationsMonitor workspaceOperationsMonitor, out bool isCancelled) { ForPaths( wkPath, GetPaths(changes), true, workspaceOperationsMonitor, out isCancelled); } internal static void ForPathsWithConfirmation( string wkPath, List paths, WorkspaceOperationsMonitor workspaceOperationsMonitor, out bool isCancelled) { ForPaths( wkPath, paths, true, workspaceOperationsMonitor, out isCancelled); } internal static void ForChangesWithoutConfirmation( string wkPath, List changes, WorkspaceOperationsMonitor workspaceOperationsMonitor) { bool isCancelled; ForPaths( wkPath, GetPaths(changes), false, workspaceOperationsMonitor, out isCancelled); } internal static void ForPathsWithoutConfirmation( string wkPath, List paths, WorkspaceOperationsMonitor workspaceOperationsMonitor) { bool isCancelled; ForPaths( wkPath, paths, false, workspaceOperationsMonitor, out isCancelled); } static void ForPaths( string wkPath, List paths, bool askForUserConfirmation, WorkspaceOperationsMonitor workspaceOperationsMonitor, out bool isCancelled) { workspaceOperationsMonitor.Disable(); try { SaveDirtyScenes( wkPath, paths, askForUserConfirmation, out isCancelled); if (isCancelled) return; AssetDatabase.SaveAssets(); } finally { workspaceOperationsMonitor.Enable(); } } static void SaveDirtyScenes( string wkPath, List paths, bool askForUserConfirmation, out bool isCancelled) { isCancelled = false; List scenesToSave = GetScenesToSave(wkPath, paths); if (scenesToSave.Count == 0) return; if (askForUserConfirmation) { isCancelled = !EditorSceneManager. SaveModifiedScenesIfUserWantsTo( scenesToSave.ToArray()); if (!isCancelled) DiscardChangesInActiveSceneIfDirty(scenesToSave); return; } EditorSceneManager.SaveScenes( scenesToSave.ToArray()); } static void DiscardChangesInActiveSceneIfDirty(List scenesToSave) { string activeScenePath = EditorSceneManager.GetActiveScene().path; Scene? activeScene = GetSceneByPath(scenesToSave, activeScenePath); if (activeScene == null) return; if (!activeScene.Value.isDirty) return; EditorSceneManager.OpenScene(activeScenePath); } static Scene? GetSceneByPath(List scenes, string scenePath) { foreach (Scene scene in scenes) { if (scene.path == scenePath) return scene; } return null; } static List GetScenesToSave(string wkPath, List paths) { List dirtyScenes = GetDirtyScenesUnderWorkspace(wkPath); if (paths == null) return dirtyScenes; List scenesToSave = new List(); foreach (Scene dirtyScene in dirtyScenes) { if (Contains(paths, dirtyScene)) scenesToSave.Add(dirtyScene); } return scenesToSave; } static List GetDirtyScenesUnderWorkspace(string wkPath) { List dirtyScenes = new List(); for (int i = 0; i < SceneManager.sceneCount; i++) { Scene scene = SceneManager.GetSceneAt(i); if (!scene.isDirty) continue; if (string.IsNullOrEmpty(scene.path)) continue; string fullPath = Path.GetFullPath(scene.path); if (!PathHelper.IsContainedOn(fullPath, wkPath)) continue; dirtyScenes.Add(scene); } return dirtyScenes; } static bool Contains( List paths, Scene scene) { foreach (string path in paths) { if (PathHelper.IsSamePath( path, Path.GetFullPath(scene.path))) return true; } return false; } static List GetPaths( List changeInfos) { List result = new List(); foreach (ChangeInfo change in changeInfos) result.Add(change.GetFullPath()); return result; } } }