xingweizhu
4 年前
当前提交
50ef2073
共有 10 个文件被更改,包括 623 次插入 和 116 次删除
-
8com.unity.uiwidgets/Editor/UIWidgetsPanelEditor.cs
-
182com.unity.uiwidgets/Runtime/engine2/UIWidgetsEditorPanel.cs
-
20com.unity.uiwidgets/Runtime/engine2/UIWidgetsPanel.cs
-
6com.unity.uiwidgets/Runtime/engine2/UIWidgetsPanelWrapper.cs
-
1com.unity.uiwidgets/Runtime/ui2/window.cs
-
3Samples/UIWidgetsSamples_2019_4/Assets/EditorWindowSample.meta
-
439com.unity.uiwidgets/Runtime/engine2/EditorCoroutines.cs
-
77Samples/UIWidgetsSamples_2019_4/Assets/EditorWindowSample/CountDemo.cs
-
3Samples/UIWidgetsSamples_2019_4/Assets/EditorWindowSample/CountDemo.cs.meta
|
|||
fileFormatVersion: 2 |
|||
guid: 67e95d5f76f549d4ad7bfdeda34a9e75 |
|||
timeCreated: 1614132309 |
|
|||
using UnityEngine; |
|||
using System.Collections; |
|||
using UnityEditor; |
|||
using System.Collections.Generic; |
|||
using System; |
|||
using System.Reflection; |
|||
|
|||
namespace Unity.UIWidgets.editor2 { |
|||
public class EditorCoroutines |
|||
{ |
|||
public class EditorCoroutine |
|||
{ |
|||
public ICoroutineYield currentYield = new YieldDefault(); |
|||
public IEnumerator routine; |
|||
public string routineUniqueHash; |
|||
public string ownerUniqueHash; |
|||
public string MethodName = ""; |
|||
|
|||
public int ownerHash; |
|||
public string ownerType; |
|||
|
|||
public bool finished = false; |
|||
|
|||
public EditorCoroutine(IEnumerator routine, int ownerHash, string ownerType) |
|||
{ |
|||
this.routine = routine; |
|||
this.ownerHash = ownerHash; |
|||
this.ownerType = ownerType; |
|||
ownerUniqueHash = ownerHash + "_" + ownerType; |
|||
|
|||
if (routine != null) |
|||
{ |
|||
string[] split = routine.ToString().Split('<', '>'); |
|||
if (split.Length == 3) |
|||
{ |
|||
MethodName = split[1]; |
|||
} |
|||
} |
|||
|
|||
routineUniqueHash = ownerHash + "_" + ownerType + "_" + MethodName; |
|||
} |
|||
|
|||
public EditorCoroutine(string methodName, int ownerHash, string ownerType) |
|||
{ |
|||
MethodName = methodName; |
|||
this.ownerHash = ownerHash; |
|||
this.ownerType = ownerType; |
|||
ownerUniqueHash = ownerHash + "_" + ownerType; |
|||
routineUniqueHash = ownerHash + "_" + ownerType + "_" + MethodName; |
|||
} |
|||
} |
|||
|
|||
public interface ICoroutineYield |
|||
{ |
|||
bool IsDone(float deltaTime); |
|||
} |
|||
|
|||
struct YieldDefault : ICoroutineYield |
|||
{ |
|||
public bool IsDone(float deltaTime) |
|||
{ |
|||
return true; |
|||
} |
|||
} |
|||
|
|||
struct YieldWaitForSeconds : ICoroutineYield |
|||
{ |
|||
public float timeLeft; |
|||
|
|||
public bool IsDone(float deltaTime) |
|||
{ |
|||
timeLeft -= deltaTime; |
|||
return timeLeft < 0; |
|||
} |
|||
} |
|||
|
|||
struct YieldCustomYieldInstruction : ICoroutineYield |
|||
{ |
|||
public CustomYieldInstruction customYield; |
|||
|
|||
public bool IsDone(float deltaTime) |
|||
{ |
|||
return !customYield.keepWaiting; |
|||
} |
|||
} |
|||
|
|||
struct YieldWWW : ICoroutineYield |
|||
{ |
|||
public WWW Www; |
|||
|
|||
public bool IsDone(float deltaTime) |
|||
{ |
|||
return Www.isDone; |
|||
} |
|||
} |
|||
|
|||
struct YieldAsync : ICoroutineYield |
|||
{ |
|||
public AsyncOperation asyncOperation; |
|||
|
|||
public bool IsDone(float deltaTime) |
|||
{ |
|||
return asyncOperation.isDone; |
|||
} |
|||
} |
|||
|
|||
struct YieldNestedCoroutine : ICoroutineYield |
|||
{ |
|||
public EditorCoroutine coroutine; |
|||
|
|||
public bool IsDone(float deltaTime) |
|||
{ |
|||
return coroutine.finished; |
|||
} |
|||
} |
|||
|
|||
static EditorCoroutines instance = null; |
|||
|
|||
Dictionary<string, List<EditorCoroutine>> coroutineDict = new Dictionary<string, List<EditorCoroutine>>(); |
|||
List<List<EditorCoroutine>> tempCoroutineList = new List<List<EditorCoroutine>>(); |
|||
|
|||
Dictionary<string, Dictionary<string, EditorCoroutine>> coroutineOwnerDict = |
|||
new Dictionary<string, Dictionary<string, EditorCoroutine>>(); |
|||
|
|||
DateTime previousTimeSinceStartup; |
|||
|
|||
/// <summary>Starts a coroutine.</summary>
|
|||
/// <param name="routine">The coroutine to start.</param>
|
|||
/// <param name="thisReference">Reference to the instance of the class containing the method.</param>
|
|||
public static EditorCoroutine StartCoroutine(IEnumerator routine, object thisReference) |
|||
{ |
|||
CreateInstanceIfNeeded(); |
|||
return instance.GoStartCoroutine(routine, thisReference); |
|||
} |
|||
|
|||
/// <summary>Starts a coroutine.</summary>
|
|||
/// <param name="methodName">The name of the coroutine method to start.</param>
|
|||
/// <param name="thisReference">Reference to the instance of the class containing the method.</param>
|
|||
public static EditorCoroutine StartCoroutine(string methodName, object thisReference) |
|||
{ |
|||
return StartCoroutine(methodName, null, thisReference); |
|||
} |
|||
|
|||
/// <summary>Starts a coroutine.</summary>
|
|||
/// <param name="methodName">The name of the coroutine method to start.</param>
|
|||
/// <param name="value">The parameter to pass to the coroutine.</param>
|
|||
/// <param name="thisReference">Reference to the instance of the class containing the method.</param>
|
|||
public static EditorCoroutine StartCoroutine(string methodName, object value, object thisReference) |
|||
{ |
|||
MethodInfo methodInfo = thisReference.GetType() |
|||
.GetMethod(methodName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); |
|||
if (methodInfo == null) |
|||
{ |
|||
Debug.LogError("Coroutine '" + methodName + "' couldn't be started, the method doesn't exist!"); |
|||
} |
|||
object returnValue; |
|||
|
|||
if (value == null) |
|||
{ |
|||
returnValue = methodInfo.Invoke(thisReference, null); |
|||
} |
|||
else |
|||
{ |
|||
returnValue = methodInfo.Invoke(thisReference, new object[] {value}); |
|||
} |
|||
|
|||
if (returnValue is IEnumerator) |
|||
{ |
|||
CreateInstanceIfNeeded(); |
|||
return instance.GoStartCoroutine((IEnumerator) returnValue, thisReference); |
|||
} |
|||
else |
|||
{ |
|||
Debug.LogError("Coroutine '" + methodName + "' couldn't be started, the method doesn't return an IEnumerator!"); |
|||
} |
|||
|
|||
return null; |
|||
} |
|||
|
|||
/// <summary>Stops all coroutines being the routine running on the passed instance.</summary>
|
|||
/// <param name="routine"> The coroutine to stop.</param>
|
|||
/// <param name="thisReference">Reference to the instance of the class containing the method.</param>
|
|||
public static void StopCoroutine(IEnumerator routine, object thisReference) |
|||
{ |
|||
CreateInstanceIfNeeded(); |
|||
instance.GoStopCoroutine(routine, thisReference); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Stops all coroutines named methodName running on the passed instance.</summary>
|
|||
/// <param name="methodName"> The name of the coroutine method to stop.</param>
|
|||
/// <param name="thisReference">Reference to the instance of the class containing the method.</param>
|
|||
public static void StopCoroutine(string methodName, object thisReference) |
|||
{ |
|||
CreateInstanceIfNeeded(); |
|||
instance.GoStopCoroutine(methodName, thisReference); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Stops all coroutines running on the passed instance.</summary>
|
|||
/// <param name="thisReference">Reference to the instance of the class containing the method.</param>
|
|||
public static void StopAllCoroutines(object thisReference) |
|||
{ |
|||
CreateInstanceIfNeeded(); |
|||
instance.GoStopAllCoroutines(thisReference); |
|||
} |
|||
|
|||
static void CreateInstanceIfNeeded() |
|||
{ |
|||
if (instance == null) |
|||
{ |
|||
instance = new EditorCoroutines(); |
|||
instance.Initialize(); |
|||
} |
|||
} |
|||
|
|||
void Initialize() |
|||
{ |
|||
previousTimeSinceStartup = DateTime.Now; |
|||
EditorApplication.update += OnUpdate; |
|||
} |
|||
|
|||
void GoStopCoroutine(IEnumerator routine, object thisReference) |
|||
{ |
|||
GoStopActualRoutine(CreateCoroutine(routine, thisReference)); |
|||
} |
|||
|
|||
void GoStopCoroutine(string methodName, object thisReference) |
|||
{ |
|||
GoStopActualRoutine(CreateCoroutineFromString(methodName, thisReference)); |
|||
} |
|||
|
|||
void GoStopActualRoutine(EditorCoroutine routine) |
|||
{ |
|||
if (coroutineDict.ContainsKey(routine.routineUniqueHash)) |
|||
{ |
|||
coroutineOwnerDict[routine.ownerUniqueHash].Remove(routine.routineUniqueHash); |
|||
coroutineDict.Remove(routine.routineUniqueHash); |
|||
} |
|||
} |
|||
|
|||
void GoStopAllCoroutines(object thisReference) |
|||
{ |
|||
EditorCoroutine coroutine = CreateCoroutine(null, thisReference); |
|||
if (coroutineOwnerDict.ContainsKey(coroutine.ownerUniqueHash)) |
|||
{ |
|||
foreach (var couple in coroutineOwnerDict[coroutine.ownerUniqueHash]) |
|||
{ |
|||
coroutineDict.Remove(couple.Value.routineUniqueHash); |
|||
} |
|||
coroutineOwnerDict.Remove(coroutine.ownerUniqueHash); |
|||
} |
|||
} |
|||
|
|||
EditorCoroutine GoStartCoroutine(IEnumerator routine, object thisReference) |
|||
{ |
|||
if (routine == null) |
|||
{ |
|||
Debug.LogException(new Exception("IEnumerator is null!"), null); |
|||
} |
|||
EditorCoroutine coroutine = CreateCoroutine(routine, thisReference); |
|||
GoStartCoroutine(coroutine); |
|||
return coroutine; |
|||
} |
|||
|
|||
void GoStartCoroutine(EditorCoroutine coroutine) |
|||
{ |
|||
if (!coroutineDict.ContainsKey(coroutine.routineUniqueHash)) |
|||
{ |
|||
List<EditorCoroutine> newCoroutineList = new List<EditorCoroutine>(); |
|||
coroutineDict.Add(coroutine.routineUniqueHash, newCoroutineList); |
|||
} |
|||
coroutineDict[coroutine.routineUniqueHash].Add(coroutine); |
|||
|
|||
if (!coroutineOwnerDict.ContainsKey(coroutine.ownerUniqueHash)) |
|||
{ |
|||
Dictionary<string, EditorCoroutine> newCoroutineDict = new Dictionary<string, EditorCoroutine>(); |
|||
coroutineOwnerDict.Add(coroutine.ownerUniqueHash, newCoroutineDict); |
|||
} |
|||
|
|||
// If the method from the same owner has been stored before, it doesn't have to be stored anymore,
|
|||
// One reference is enough in order for "StopAllCoroutines" to work
|
|||
if (!coroutineOwnerDict[coroutine.ownerUniqueHash].ContainsKey(coroutine.routineUniqueHash)) |
|||
{ |
|||
coroutineOwnerDict[coroutine.ownerUniqueHash].Add(coroutine.routineUniqueHash, coroutine); |
|||
} |
|||
|
|||
MoveNext(coroutine); |
|||
} |
|||
|
|||
EditorCoroutine CreateCoroutine(IEnumerator routine, object thisReference) |
|||
{ |
|||
return new EditorCoroutine(routine, thisReference.GetHashCode(), thisReference.GetType().ToString()); |
|||
} |
|||
|
|||
EditorCoroutine CreateCoroutineFromString(string methodName, object thisReference) |
|||
{ |
|||
return new EditorCoroutine(methodName, thisReference.GetHashCode(), thisReference.GetType().ToString()); |
|||
} |
|||
|
|||
void OnUpdate() |
|||
{ |
|||
float deltaTime = (float) (DateTime.Now.Subtract(previousTimeSinceStartup).TotalMilliseconds / 1000.0f); |
|||
|
|||
previousTimeSinceStartup = DateTime.Now; |
|||
if (coroutineDict.Count == 0) |
|||
{ |
|||
return; |
|||
} |
|||
|
|||
tempCoroutineList.Clear(); |
|||
foreach (var pair in coroutineDict) |
|||
tempCoroutineList.Add(pair.Value); |
|||
|
|||
for (var i = tempCoroutineList.Count - 1; i >= 0; i--) |
|||
{ |
|||
List<EditorCoroutine> coroutines = tempCoroutineList[i]; |
|||
|
|||
for (int j = coroutines.Count - 1; j >= 0; j--) |
|||
{ |
|||
EditorCoroutine coroutine = coroutines[j]; |
|||
|
|||
if (!coroutine.currentYield.IsDone(deltaTime)) |
|||
{ |
|||
continue; |
|||
} |
|||
|
|||
if (!MoveNext(coroutine)) |
|||
{ |
|||
coroutines.RemoveAt(j); |
|||
coroutine.currentYield = null; |
|||
coroutine.finished = true; |
|||
} |
|||
|
|||
if (coroutines.Count == 0) |
|||
{ |
|||
coroutineDict.Remove(coroutine.routineUniqueHash); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
static bool MoveNext(EditorCoroutine coroutine) |
|||
{ |
|||
if (coroutine.routine.MoveNext()) |
|||
{ |
|||
return Process(coroutine); |
|||
} |
|||
|
|||
return false; |
|||
} |
|||
|
|||
// returns false if no next, returns true if OK
|
|||
static bool Process(EditorCoroutine coroutine) |
|||
{ |
|||
object current = coroutine.routine.Current; |
|||
if (current == null) |
|||
{ |
|||
coroutine.currentYield = new YieldDefault(); |
|||
} |
|||
else if (current is WaitForSeconds) |
|||
{ |
|||
float seconds = float.Parse(GetInstanceField(typeof(WaitForSeconds), current, "m_Seconds").ToString()); |
|||
coroutine.currentYield = new YieldWaitForSeconds() {timeLeft = seconds}; |
|||
} |
|||
else if (current is CustomYieldInstruction) |
|||
{ |
|||
coroutine.currentYield = new YieldCustomYieldInstruction() |
|||
{ |
|||
customYield = current as CustomYieldInstruction |
|||
}; |
|||
} |
|||
else if (current is WWW) |
|||
{ |
|||
coroutine.currentYield = new YieldWWW {Www = (WWW) current}; |
|||
} |
|||
else if (current is WaitForFixedUpdate || current is WaitForEndOfFrame) |
|||
{ |
|||
coroutine.currentYield = new YieldDefault(); |
|||
} |
|||
else if (current is AsyncOperation) |
|||
{ |
|||
coroutine.currentYield = new YieldAsync {asyncOperation = (AsyncOperation) current}; |
|||
} |
|||
else if (current is EditorCoroutine) |
|||
{ |
|||
coroutine.currentYield = new YieldNestedCoroutine { coroutine= (EditorCoroutine) current}; |
|||
} |
|||
else |
|||
{ |
|||
Debug.LogException( |
|||
new Exception("<" + coroutine.MethodName + "> yielded an unknown or unsupported type! (" + current.GetType() + ")"), |
|||
null); |
|||
coroutine.currentYield = new YieldDefault(); |
|||
} |
|||
return true; |
|||
} |
|||
|
|||
static object GetInstanceField(Type type, object instance, string fieldName) |
|||
{ |
|||
BindingFlags bindFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static; |
|||
FieldInfo field = type.GetField(fieldName, bindFlags); |
|||
return field.GetValue(instance); |
|||
} |
|||
} |
|||
|
|||
public static class EditorCoroutineExtensions |
|||
{ |
|||
public static EditorCoroutines.EditorCoroutine StartCoroutine(this EditorWindow thisRef, IEnumerator coroutine) |
|||
{ |
|||
return EditorCoroutines.StartCoroutine(coroutine, thisRef); |
|||
} |
|||
|
|||
public static EditorCoroutines.EditorCoroutine StartCoroutine(this EditorWindow thisRef, string methodName) |
|||
{ |
|||
return EditorCoroutines.StartCoroutine(methodName, thisRef); |
|||
} |
|||
|
|||
public static EditorCoroutines.EditorCoroutine StartCoroutine(this EditorWindow thisRef, string methodName, object value) |
|||
{ |
|||
return EditorCoroutines.StartCoroutine(methodName, value, thisRef); |
|||
} |
|||
|
|||
public static void StopCoroutine(this EditorWindow thisRef, IEnumerator coroutine) |
|||
{ |
|||
EditorCoroutines.StopCoroutine(coroutine, thisRef); |
|||
} |
|||
|
|||
public static void StopCoroutine(this EditorWindow thisRef, string methodName) |
|||
{ |
|||
EditorCoroutines.StopCoroutine(methodName, thisRef); |
|||
} |
|||
|
|||
public static void StopAllCoroutines(this EditorWindow thisRef) |
|||
{ |
|||
EditorCoroutines.StopAllCoroutines(thisRef); |
|||
} |
|||
} |
|||
} |
|
|||
using System.Collections.Generic; |
|||
using Unity.UIWidgets.cupertino; |
|||
using Unity.UIWidgets.editor2; |
|||
using Unity.UIWidgets.engine2; |
|||
using Unity.UIWidgets.ui; |
|||
using Unity.UIWidgets.widgets; |
|||
using UnityEditor; |
|||
using UnityEngine.UI; |
|||
using Text = Unity.UIWidgets.widgets.Text; |
|||
using ui_ = Unity.UIWidgets.widgets.ui_; |
|||
using TextStyle = Unity.UIWidgets.painting.TextStyle; |
|||
|
|||
namespace UIWidgetsSample |
|||
{ |
|||
public class EditorWindowCountDemo : UIWidgetsEditorPanel |
|||
{ |
|||
[MenuItem("UIWidgets/CountDemo")] |
|||
public static void CountDemo() |
|||
{ |
|||
CreateWindow<EditorWindowCountDemo>(); |
|||
} |
|||
|
|||
protected override void main() |
|||
{ |
|||
ui_.runApp(new MyApp()); |
|||
} |
|||
|
|||
class MyApp : StatelessWidget |
|||
{ |
|||
public override Widget build(BuildContext context) |
|||
{ |
|||
return new CupertinoApp( |
|||
home: new EditorWindowCounterApp() |
|||
); |
|||
} |
|||
} |
|||
} |
|||
|
|||
internal class EditorWindowCounterApp : StatefulWidget |
|||
{ |
|||
public override State createState() |
|||
{ |
|||
return new EditorWindowCounterState(); |
|||
} |
|||
} |
|||
|
|||
internal class EditorWindowCounterState : State<CounterApp> |
|||
{ |
|||
private int count = 0; |
|||
|
|||
public override Widget build(BuildContext context) |
|||
{ |
|||
return new Container( |
|||
color: Color.fromARGB(255, 255, 0, 0), |
|||
child: new Column(children: new List<Widget>() |
|||
{ |
|||
new Text($"count: {count}", style: new TextStyle(color: Color.fromARGB(255, 0 ,0 ,255))), |
|||
new CupertinoButton( |
|||
onPressed: () => |
|||
{ |
|||
setState(() => |
|||
{ |
|||
count++; |
|||
}); |
|||
}, |
|||
child: new Container( |
|||
color: Color.fromARGB(255,0 , 255, 0), |
|||
width: 100, |
|||
height: 40 |
|||
) |
|||
), |
|||
} |
|||
) |
|||
); |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 5e098e276aca4edf89cd58abb8af51b0 |
|||
timeCreated: 1614132321 |
撰写
预览
正在加载...
取消
保存
Reference in new issue