public IEnumerator RunCoroutine(NovelCommand.CommonVariable variable) { if (variable == null) { yield break; } if (this.commonData == null) { yield break; } this.commonVariable = variable; while (commonVariable.currentIndex < novelContentData.contentData.Count) { this.commonData.contentData = novelContentData.contentData[commonVariable.currentIndex]; // Try to create specific novel command actions Type commandType; if (dicNovelCommandType.TryGetValue(commonData.contentData.command, out commandType)) { command = Activator.CreateInstance(commandType) as NovelCommand.NovelCommandInterface; var coroutine = command.Do(commonData, commonVariable); yield return(coroutine); } commonVariable.currentIndex++; } yield break; }
/// <summary> /// セットアップコルーチン /// Include, Import, Groupコマンドの必要情報を集めます /// </summary> public IEnumerator SetupCoroutine(NovelCommand.SharedData data) { if (data == null) { yield break; } sharedData = data; sharedData.meta = new NovelMetaData(); sharedData.meta.groupDic = new Dictionary <string, NovelMetaData.GroupData>(); // セットアップ用に専用の変数を用意 // indexはRunCoroutine時とは別物である為(開始位置に関わらずSetupは全部見る) var variable = new NovelCommand.SharedVariable() { values = new Dictionary <string, string>(), handles = new Dictionary <string, UnityEngine.GameObject>(), index = 0, }; // セットアップが必要なコマンド var setupIDs = new int[] { (int)NovelCommandType.Include, (int)NovelCommandType.Import, (int)NovelCommandType.Group, }; while (variable.index < novelData.NovelInfoList.Count) { // 次に処理するコマンドデータ // 各コマンドはここから引数を取得します sharedData.model_ = novelData.NovelInfoList[variable.index]; // セットアップが必要なコマンドのみ実行 if (sharedData.model_.id.IsAny(setupIDs)) { // コマンドデータのIDから型を取得 Type commandType; if (commandTypeDic.TryGetValue(sharedData.model_.id, out commandType)) { // 型からインスタンスを生成 // このインスタンスはUndoを簡易的に行う為のものです command = Activator.CreateInstance(commandType) as NovelCommand.NovelCommandInterface; // 必ず1フレーム消費するので、これだとシビアなタイミングがまずい //yield return command.Do(sharedData, sharedVariable); // 同フレームで処理できるように自分でコルーチンを回す var coroutine = command.Do(sharedData, variable); while (coroutine.MoveNext()) { if (coroutine.Current != null) { // 何かしらが返ってきたら同フレームを保証する必要はなさそう var nestCoroutine = coroutine.Current as IEnumerator; if (nestCoroutine != null) { yield return(nestCoroutine); } } yield return(null); } } } variable.index++; } yield break; }
/// <summary> /// 実行コルーチン /// </summary> public IEnumerator RunCoroutine(NovelCommand.SharedVariable variable, int endIndex) { if (variable == null) { yield break; } if (sharedData == null) { yield break; } sharedVariable = variable; // handlesが存在する場合は引き継いでいる想定 // (最初には存在しなかった余計なオブジェクトも取得してしまうので処理しない) if (sharedVariable.handles.Count() <= 0) { // Scene上のGameObjectをハンドルに登録 foreach (var pair in sharedData.view.Canvases.GetComponentsInChildren <UnityEngine.Transform>(true)) { sharedVariable.handles[pair.name] = pair.gameObject; } } // 履歴登録が不要なID var noHistoryID = new int[] { (int)NovelCommandType.Import, (int)NovelCommandType.GroupRun, }; while (sharedVariable.index < novelData.NovelInfoList.Count && sharedVariable.index <= endIndex) { // 次に処理するコマンドデータ // 各コマンドはここから引数を取得します sharedData.model_ = novelData.NovelInfoList[sharedVariable.index]; // コマンドデータのIDから型を取得 Type commandType; if (commandTypeDic.TryGetValue(sharedData.model_.id, out commandType)) { // 型からインスタンスを生成 // このインスタンスはUndoを簡易的に行う為のものです command = Activator.CreateInstance(commandType) as NovelCommand.NovelCommandInterface; // 履歴保存 if (!sharedData.model_.id.IsAny(noHistoryID)) { sharedData.system_.history.Add( sharedData, sharedVariable, command); } // 必ず1フレーム消費するので、これだとシビアなタイミングがまずい //yield return command.Do(sharedData, sharedVariable); // 同フレームで処理できるように自分でコルーチンを回す var coroutine = command.Do(sharedData, sharedVariable); while (coroutine.MoveNext()) { if (coroutine.Current != null) { // 何かしらが返ってきたら同フレームを保証する必要はなさそう var nestCoroutine = coroutine.Current as IEnumerator; if (nestCoroutine != null) { yield return(nestCoroutine); } } yield return(null); } } sharedVariable.index++; } yield break; }