This commit is contained in:
2025-01-17 13:10:42 +01:00
commit 4536213c91
15115 changed files with 1442174 additions and 0 deletions

View File

@@ -0,0 +1,128 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using UnityEditor;
using UnityEngine;
using Codice.Client.BaseCommands;
using Codice.Client.Common;
using Codice.CM.Common;
using Codice.Utils;
using PlasticGui;
namespace Unity.PlasticSCM.Editor.AssetUtils
{
internal static class AssetsPath
{
internal static class GetFullPath
{
internal static string ForObject(Object obj)
{
string relativePath = AssetDatabase.GetAssetPath(obj);
if (string.IsNullOrEmpty(relativePath))
return null;
return Path.GetFullPath(relativePath);
}
internal static string ForGuid(string guid)
{
string relativePath = GetAssetPath(guid);
if (string.IsNullOrEmpty(relativePath))
return null;
return Path.GetFullPath(relativePath);
}
}
internal static class GetFullPathUnderWorkspace
{
internal static string ForAsset(
string wkPath,
string assetPath)
{
if (string.IsNullOrEmpty(assetPath))
return null;
string fullPath = Path.GetFullPath(assetPath);
if (!PathHelper.IsContainedOn(fullPath, wkPath))
return null;
if (!fullPath.StartsWith("/"))
fullPath = fullPath.Substring(0, 1).ToLowerInvariant() + fullPath.Substring(1);
return fullPath.TrimEnd('/', '\\');
}
internal static string ForGuid(
string wkPath,
string guid)
{
return ForAsset(wkPath, GetAssetPath(guid));
}
}
internal static string GetLayoutsFolderRelativePath()
{
return string.Concat(mAssetsFolderLocation, "/Layouts");
}
internal static string GetStylesFolderRelativePath()
{
return string.Concat(mAssetsFolderLocation, "/Styles");
}
internal static string GetImagesFolderRelativePath()
{
return string.Concat(mAssetsFolderLocation, "/Images");
}
internal static string GetRelativePath(string fullPath)
{
return PathHelper.GetRelativePath(
mProjectFullPath, fullPath).Substring(1);
}
internal static bool IsRunningAsUPMPackage()
{
string unityPlasticDllPath = Path.GetFullPath(
AssemblyLocation.GetAssemblyDirectory(
Assembly.GetAssembly(typeof(PlasticLocalization))));
return Directory.Exists(
Path.GetFullPath(Path.Combine(
unityPlasticDllPath,
// assets relative path when running as a UPM package
"../../../Editor/PlasticSCM/Assets")));
}
static string GetAssetPath(string guid)
{
if (string.IsNullOrEmpty(guid))
return null;
return AssetDatabase.GUIDToAssetPath(guid);
}
internal static bool IsPackagesRootElement(string path)
{
return PathHelper.IsSamePath(mProjectPackagesFullPath, PathHelper.GetParentPath(path));
}
static AssetsPath()
{
mAssetsFolderLocation = (IsRunningAsUPMPackage()) ?
"Packages/com.unity.collab-proxy/Editor/PlasticSCM/Assets" :
"Assets/Plugins/PlasticSCM/Editor/Assets";
}
static readonly string mProjectFullPath = ProjectPath.FromApplicationDataPath(ApplicationDataPath.Get());
static readonly string mProjectPackagesFullPath = Path.Combine(mProjectFullPath, "Packages");
static string mAssetsFolderLocation;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a077a49d9db9de74f827f0568f6e65c2
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,58 @@
using System.Collections.Generic;
using System.IO;
using Unity.PlasticSCM.Editor.AssetMenu;
using Unity.PlasticSCM.Editor.AssetsOverlays.Cache;
using UnityEditor.VersionControl;
namespace Unity.PlasticSCM.Editor.AssetUtils
{
internal static class GetSelectedPaths
{
internal static List<string> ForOperation(
string wkPath,
AssetList assetList,
IAssetStatusCache assetStatusCache,
AssetMenuOperations operation)
{
List<string> selectedPaths = AssetsSelection.
GetSelectedPaths(wkPath, assetList);
List<string> result = new List<string>(selectedPaths);
foreach (string path in selectedPaths)
{
if (MetaPath.IsMetaPath(path))
continue;
string metaPath = MetaPath.GetMetaPath(path);
if (!File.Exists(metaPath))
continue;
if (result.Contains(metaPath))
continue;
if (!IsApplicableForOperation(
metaPath, false, operation, assetStatusCache))
continue;
result.Add(metaPath);
}
return result;
}
static bool IsApplicableForOperation(
string path,
bool isDirectory,
AssetMenuOperations operation,
IAssetStatusCache assetStatusCache)
{
SelectedAssetGroupInfo info = SelectedAssetGroupInfo.BuildFromSingleFile(
path, isDirectory, assetStatusCache);
return AssetMenuUpdater.GetAvailableMenuOperations(info).HasFlag(operation);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d9369fa547ca81b4fafa42a3e74c1b7a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,46 @@
using System;
using System.IO;
using UnityEditor;
using Codice.Client.BaseCommands;
namespace Unity.PlasticSCM.Editor.AssetUtils
{
internal static class LoadAsset
{
internal static UnityEngine.Object FromChangeInfo(ChangeInfo changeInfo)
{
string changeFullPath = changeInfo.GetFullPath();
if (MetaPath.IsMetaPath(changeFullPath))
changeFullPath = MetaPath.GetPathFromMetaPath(changeFullPath);
return FromFullPath(changeFullPath);
}
static UnityEngine.Object FromFullPath(string fullPath)
{
if (!IsPathUnderProject(fullPath))
return null;
return AssetDatabase.LoadMainAssetAtPath(
AssetsPath.GetRelativePath(fullPath));
}
static bool IsPathUnderProject(string path)
{
if (string.IsNullOrEmpty(path))
return false;
var fullPath = Path.GetFullPath(path).Replace('\\', '/');
return fullPath.StartsWith(
mProjectRelativePath,
StringComparison.OrdinalIgnoreCase);
}
static string mProjectRelativePath =
Directory.GetCurrentDirectory().Replace('\\', '/') + '/';
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 91f74d588534bef42ac4b919a2ece84a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: e5a9787c5ed94504798db0c3330424fe
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,106 @@
using UnityEditor;
using Codice.LogWrapper;
using Unity.PlasticSCM.Editor.AssetsOverlays.Cache;
using Unity.PlasticSCM.Editor.UI;
using AssetOverlays = Unity.PlasticSCM.Editor.AssetsOverlays;
namespace Unity.PlasticSCM.Editor.AssetUtils.Processor
{
class AssetModificationProcessor : UnityEditor.AssetModificationProcessor
{
internal static bool ForceCheckout { get; private set; }
/* We need to do a checkout, verifying that the content/date or size has changed.
* In order to do this checkout we need the changes to have reached the disk.
* That's why we save the changed files in this array, and when they are reloaded
* in AssetPostprocessor.OnPostprocessAllAssets we process them. */
internal static string[] ModifiedAssets { get; set; }
static AssetModificationProcessor()
{
ForceCheckout = EditorPrefs.GetBool(
UnityConstants.FORCE_CHECKOUT_KEY_NAME);
}
internal static void Enable(
string wkPath,
IAssetStatusCache assetStatusCache)
{
mLog.Debug("Enable");
mWkPath = wkPath;
mAssetStatusCache = assetStatusCache;
mIsEnabled = true;
}
internal static void Disable()
{
mLog.Debug("Disable");
mIsEnabled = false;
mWkPath = null;
mAssetStatusCache = null;
}
internal static void SetForceCheckoutOption(bool isEnabled)
{
ForceCheckout = isEnabled;
EditorPrefs.SetBool(
UnityConstants.FORCE_CHECKOUT_KEY_NAME,
isEnabled);
}
static string[] OnWillSaveAssets(string[] paths)
{
if (!mIsEnabled)
return paths;
ModifiedAssets = (string[])paths.Clone();
return paths;
}
static bool IsOpenForEdit(string assetPath, out string message)
{
message = string.Empty;
if (!mIsEnabled)
return true;
if (!ForceCheckout)
return true;
if (assetPath.StartsWith("ProjectSettings/"))
return true;
string assetFullPath = AssetsPath.GetFullPathUnderWorkspace.
ForAsset(mWkPath, assetPath);
if (assetFullPath == null)
return true;
if (MetaPath.IsMetaPath(assetFullPath))
assetFullPath = MetaPath.GetPathFromMetaPath(assetFullPath);
AssetOverlays.AssetStatus status = mAssetStatusCache.
GetStatus(assetFullPath);
if (AssetOverlays.ClassifyAssetStatus.IsAdded(status) ||
AssetOverlays.ClassifyAssetStatus.IsCheckedOut(status))
return true;
return !AssetOverlays.ClassifyAssetStatus.IsControlled(status);
}
static bool mIsEnabled;
static IAssetStatusCache mAssetStatusCache;
static string mWkPath;
static readonly ILog mLog = PlasticApp.GetLogger("AssetModificationProcessor");
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c53c624438663f74ab67fbdf8869ae18
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,199 @@
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using Codice.Client.Common;
using Codice.Client.Common.FsNodeReaders.Watcher;
using Codice.LogWrapper;
using Unity.PlasticSCM.Editor.UI;
namespace Unity.PlasticSCM.Editor.AssetUtils.Processor
{
class AssetPostprocessor : UnityEditor.AssetPostprocessor
{
internal static bool AutomaticAdd { get; private set; }
static AssetPostprocessor()
{
AutomaticAdd = BoolSetting.Load(UnityConstants.AUTOMATIC_ADD_KEY_NAME, true);
}
internal static void SetAutomaticAddOption(bool isEnabled)
{
if (AutomaticAdd != isEnabled)
{
AutomaticAdd = isEnabled;
BoolSetting.Save(isEnabled, UnityConstants.AUTOMATIC_ADD_KEY_NAME);
}
}
internal struct PathToMove
{
internal readonly string SrcPath;
internal readonly string DstPath;
internal PathToMove(string srcPath, string dstPath)
{
SrcPath = srcPath;
DstPath = dstPath;
}
}
internal static void Enable(
string wkPath,
PlasticAssetsProcessor plasticAssetsProcessor)
{
mLog.Debug("Enable");
mWkPath = wkPath;
mPlasticAssetsProcessor = plasticAssetsProcessor;
mIsEnabled = true;
}
internal static void Disable()
{
mLog.Debug("Disable");
mIsEnabled = false;
mWkPath = null;
mPlasticAssetsProcessor = null;
}
internal static void SetIsRepaintNeededAfterAssetDatabaseRefresh()
{
mIsRepaintNeededAfterAssetDatabaseRefresh = true;
}
static void OnPostprocessAllAssets(
string[] importedAssets,
string[] deletedAssets,
string[] movedAssets,
string[] movedFromAssetPaths)
{
if (!mIsEnabled)
return;
if (mIsRepaintNeededAfterAssetDatabaseRefresh)
{
mIsRepaintNeededAfterAssetDatabaseRefresh = false;
ProjectWindow.Repaint();
RepaintInspector.All();
}
// We need to ensure that the MonoFSWatcher is enabled before processing Plastic operations
// It fixes the following scenario:
// 1. Close PlasticSCM window
// 2. Create an asset, it appears with the added overlay
// 3. Open PlasticSCM window, the asset should appear as added instead of deleted locally
PlasticApp.EnableMonoFsWatcherIfNeeded();
mPlasticAssetsProcessor.MoveOnSourceControl(
ExtractPathsToMove(movedAssets, movedFromAssetPaths));
mPlasticAssetsProcessor.DeleteFromSourceControl(
GetPathsContainedOnWorkspace(mWkPath, deletedAssets));
if (AutomaticAdd)
{
mPlasticAssetsProcessor.AddToSourceControl(
GetPathsContainedOnWorkspace(mWkPath, importedAssets));
}
// We expect modified assets to go through AssetModificationProcessor.OnWillSaveAssets before getting here.
// To fix: there is a known limitation of renamed prefabs not triggering OnWillSaveAssets method.
if (AssetModificationProcessor.ModifiedAssets == null)
return;
mPlasticAssetsProcessor.CheckoutOnSourceControl(
GetPathsContainedOnWorkspace(
mWkPath, AssetModificationProcessor.ModifiedAssets));
AssetModificationProcessor.ModifiedAssets = null;
}
static List<PathToMove> ExtractPathsToMove(string[] movedAssets, string[] movedFromAssetPaths)
{
List<PathToMove> proposedPathsToMove = GetPathsToMoveContainedOnWorkspace(mWkPath, movedAssets, movedFromAssetPaths);
// Unity doesn't provide the moved paths ordered.
// We want to enqueue the batched movements in hierarchical order to avoid plastic considering assets as locally moved.
// It also avoid unnecessary children movements when their parents are also moved.
proposedPathsToMove.Sort((x, y) => PathHelper.GetPathMatchSorter().Compare(x.SrcPath, y.SrcPath));
List<PathToMove> pathsToMove = new List<PathToMove>();
foreach (PathToMove proposedPathToMove in proposedPathsToMove)
{
if (pathsToMove.Any(pathToMove => PathHelper.IsContainedOn(proposedPathToMove.SrcPath, pathToMove.SrcPath)))
{
continue;
}
pathsToMove.Add(proposedPathToMove);
}
return pathsToMove;
}
static List<PathToMove> GetPathsToMoveContainedOnWorkspace(
string wkPath,
string[] movedAssets,
string[] movedFromAssetPaths)
{
List<PathToMove> result = new List<PathToMove>(movedAssets.Length);
for (int i = 0; i < movedAssets.Length; i++)
{
string fullSrcPath = AssetsPath.GetFullPathUnderWorkspace.
ForAsset(wkPath, movedFromAssetPaths[i]);
if (fullSrcPath == null)
continue;
string fullDstPath = AssetsPath.GetFullPathUnderWorkspace.
ForAsset(wkPath, movedAssets[i]);
if (fullDstPath == null)
continue;
result.Add(new PathToMove(
fullSrcPath, fullDstPath));
}
return result;
}
static List<string> GetPathsContainedOnWorkspace(
string wkPath, string[] assets)
{
List<string> result = new List<string>(
assets.Length);
foreach (string asset in assets)
{
string fullPath = AssetsPath.GetFullPathUnderWorkspace.
ForAsset(wkPath, asset);
if (fullPath == null)
continue;
result.Add(fullPath);
}
return result;
}
static bool mIsEnabled;
static bool mIsRepaintNeededAfterAssetDatabaseRefresh;
static PlasticAssetsProcessor mPlasticAssetsProcessor;
static string mWkPath;
static readonly ILog mLog = PlasticApp.GetLogger("AssetPostprocessor");
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e9ffdef169b1cbb4e9910671a9ee83bc
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,22 @@
using Unity.PlasticSCM.Editor.AssetsOverlays.Cache;
namespace Unity.PlasticSCM.Editor.AssetUtils.Processor
{
internal static class AssetsProcessors
{
internal static void Enable(
string wkPath,
PlasticAssetsProcessor plasticAssetsProcessor,
IAssetStatusCache assetStatusCache)
{
AssetPostprocessor.Enable(wkPath, plasticAssetsProcessor);
AssetModificationProcessor.Enable(wkPath, assetStatusCache);
}
internal static void Disable()
{
AssetPostprocessor.Disable();
AssetModificationProcessor.Disable();
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 71cb30384b5f8d64ea7df220cff88d0c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,107 @@
using System;
using System.Collections.Generic;
using Codice.LogWrapper;
namespace Unity.PlasticSCM.Editor.AssetUtils.Processor
{
internal class PlasticAssetsProcessor : WorkspaceOperationsMonitor.IDisableAssetsProcessor
{
internal void SetWorkspaceOperationsMonitor(
WorkspaceOperationsMonitor workspaceOperationsMonitor)
{
mWorkspaceOperationsMonitor = workspaceOperationsMonitor;
}
internal void AddToSourceControl(List<string> paths)
{
if (paths.Count == 0)
return;
if (IsDisableBecauseExceptionHappened(DateTime.Now))
{
mLog.Warn(
"PlasticAssetsProcessor skipping AddToSourceControl operation " +
"because an exception happened in the last 60 seconds");
return;
}
foreach (string path in paths)
mLog.DebugFormat("AddToSourceControl: {0}", path);
mWorkspaceOperationsMonitor.AddAssetsProcessorPathsToAdd(paths);
}
internal void DeleteFromSourceControl(List<string> paths)
{
if (paths.Count == 0)
return;
if (IsDisableBecauseExceptionHappened(DateTime.Now))
{
mLog.Warn(
"PlasticAssetsProcessor skipping DeleteFromSourceControl operation " +
"because an exception happened in the last 60 seconds");
return;
}
foreach (string path in paths)
mLog.DebugFormat("DeleteFromSourceControl: {0}", path);
mWorkspaceOperationsMonitor.AddAssetsProcessorPathsToDelete(paths);
}
internal void MoveOnSourceControl(List<AssetPostprocessor.PathToMove> paths)
{
if (paths.Count == 0)
return;
if (IsDisableBecauseExceptionHappened(DateTime.Now))
{
mLog.Warn(
"PlasticAssetsProcessor skipping MoveOnSourceControl operation " +
"because an exception happened in the last 60 seconds");
return;
}
foreach (AssetPostprocessor.PathToMove path in paths)
mLog.DebugFormat("MoveOnSourceControl: {0} to {1}", path.SrcPath, path.DstPath);
mWorkspaceOperationsMonitor.AddAssetsProcessorPathsToMove(paths);
}
internal void CheckoutOnSourceControl(List<string> paths)
{
if (paths.Count == 0)
return;
if (IsDisableBecauseExceptionHappened(DateTime.Now))
{
mLog.Warn(
"PlasticAssetsProcessor skipping CheckoutOnSourceControl operation " +
"because an exception happened in the last 60 seconds");
return;
}
foreach (string path in paths)
mLog.DebugFormat("CheckoutOnSourceControl: {0}", path);
mWorkspaceOperationsMonitor.AddAssetsProcessorPathsToCheckout(paths);
}
void WorkspaceOperationsMonitor.IDisableAssetsProcessor.Disable()
{
mLastExceptionDateTime = DateTime.Now;
}
bool IsDisableBecauseExceptionHappened(DateTime now)
{
return (now - mLastExceptionDateTime).TotalSeconds < 5;
}
DateTime mLastExceptionDateTime = DateTime.MinValue;
WorkspaceOperationsMonitor mWorkspaceOperationsMonitor;
static readonly ILog mLog = PlasticApp.GetLogger("PlasticAssetsProcessor");
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d3daa94b5fca9a648b12f6ef2aae752f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: fdec637f96aaa6546ad88a90cae5dcf1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,12 @@
using System.IO;
namespace Unity.PlasticSCM.Editor.AssetUtils
{
internal static class ProjectPath
{
internal static string FromApplicationDataPath(string dataPath)
{
return Path.GetDirectoryName(Path.GetFullPath(dataPath));
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6cad902920d2d0e448b4a307b199d8fd
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,66 @@
using UnityEditor.PackageManager;
using UnityEditor;
using AssetPostprocessor = Unity.PlasticSCM.Editor.AssetUtils.Processor.AssetPostprocessor;
using Unity.PlasticSCM.Editor.UI;
namespace Unity.PlasticSCM.Editor.AssetUtils
{
internal static class RefreshAsset
{
internal static void BeforeLongAssetOperation()
{
AssetDatabase.DisallowAutoRefresh();
}
internal static void AfterLongAssetOperation()
{
AssetDatabase.AllowAutoRefresh();
UnityAssetDatabaseAndPackageManagerAsync();
}
internal static void UnityAssetDatabase()
{
RefreshUnityAssetDatabase();
}
internal static void UnityAssetDatabaseAndPackageManagerAsync()
{
// Client.Resolve() will resolve any pending packages added or removed from the project
// VCS-1004718 - This is important so the domain gets reloaded first if needed
Client.Resolve();
mCooldownRefreshAssetsAction.Ping();
}
internal static void VersionControlCache()
{
ClearVersionControlCaches();
ProjectWindow.Repaint();
RepaintInspector.All();
}
static void ClearVersionControlCaches()
{
UnityEditor.VersionControl.Provider.ClearCache();
if (PlasticPlugin.AssetStatusCache != null)
PlasticPlugin.AssetStatusCache.Clear();
}
static void RefreshUnityAssetDatabase()
{
AssetDatabase.Refresh(ImportAssetOptions.Default);
ClearVersionControlCaches();
AssetPostprocessor.SetIsRepaintNeededAfterAssetDatabaseRefresh();
}
static CooldownWindowDelayer mCooldownRefreshAssetsAction = new CooldownWindowDelayer(
RefreshUnityAssetDatabase,
UnityConstants.REFRESH_ASSET_DATABASE_DELAYED_INTERVAL);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7495e44f1cb132745a310485807e68f6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,17 @@
using UnityEditor;
using UnityEngine;
namespace Unity.PlasticSCM.Editor.AssetUtils
{
internal static class RepaintInspector
{
internal static void All()
{
UnityEditor.Editor[] editors =
Resources.FindObjectsOfTypeAll<UnityEditor.Editor>();
foreach (UnityEditor.Editor editor in editors)
editor.Repaint();
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9203e3f44c0ecfd42953709384a56c4d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,159 @@
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 ForChangesWithConfirmation(
List<ChangeInfo> changes,
WorkspaceOperationsMonitor workspaceOperationsMonitor,
out bool isCancelled)
{
ForPaths(
GetPaths(changes), true,
workspaceOperationsMonitor,
out isCancelled);
}
internal static void ForPathsWithConfirmation(
List<string> paths,
WorkspaceOperationsMonitor workspaceOperationsMonitor,
out bool isCancelled)
{
ForPaths(
paths, true,
workspaceOperationsMonitor,
out isCancelled);
}
internal static void ForChangesWithoutConfirmation(
List<ChangeInfo> changes,
WorkspaceOperationsMonitor workspaceOperationsMonitor)
{
bool isCancelled;
ForPaths(
GetPaths(changes), false,
workspaceOperationsMonitor,
out isCancelled);
}
internal static void ForPathsWithoutConfirmation(
List<string> paths,
WorkspaceOperationsMonitor workspaceOperationsMonitor)
{
bool isCancelled;
ForPaths(
paths, false,
workspaceOperationsMonitor,
out isCancelled);
}
static void ForPaths(
List<string> paths,
bool askForUserConfirmation,
WorkspaceOperationsMonitor workspaceOperationsMonitor,
out bool isCancelled)
{
workspaceOperationsMonitor.Disable();
try
{
SaveDirtyScenes(
paths,
askForUserConfirmation,
out isCancelled);
if (isCancelled)
return;
AssetDatabase.SaveAssets();
}
finally
{
workspaceOperationsMonitor.Enable();
}
}
static void SaveDirtyScenes(
List<string> paths,
bool askForUserConfirmation,
out bool isCancelled)
{
isCancelled = false;
List<Scene> scenesToSave = new List<Scene>();
foreach (Scene dirtyScene in GetDirtyScenes())
{
if (Contains(paths, dirtyScene))
scenesToSave.Add(dirtyScene);
}
if (scenesToSave.Count == 0)
return;
if (askForUserConfirmation)
{
isCancelled = !EditorSceneManager.
SaveModifiedScenesIfUserWantsTo(
scenesToSave.ToArray());
return;
}
EditorSceneManager.SaveScenes(
scenesToSave.ToArray());
}
static List<Scene> GetDirtyScenes()
{
List<Scene> dirtyScenes = new List<Scene>();
for (int i = 0; i < SceneManager.sceneCount; i++)
{
Scene scene = SceneManager.GetSceneAt(i);
if (!scene.isDirty)
continue;
dirtyScenes.Add(scene);
}
return dirtyScenes;
}
static bool Contains(
List<string> paths,
Scene scene)
{
if (string.IsNullOrEmpty(scene.path))
return false;
foreach (string path in paths)
{
if (PathHelper.IsSamePath(
path,
Path.GetFullPath(scene.path)))
return true;
}
return false;
}
static List<string> GetPaths(
List<ChangeInfo> changeInfos)
{
List<string> result = new List<string>();
foreach (ChangeInfo change in changeInfos)
result.Add(change.GetFullPath());
return result;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 802adf99bdbb1a3439a0a09ae5664192
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: