/// <summary> /// コルーチンの実行。コルーチンが既に終了していたらfalseを返す。 /// </summary> /// <param name="routineList">Routine list.</param> /// <param name="coroutine">Coroutine.</param> private static bool ProcessCoroutine(MyLib.Coroutine coroutine) { // 一回だけ実行 bool executed = coroutine.routine.MoveNext(); if (executed) { object current = coroutine.routine.Current; // current は yield return の戻り値である。 if (current is MyLib.Coroutine) { MyLib.Coroutine nested = (MyLib.Coroutine)current; if (nested.isChained) { UnityEngine.Debug.Log("[エラー] 1つのコルーチンで2つ以上のコルーチンを待機させる事はできません。"); } else { // nestedが登録されているLinkedListからnestedを削除。 nested.node.List.Remove(nested.node); // coroutineのリストに改めてnestedを登録。 nested.node = coroutine.node.List.AddLast(nested); // nestedはコルーチンチェーンに組み込まれたので、フラグを立てる。 nested.isChained = true; } } } return(executed); }
//ゲームエンジンにイテレーターを登録致します。 //WARNING:このメソッドの実行中に StartCoroutine() が呼ばれると再入するので注意。 public static MyLib.Coroutine AddRoutine (MyLib.MonoBehaviour behaviour, string method_name, IEnumerator routine) { MyLib.BehaviourData b_data; //スクリプトと同じ名前のキーから、値を取得する if (_behavior_dict.TryGetValue(behaviour, out b_data)) { //コルーチンを生成、初期化 var coroutine = new MyLib.Coroutine(method_name, routine); //コルーチンを登録 var coroutine_list = new LinkedList <MyLib.Coroutine> (); coroutine._node = coroutine_list.AddLast(coroutine); b_data._routine_list.AddLast(coroutine_list); // コルーチンの初回実行を行う。 ProcessCoroutine(coroutine); return(coroutine); } else { UnityEngine.Debug.Log("登録が行われませんでした。Null値を返します"); return(null); } }
public void Update() { // すべてのMonoBehaviourを実行 foreach (MyLib.BehaviourData bdata in behaviourDict.Values) { if (!bdata.mainloopBegan) { bdata.behaviour.Start(); bdata.mainloopBegan = true; } bdata.behaviour.Update(); } foreach (MyLib.BehaviourData bdata in behaviourDict.Values) { LinkedListNode <MyLib.Coroutine> node = bdata.routineList.First; while (node != null) { MyLib.Coroutine coroutine = node.Value; if (!coroutine.routine.MoveNext()) { var currentNode = node; node = node.Next; bdata.routineList.Remove(currentNode); } else { node = node.Next; } } } }
public static MyLib.Coroutine AddRoutine(MyLib.MonoBehaviour behaviour, string methodName, IEnumerator routine) { MyLib.BehaviourData bdata; if (behaviourDict.TryGetValue(behaviour, out bdata)) { var coroutine = new MyLib.Coroutine(methodName, routine); // ひとまず1回実行 routine.MoveNext(); bdata.routineList.AddLast(coroutine); return(coroutine); } else { // ここに来ることはない return(null); } }
/// <summary> /// コルーチンの実行。コルーチンが既に終了していたらfalseを返す。 /// </summary> /// <param name="routineList">Routine list.</param> /// <param name="coroutine">Coroutine.</param> private static bool ProcessCoroutine(MyLib.Coroutine coroutine) { currentRoutine.Push(coroutine); bool executed = coroutine.routine.MoveNext(); // 一回だけ実行 if (executed) { object current = coroutine.routine.Current; // ★TODO: とりあえずcurrentがCoroutineだった場合のみ考慮 // 将来的にはYieldInstructionにも対応する必要あり。 // current は yield return の戻り値である。 if (current is MyLib.Coroutine) { var next = (MyLib.Coroutine)current; // next をbeforeの後ろにくっつける。 // ただし、next が既に別のコルーチンチェーンに組み込まれていた場合、 // ログを出すだけで何もしない。 if (next.isChained) { UnityEngine.Debug.Log("[エラー] 1つのコルーチンで2つ以上のコルーチンを待機させる事はできません。"); } else { // nextが登録されているLinkedListからnextを削除。 next.node.List.Remove(next.node); // beforeのリストに改めてnextを登録。 next.node = coroutine.node.List.AddLast(next); // nextはコルーチンチェーンに組み込まれたので、フラグを立てる。 next.isChained = true; } } } currentRoutine.Pop(); return(executed); }
/// <summary> /// このメソッドの実行中に StartCoroutine() が呼ばれると再入するので注意。 /// </summary> /// <returns>The routine.</returns> /// <param name="behaviour">Behaviour.</param> /// <param name="methodName">Method name.</param> /// <param name="routine">Routine.</param> public static MyLib.Coroutine AddRoutine(MyLib.MonoBehaviour behaviour, string methodName, IEnumerator routine) { MyLib.BehaviourData bdata; if (behaviourDict.TryGetValue(behaviour, out bdata)) { var coroutine = new MyLib.Coroutine(methodName, routine); // 何はともあれまずコルーチンを登録 var list = new LinkedList <MyLib.Coroutine>(); coroutine.node = list.AddLast(coroutine); bdata.routineList.AddLast(list); // コルーチンの初回実行を行う。 ProcessCoroutine(coroutine); return(coroutine); } else { // ここに来ることはない return(null); } }
private void ProcessChainedCoroutine(LinkedList <MyLib.Coroutine> chain) { // chainの末尾を実行。 // 実行完了していたら、chainから削除。 LinkedListNode <MyLib.Coroutine> node = chain.Last; if (node != null) { MyLib.Coroutine coroutine = node.Value; if (ProcessCoroutine(coroutine)) { node = node.Next; } else { // 終わったコルーチンはリストから除外 LinkedListNode <MyLib.Coroutine> toRemove = node; node = node.Next; chain.Remove(toRemove); } } }
/// <summary> /// このメソッドの実行中に StartCoroutine() が呼ばれると再入するので注意。 /// </summary> /// <returns>The routine.</returns> /// <param name="behaviour">Behaviour.</param> /// <param name="methodName">Method name.</param> /// <param name="routine">Routine.</param> public static MyLib.Coroutine AddRoutine(MyLib.MonoBehaviour behaviour, string methodName, IEnumerator routine) { MyLib.BehaviourData bdata; if (behaviourDict.TryGetValue(behaviour, out bdata)) { var coroutine = new MyLib.Coroutine(methodName, routine); // 何はともあれまずコルーチンを登録 var list = new LinkedList<MyLib.Coroutine>(); coroutine.node = list.AddLast(coroutine); bdata.routineList.AddLast(list); // コルーチンの初回実行を行う。 ProcessCoroutine(coroutine); return coroutine; } else { // ここに来ることはない return null; } }