public static void DemoEditorCoroutines()
 {
     // adds a menu item to test the coroutine system.
     if (!Application.isPlaying)
     {
         // lets fire off the demo coroutine with a UI so we can see what its doing. We could also run it without a UI by using EditorCoroutineRunner.StartCoroutine(...)
         EditorCoroutineRunner.StartCoroutineWithUI(DemoCoroutiune(), "Lotte's Coroutine Demo", true);
     }
 }
        static IEnumerator DemoCoroutiune()
        {
            // You can code editor coroutines exactly like you would a normal unity coroutine
            Debug.Log("Step: 0");
            yield return(null);

            // all the normal return types that work with regular Unity coroutines should work here! for example lets wait for a second
            Debug.Log("Step: 1");
            yield return(new WaitForSeconds(1));

            // We can also yeild any type that extends Unitys CustomYieldInstruction class. here we are going to use EditorStatusUpdate. this allows us to yield and update the
            // editor coroutine UI at the same time!
            yield return(new EditorStatusUpdate("coroutine is running", 0.2f));

            // We can also yield to nested coroutines
            Debug.Log("Step: 2");

            yield return(EditorCoroutineRunner.StartCoroutine(DemoTwo()));

            EditorCoroutineRunner
            .UpdateUIProgressBar(
                0.35f);      // we can use the UpdateUI helper methods to update the UI whenever, without yielding a EditorStatusUpdate
            yield return
                (DemoTwo()); // it shouldnt matter how we start the nested coroutine, the editor runner can hadle it

            // we can even yield a WWW object if we want to grab data from the internets!
            Debug.Log("Step: 3");

            // for example, lets as random.org to generate us a list of random numbers and shove it into the console
            var www = new WWW(
                "https://www.random.org/integers/?num=100&min=1&max=1000&col=1&base=10&col=5&format=plain&rnd=new");

            yield return(www);

            Debug.Log(www.text);

            EditorCoroutineRunner.UpdateUI("Half way!", 0.5f);
            yield return(new WaitForSeconds(1));

            // Finally lets do a long runnig task and split its updates over many frames to keep the editor responsive
            Debug.Log("Step: 4");
            var test = 1000;

            yield return(new WaitUntil(() =>
            {
                test--;
                EditorCoroutineRunner.UpdateUI("Crunching Numbers: " + test, 0.5f + (((1000 - test) / 1000f) * 0.5f));
                return (test <= 0);
            }));

            Debug.Log("Done!!");
        }
Beispiel #3
0
        private static IEnumerator downloadAll(List <GSPluginSettings.Sheet> sheets, string settingDir)
        {
            float progress = 0f;
            int   i        = 0;

            foreach (var ss in sheets)
            {
                EditorCoroutineRunner.UpdateUILabel("Downloading " + ss.targetPath);
                yield return(EditorCoroutineRunner.StartCoroutine(Download(ss, settingDir)));

                progress = (float)(++i) / sheets.Count;
                EditorCoroutineRunner.UpdateUIProgressBar(progress);
            }

            AssetDatabase.Refresh();
        }
        public static IEnumerator ExecuteImport(ConvertSetting s)
        {
            downloadSuccess = false;
            yield return(EditorCoroutineRunner.StartCoroutine(ExecuteDownload(s)));

            if (!downloadSuccess)
            {
                yield break;
            }

            CreateAssetsJob createAssetsJob = new CreateAssetsJob(s);

            // Generate Code if type script is not found.
            Type assetType;

            if (s.isEnum || !CsvConvert.TryGetTypeWithError(s.className, out assetType,
                                                            s.checkFullyQualifiedName, dialog: false))
            {
                GlobalCCSettings gSettings = CCLogic.GetGlobalSettings();
                GenerateOneCode(s, gSettings);

                if (!s.isEnum)
                {
                    EditorUtility.DisplayDialog(
                        "Code Generated",
                        "Please reimport for creating assets after compiling",
                        "ok"
                        );
                }
            }
            // Create Assets
            else
            {
                createAssetsJob.Execute();
            }

            // AfterImport 処理
            for (int i = 0; i < s.executeAfterImport.Count; i++)
            {
                var afterSettings = s.executeAfterImport[i];

                if (afterSettings != null)
                {
                    yield return(EditorCoroutineRunner.StartCoroutine(ExecuteImport(afterSettings)));
                }
            }
        }
        public static IEnumerator ExecuteDownload(ConvertSetting s)
        {
            GSPluginSettings.Sheet sheet = new GSPluginSettings.Sheet();
            sheet.sheetId = s.sheetID;
            sheet.gid     = s.gid;

            GlobalCCSettings gSettings = CCLogic.GetGlobalSettings();

            string csvPath = s.GetCsvPath(gSettings);

            if (string.IsNullOrWhiteSpace(csvPath))
            {
                Debug.LogError("unexpected downloadPath: " + csvPath);
                downloadSuccess = false;
                yield break;
            }

            string absolutePath = CCLogic.GetFilePathRelativesToAssets(s.GetDirectoryPath(), csvPath);

            // 先頭の Assets を削除する
            if (absolutePath.StartsWith("Assets" + Path.DirectorySeparatorChar))
            {
                sheet.targetPath = absolutePath.Substring(6);
            }
            else
            {
                Debug.LogError("unexpected downloadPath: " + absolutePath);
                downloadSuccess = false;
                yield break;
            }

            sheet.isCsv   = true;
            sheet.verbose = false;

            string title = "Google Spreadsheet Loader";

            yield return(EditorCoroutineRunner.StartCoroutineWithUI(GSEditorWindow.Download(sheet, s.GetDirectoryPath()), title, true));

            // 成功判定を行う.
            if (GSEditorWindow.previousDownloadSuccess)
            {
                downloadSuccess = true;
            }

            yield break;
        }
Beispiel #6
0
        /// <summary>
        /// 指定の sheetId, gid のシートを CsvData としてダウンロードする.
        ///
        /// Google Spreadsheet URL に2つのリクエストを送る。
        /// まず一つ目は sheetId に対する複数の worksheet を持つ URL へのリクエスト。
        /// 二つ目は その sheetId の中で特定の gid を持つ URL へのリクエスト。
        /// </summary>
        public IEnumerator LoadGS(string sheetId, string gid, string apiKey = "", bool useV4 = true)
        {
            isSuccess = false;

            if (useV4)
            {
                var coroutine = GSLoaderV4.LoadCsvData(sheetId, gid, apiKey);
                yield return(coroutine);

                loadedCsvData = GSLoaderV4.csvData;
                isSuccess     = loadedCsvData != null;
            }
            // V3 old api
            else
            {
                // Load spread sheet
                yield return(EditorCoroutineRunner.StartCoroutine(downloadWorksheets(sheetId)));

                if (_worksheets == null)
                {
                    Debug.LogError("Failed to download worksheets");
                    yield break;
                }

                // Load each worksheet
                foreach (GSWorksheet sheet in _worksheets)
                {
                    if (sheet.gid == gid)
                    {
                        yield return(EditorCoroutineRunner.StartCoroutine(LoadCsvData(sheet)));

                        yield break;
                    }
                }
            }
        }
Beispiel #7
0
        public static IEnumerator Download(GSPluginSettings.Sheet ss, string settingDir)
        {
            previousDownloadSuccess = false;
            string sheetId = ss.sheetId;
            string gid     = ss.gid;

            string label = "Downloading " + ss.targetPath;

            EditorCoroutineRunner.UpdateUILabel(label);

            var gsLoader       = new GSLoader();
            var globalSettings = CCLogic.GetGlobalSettings();

            string apiKey = globalSettings.apiKey;
            bool   useV4  = globalSettings.useV4;

            yield return(EditorCoroutineRunner.StartCoroutine(gsLoader.LoadGS(sheetId, gid, apiKey, useV4)));

            if (!gsLoader.isSuccess)
            {
                Debug.Log("Failed to load spreadsheet data.");
                yield break;
            }

            CsvData csvData = gsLoader.loadedCsvData;
            string  targetPathRelativeToAssets = ss.GetFilePathRelativesToAssets(settingDir);

            if (csvData != null)
            {
                if (ss.isCsv)
                {
                    string targetDir = Path.GetDirectoryName(targetPathRelativeToAssets);

                    if (!Directory.Exists(targetDir))
                    {
                        try
                        {
                            Directory.CreateDirectory(targetDir);
                            Debug.Log("指定のフォルダが存在しないため、作成しました: " + targetDir);
                        }
                        catch (Exception e)
                        {
                            Debug.LogError("指定のフォルダの作成に失敗: " + e.Message);
                        }
//                            Debug.LogError("指定のフォルダは存在しません: " + targetDir);
//                        return;
                    }

                    using (var s = new StreamWriter(targetPathRelativeToAssets)) {
                        s.Write(csvData.ToString());
                    }
                }
                else
                {
                    // AssetDatabase.CreateAsset(csvData, targetPathRelativeToAssets);
                    Debug.LogError("CsvData の書き出しには未対応になりました");
                }

                if (ss.verbose)
                {
                    Debug.Log("Write " + ss.targetPath);
                }

                previousDownloadSuccess = true;
                AssetDatabase.Refresh();
            }
            else
            {
                Debug.LogError("Fails for " + ss.ToString());
            }
        }
Beispiel #8
0
        public static void DownloadOne(GSPluginSettings.Sheet sheet, string settingPath)
        {
            string title = "Google Spreadsheet Loader";

            EditorCoroutineRunner.StartCoroutineWithUI(Download(sheet, settingPath), title, true);
        }
Beispiel #9
0
        private void DownloadAll(List <GSPluginSettings.Sheet> sheets, string settingDir)
        {
            string title = "Downloading All";

            EditorCoroutineRunner.StartCoroutineWithUI(downloadAll(sheets, settingDir), title, true);
        }
Beispiel #10
0
        private void OnGUI()
        {
            GUILayout.Space(6f);
            ConvertSetting[] settings = null;

            if (cachedAllSettings != null)
            {
                settings = cachedAllSettings;
            }

            // 検索ボックスを表示
            GUILayout.BeginHorizontal();
            searchTxt = SearchField(searchTxt);
            searchTxt = searchTxt.ToLower();
            GUILayout.EndHorizontal();

            if (settings != null)
            {
                scrollPosition = GUILayout.BeginScrollView(scrollPosition);

                for (int i = 0; i < settings.Length; i++)
                {
                    var s = settings[i];

                    // 設定が削除されている場合などに対応
                    if (s == null)
                    {
                        continue;
                    }

                    // 検索ワードチェック
                    if (!string.IsNullOrEmpty(searchTxt))
                    {
                        if (s.tableGenerate)
                        {
                            if (!searchTxt.IsSubsequence(s.tableAssetName.ToLower()))
                            {
                                continue;
                            }
                        }
                        else
                        {
                            if (!searchTxt.IsSubsequence(s.className.ToLower()))
                            {
                                continue;
                            }
                        }
                    }

                    GUILayout.BeginHorizontal("box");

#if ODIN_INSPECTOR
                    // ------------------------------
                    // 設定を複製ボタン.
                    // ------------------------------
                    if (GUILayout.Button("+", GUILayout.Width(20)))
                    {
                        var copied = s.Copy();

                        var window = CCSettingsEditWindow.OpenWindow();
                        window.SetNewSettings(copied, s.GetDirectoryPath());

                        GUIUtility.ExitGUI();
                    }

                    // ------------------------------
                    // 設定を編集ボタン.
                    // ------------------------------
                    var edit = EditorGUIUtility.Load("editicon.sml") as Texture2D;
                    if (GUILayout.Button(edit, GUILayout.Width(20)))
                    {
                        var window = CCSettingsEditWindow.OpenWindow();
                        window.SetSettings(s);
                        GUIUtility.ExitGUI();
                    }
#endif

                    // ------------------------------
                    // テーブル名 (enum の場合は enum名) を表示.
                    // クリックして、設定ファイルに飛べるようにする.
                    // ------------------------------
                    if (s.tableGenerate)
                    {
                        if (GUILayout.Button(s.tableAssetName, "Label"))
                        {
                            EditorGUIUtility.PingObject(s.GetInstanceID());
                            GUIUtility.ExitGUI();
                        }
                    }
                    else
                    {
                        if (GUILayout.Button(s.className, "Label"))
                        {
                            EditorGUIUtility.PingObject(s.GetInstanceID());
                            GUIUtility.ExitGUI();
                        }
                    }

                    // ------------------------------
                    // GS Plugin 使う場合のボタン.
                    //
                    // Import ボタン
                    // Open ボタン
                    // ------------------------------
                    if (s.useGSPlugin)
                    {
                        if (GUILayout.Button("Import", GUILayout.Width(110)))
                        {
                            EditorCoroutineRunner.StartCoroutine(ExecuteImport(s));
                            GUIUtility.ExitGUI();
                        }

                        // GS Plugin を使う場合は Open ボタンを用意する.
                        if (s.useGSPlugin)
                        {
                            if (GUILayout.Button("Open", GUILayout.Width(80)) && !isDownloading)
                            {
                                GSUtils.OpenURL(s.sheetID, s.gid);
                                GUIUtility.ExitGUI();
                            }
                        }


                        if (s.verboseBtn)
                        {
                            if (GUILayout.Button("DownLoad", GUILayout.Width(110)))
                            {
                                EditorCoroutineRunner.StartCoroutine(ExecuteDownload(s));
                                GUIUtility.ExitGUI();
                            }
                        }
                    }

                    // ------------------------------
                    // コード生成ボタン.
                    // v0.1.2 からは Import に置き換え.
                    // ------------------------------
                    if (s.verboseBtn)
                    {
                        GUI.enabled = s.canGenerateCode;
                        if (GUILayout.Button("Generate Code", GUILayout.Width(110)) && !isDownloading)
                        {
                            GlobalCCSettings gSettings = CCLogic.GetGlobalSettings();
                            isDownloading = true;
                            GenerateOneCode(s, gSettings);
                            isDownloading = false;

                            GUIUtility.ExitGUI();
                        }
                    }

                    // ------------------------------
                    // アセット生成ボタン.
                    // v0.1.2 からは Import に置き換え.
                    // ------------------------------
                    if (s.verboseBtn)
                    {
                        GUI.enabled = s.canCreateAsset;

                        if (GUILayout.Button("Create Assets", GUILayout.Width(110)) && !isDownloading)
                        {
                            CreateAssetsJob createAssetsJob = new CreateAssetsJob(s);
                            createAssetsJob.Execute();
                            GUIUtility.ExitGUI();
                        }
                    }

                    GUI.enabled = true;

                    // ------------------------------
                    // 成果物参照まど.
                    // ------------------------------
                    {
                        Object outputRef = null;

                        if (s.join)
                        {
                            outputRef = s.targetTable;
                        }
                        else
                        {
                            string mainOutputPath = CCLogic.GetMainOutputPath(s);

                            if (mainOutputPath != null)
                            {
                                outputRef = AssetDatabase.LoadAssetAtPath <Object>(mainOutputPath);
                            }
                        }

                        EditorGUI.BeginDisabledGroup(true);
                        EditorGUILayout.ObjectField(outputRef, typeof(Object), false, GUILayout.Width(100));
                        EditorGUI.EndDisabledGroup();
                    }

                    GUILayout.EndHorizontal();
                }

                GUILayout.EndScrollView();

                GUILayout.BeginHorizontal("box");
                if (GUILayout.Button("Generate All Codes", "LargeButtonMid") && !isDownloading)
                {
                    GlobalCCSettings gSettings = CCLogic.GetGlobalSettings();
                    isDownloading = true;
                    GenerateAllCode(settings, gSettings);
                    isDownloading = false;

                    GUIUtility.ExitGUI();
                }

                if (GUILayout.Button("Create All Assets", "LargeButtonMid") && !isDownloading)
                {
                    GlobalCCSettings gSettings = CCLogic.GetGlobalSettings();
                    isDownloading = true;
                    CreateAllAssets(settings, gSettings);
                    isDownloading = false;

                    GUIUtility.ExitGUI();
                }

                GUILayout.EndHorizontal();
            }
        }
        public void Tick()
        {
            if (coroutine != null)
            {
                // First check if we have been canceled by the UI. If so, we need to stop before doing any wait processing
                if (canceled)
                {
                    Stop();
                    return;
                }

                // Did the last Yield want us to wait?
                bool isWaiting = false;
                var  now       = DateTime.Now;
                if (current != null)
                {
                    if (currentType == typeof(WaitForSeconds))
                    {
                        // last yield was a WaitForSeconds. Lets update the timer.
                        var delta = now - lastUpdateTime;
                        timer -= (float)delta.TotalSeconds;

                        if (timer > 0.0f)
                        {
                            isWaiting = true;
                        }
                    }
                    else if (currentType == typeof(WaitForEndOfFrame) || currentType == typeof(WaitForFixedUpdate))
                    {
                        // These dont make sense in editor, so we will treat them the same as a null return...
                        isWaiting = false;
                    }
                    else if (currentType == typeof(WWW))
                    {
                        // Web download request, lets see if its done!
                        var www = current as WWW;
                        if (!www.isDone)
                        {
                            isWaiting = true;
                        }
                    }
                    else if (currentType.IsSubclassOf(typeof(CustomYieldInstruction)))
                    {
                        // last yield was a custom yield type, lets check its keepWaiting property and react to that
                        var yieldInstruction = current as CustomYieldInstruction;
                        if (yieldInstruction.keepWaiting)
                        {
                            isWaiting = true;
                        }
                    }
                    else if (currentType == typeof(EditorCoroutine))
                    {
                        // Were waiting on another coroutine to finish
                        var editorCoroutine = current as EditorCoroutine;
                        if (!editorCoroutine.HasFinished)
                        {
                            isWaiting = true;
                        }
                    }
                    else if (typeof(IEnumerator).IsAssignableFrom(currentType))
                    {
                        // if were just seeing an enumerator lets assume that were seeing a nested coroutine that has been passed in without calling start.. were start it properly here if we need to
                        if (nestedCoroutine == null)
                        {
                            nestedCoroutine = EditorCoroutineRunner.StartCoroutine(current as IEnumerator);
                            isWaiting       = true;
                        }
                        else
                        {
                            isWaiting = !nestedCoroutine.HasFinished;
                        }
                    }
                    else if (currentType == typeof(Coroutine))
                    {
                        // UNSUPPORTED
                        Debug.LogError(
                            "Nested Coroutines started by Unity's defaut StartCoroutine method are not supported in editor! please use EditorCoroutineRunner.Start instead. Canceling.");
                        canceled = true;
                    }
                    else
                    {
                        // UNSUPPORTED
                        Debug.LogError("Unsupported yield (" + currentType + ") in editor coroutine!! Canceling.");
                        canceled = true;
                    }
                }

                lastUpdateTime = now;

                // have we been canceled?
                if (canceled)
                {
                    Stop();
                    return;
                }

                if (!isWaiting)
                {
                    // nope were good! tick the coroutine!
                    bool update = coroutine.MoveNext();

                    if (update)
                    {
                        // yup the coroutine returned true so its been ticked...

                        // lets see what it actually yielded
                        current = coroutine.Current;
                        if (current != null)
                        {
                            // is it a type we have to do extra processing on?
                            currentType = current.GetType();

                            if (currentType == typeof(WaitForSeconds))
                            {
                                // its a WaitForSeconds... lets use reflection to pull out how long the actual wait is for so we can process the wait
                                var       wait      = current as WaitForSeconds;
                                FieldInfo m_Seconds = typeof(WaitForSeconds).GetField("m_Seconds",
                                                                                      BindingFlags.NonPublic | BindingFlags.Instance);
                                if (m_Seconds != null)
                                {
                                    timer = (float)m_Seconds.GetValue(wait);
                                }
                            }
                            else if (currentType == typeof(EditorStatusUpdate))
                            {
                                // Special case yield that wants to update the UI!
                                var updateInfo = current as EditorStatusUpdate;
                                if (updateInfo.HasLabelUpdate)
                                {
                                    Label = updateInfo.Label;
                                }

                                if (updateInfo.HasPercentUpdate)
                                {
                                    PercentComplete = updateInfo.PercentComplete;
                                }
                            }
                        }
                    }
                    else
                    {
                        // Coroutine returned false so its finally finished!!
                        Stop();
                    }
                }
            }
        }