Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@marijnz
Created March 12, 2019 21:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save marijnz/05fc3ba14d1edd9c9bd48b44465c319c to your computer and use it in GitHub Desktop.
Save marijnz/05fc3ba14d1edd9c9bd48b44465c319c to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using DG.Tweening;
using UnityEditor;
using UnityEngine;
using Object = UnityEngine.Object;
public class Void
{
public static Void Default = new Void();
}
public class Wait : Controller
{
struct ConditionTask
{
public Func<bool> condition;
public TaskCompletionSource<Void> taskSource;
public Object obj;
public bool hasObj;
}
static Wait _instance;
public static Wait instance
{
get
{
if(_instance == null)
{
_instance = Injector.Get<Wait>();
#if UNITY_EDITOR
EditorApplication.update += _instance.OnEditorUpdate;
#endif
}
return _instance;
}
}
List<ConditionTask> conditionTasks = new List<ConditionTask>();
public Task ForSeconds(float seconds, Object obj = null)
{
var time = Time.realtimeSinceStartup + seconds;
return Until(() => Time.realtimeSinceStartup >= time, obj);
}
public Task ForTween(Tweener tween, Object obj = null)
{
return Until(() => !tween.IsPlaying(), obj);
}
public Task ForFrame(Object obj = null)
{
var nextFrame = Time.frameCount + 1;
return Until(() => Time.frameCount >= nextFrame, obj);
}
public Task ForEndOfFrame(Object obj = null)
{
return Until(() => true, obj);
}
public Task Until(Func<bool> condition, Object obj = null)
{
var taskSource = new TaskCompletionSource<Void>();
var conditionTask = new ConditionTask
{
condition = condition,
taskSource = taskSource,
obj = obj,
hasObj = obj != null
};
conditionTasks.Add(conditionTask);
return taskSource.Task;
}
public void Clear()
{
conditionTasks.Clear();
}
#if UNITY_EDITOR
public void OnEditorUpdate()
{
if(IsInEditor())
{
OnUpdate();
}
}
#endif
public void OnUpdate()
{
var conditionTaskCount = conditionTasks.Count;
for (var i = conditionTaskCount - 1; i >= 0; i--)
if ((!conditionTasks[i].hasObj || conditionTasks[i].obj != null) && conditionTasks[i].condition())
{
conditionTasks[i].taskSource.SetResult(Void.Default);
conditionTasks.RemoveAt(i);
#if UNITY_EDITOR
if(IsInEditor())
{
SceneView.RepaintAll();
}
#endif
}
}
#if UNITY_EDITOR
static bool IsInEditor()
{
return !EditorApplication.isPlaying && !EditorApplication.isPaused;
}
#endif
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment