Repository URL to install this package:
Version:
1.3.1 ▾
|
using System;
using System.Threading;
using System.Threading.Tasks;
using UnityEditor;
using CallbackFunction = UnityEditor.EditorApplication.CallbackFunction;
// ReSharper disable AccessToModifiedClosure
namespace Fluctio.FluctioSim.EditorUtils.EditorGeneral
{
public static class EditorUpdateEvents
{
/**
* Uses <see cref="EditorApplication.update"/>, but allows to unsubscribe from inside the handler
*/
public static event Action<Action> UpdateWithUnsubscribe
{
add
{
CallbackFunction handler = null;
Action unsubscribe = () => EditorApplication.update -= handler;
handler = () =>
{
value(unsubscribe);
};
EditorApplication.update += handler;
}
remove => ThrowRemoveException(nameof(UpdateWithUnsubscribe), value);
}
/**
* Uses <see cref="EditorApplication.update"/>, stops execution if function returns true
*/
public static event Func<bool> UpdateUntil
{
add => UpdateWithUnsubscribe += (unsubscribe) =>
{
var isFinished = value();
if (isFinished)
{
unsubscribe();
}
};
remove => ThrowRemoveException(nameof(UpdateWhile), value);
}
/**
* Uses <see cref="EditorApplication.update"/>, stops execution if function returns false
*/
public static event Func<bool> UpdateWhile
{
add => UpdateUntil += () => !value();
remove => ThrowRemoveException(nameof(UpdateWhile), value);
}
/**
* Uses <see cref="EditorApplication.update"/>, but unsubscribes immediately after one execution.
* Works almost like <see cref="EditorApplication.delayCall"/>, but <see cref="EditorApplication.delayCall"/>
* may cause long delays if Unity Editor is in background, and this will execute on the earlist tick possible.
*/
public static event Action UpdateOnce
{
add => UpdateWithUnsubscribe += (unsubscribe) =>
{
value();
unsubscribe();
};
remove => ThrowRemoveException(nameof(UpdateOnce), value);
}
/**
* Ensures code is executed on main thread. If we are already on main thread, executes immediately.
* If we are on another thread, uses <see cref="UpdateOnce"/>.
*/
public static event Action MainThread
{
add
{
if (Thread.CurrentThread == EditorUtil.MainThread)
{
value();
}
else
{
UpdateOnce += value;
}
}
remove => ThrowRemoveException(nameof(MainThread), value);
}
private static void ThrowRemoveException(string eventName, object _)
{
throw new NotSupportedException($"Removing from {eventName} event is not supported (yet?)");
}
public static async Task WaitNextUpdate()
{
var completionSource = new TaskCompletionSource<object>();
UpdateOnce += () => completionSource.SetResult(null);
await completionSource.Task;
}
public static async Task WaitDelayCall()
{
var completionSource = new TaskCompletionSource<object>();
EditorApplication.delayCall += () => completionSource.SetResult(null);
await completionSource.Task;
}
}
}