using System;
using UnityEditor;
using UnityEditorInternal;
namespace Unity.PlasticSCM.Editor
{
internal static class Execute
{
// Executes action once when the editor is not updating or compiling.
// Use this for quick actions that need to wait for the current import/compile to finish.
internal static void WhenEditorIsReady(Action action)
{
if (PlasticApp.IsUnitTesting)
{
action();
return;
}
EditorApplication.update += RunOnceWhenEditorIsReady;
bool IsEditorBusy()
{
return EditorApplication.isUpdating ||
EditorApplication.isCompiling;
}
void RunOnceWhenEditorIsReady()
{
if (IsEditorBusy())
return;
EditorApplication.update -= RunOnceWhenEditorIsReady;
action();
}
}
// Executes action once the editor has been idle for a sustained period of time.
// Checks: isUpdating, isCompiling, Progress.running (background tasks),
// and isApplicationActive (editor must be in foreground, otherwise background tasks are deferred).
// Use this for operations that need all editor activity to settle first,
// such as workspace creation from the Hub where late file modifications
// could cause files to appear as "changed" in pending changes.
internal static void AfterEditorIsIdleForSeconds(double delaySeconds, Action action)
{
if (PlasticApp.IsUnitTesting)
{
action();
return;
}
double lastBusyTime = EditorApplication.timeSinceStartup;
EditorApplication.update += RunOnceAfterEditorIsIdle;
bool IsEditorInBackground()
{
return !InternalEditorUtility.isApplicationActive;
}
bool IsEditorBusy()
{
return EditorApplication.isUpdating ||
EditorApplication.isCompiling ||
Progress.running;
}
void RunOnceAfterEditorIsIdle()
{
double currentTime = EditorApplication.timeSinceStartup;
if (IsEditorInBackground() || IsEditorBusy())
{
lastBusyTime = currentTime;
return;
}
if (currentTime - lastBusyTime < delaySeconds)
return;
EditorApplication.update -= RunOnceAfterEditorIsIdle;
action();
}
}
}
}