/// <summary> /// Adds the data to the next avaiable space to write it after the startcell /// </summary> /// <param name="search"></param> /// <param name="inputData"></param> /// <param name="callback"></param> public static void Append(GSTU_Search search, ValueRange inputData, UnityAction callback) { StringBuilder sb = new StringBuilder(); sb.Append("https://sheets.googleapis.com/v4/spreadsheets"); sb.Append("/" + search.sheetId); sb.Append("/values"); sb.Append("/" + search.worksheetName + "!" + search.startCell); sb.Append(":append"); sb.Append("?valueInputOption=USER_ENTERED"); sb.Append("&access_token=" + Config.gdr.access_token); string json = JSON.Dump(inputData, EncodeOptions.NoTypeHints); UnityWebRequest request = UnityWebRequest.Post(sb.ToString(), ""); //have to do this cause unitywebrequest post will nto accept json data corrently... byte[] bodyRaw = new UTF8Encoding().GetBytes(json); request.uploadHandler = new UploadHandlerRaw(bodyRaw); request.downloadHandler = new DownloadHandlerBuffer(); if (Application.isPlaying) { new Task(Append(request, callback)); } #if UNITY_EDITOR else { EditorCoroutineRunner.StartCoroutine(Append(request, callback)); } #endif }
/// <summary> /// Writes a batch update to a spreadsheet /// </summary> /// <param name="search"></param> /// <param name="requestData"></param> /// <param name="callback"></param> public static void WriteBatch(GSTU_Search search, BatchRequestBody requestData, UnityAction callback) { StringBuilder sb = new StringBuilder(); sb.Append("https://sheets.googleapis.com/v4/spreadsheets"); sb.Append("/" + search.sheetId); sb.Append("/values:batchUpdate"); sb.Append("?access_token=" + Config.gdr.access_token); string json = JSON.Dump(requestData, EncodeOptions.NoTypeHints); UnityWebRequest request = UnityWebRequest.Post(sb.ToString(), ""); byte[] bodyRaw = new UTF8Encoding().GetBytes(json); request.uploadHandler = new UploadHandlerRaw(bodyRaw); request.downloadHandler = new DownloadHandlerBuffer(); if (Application.isPlaying) { new Task(WriteBatch(request, callback)); } #if UNITY_EDITOR else { EditorCoroutineRunner.StartCoroutine(WriteBatch(request, callback)); } #endif }
/// <summary> /// Read a public accessable spreadsheet /// </summary> /// <param name="searchDetails"></param> /// <param name="callback">event that will fire after reading is complete</param> public static void ReadPublicSpreadsheet(GSTU_Search searchDetails, OnSpreedSheetLoaded callback) { if (string.IsNullOrEmpty(Config.API_Key)) { Debug.Log("Missing API Key, please enter this in the confie settings"); return; } StringBuilder sb = new StringBuilder(); sb.Append("https://sheets.googleapis.com/v4/spreadsheets"); sb.Append("/" + searchDetails.sheetId); sb.Append("/values"); sb.Append("/" + searchDetails.worksheetName + "!" + searchDetails.startCell + ":" + searchDetails.endCell); sb.Append("?key=" + Config.API_Key); if (Application.isPlaying) { new Task(Read(new WWW(sb.ToString()), searchDetails.titleColumn, searchDetails.titleRow, callback)); } #if UNITY_EDITOR else { EditorCoroutineRunner.StartCoroutine(Read(new WWW(sb.ToString()), searchDetails.titleColumn, searchDetails.titleRow, callback)); } #endif }
/// <summary> /// Writes data to a spreadsheet /// </summary> /// <param name="search"></param> /// <param name="inputData"></param> /// <param name="callback"></param> public static void Write(GSTU_Search search, ValueRange inputData, UnityAction callback) { StringBuilder sb = new StringBuilder(); sb.Append("https://sheets.googleapis.com/v4/spreadsheets"); sb.Append("/" + search.sheetId); sb.Append("/values"); sb.Append("/" + search.worksheetName + "!" + search.startCell + ":" + search.endCell); sb.Append("?valueInputOption=USER_ENTERED"); sb.Append("&access_token=" + Config.gdr.access_token); string json = JSON.Dump(inputData, EncodeOptions.NoTypeHints); byte[] bodyRaw = new UTF8Encoding().GetBytes(json); UnityWebRequest request = UnityWebRequest.Put(sb.ToString(), bodyRaw); if (Application.isPlaying) { new Task(Write(request, callback)); } #if UNITY_EDITOR else { EditorCoroutineRunner.StartCoroutine(Write(request, callback)); } #endif }
public void Load(WWW url, OnSpreedSheetLoaded callback) { if (string.IsNullOrEmpty(config.API_Key)) { Debug.Log("Missing API Key, please enter this in the confie settings"); return; } if (callback != null) { onFinishedLoading += callback; } if (Application.isPlaying) { Task t = new Task(WaitForRequest(url)); } #if UNITY_EDITOR else { EditorCoroutineRunner.StartCoroutine(WaitForRequest(url)); } #endif }
/// <summary> /// Reads the spread sheet and callback with the results /// </summary> /// <param name="request"></param> /// <param name="search"></param> /// <param name="containsMergedCells"></param> /// <param name="callback"></param> /// <returns></returns> static IEnumerator Read(UnityWebRequest request, GSTU_Search search, bool containsMergedCells, UnityAction <GstuSpreadSheet> callback) { if (Application.isPlaying) { yield return(new Task(CheckForRefreshToken())); } #if UNITY_EDITOR else { yield return(EditorCoroutineRunner.StartCoroutine(CheckForRefreshToken())); } #endif using (request) { yield return(request.SendWebRequest()); if (string.IsNullOrEmpty(request.downloadHandler.text) || request.downloadHandler.text == "{}") { Debug.LogWarning("Unable to Retreive data from google sheets"); yield break; } ValueRange rawData = JSON.Load(request.downloadHandler.text).Make <ValueRange>(); LoadSheet.rawData = JSON.Load(request.downloadHandler.text).Make <ValueRange>(); GSTU_SpreadsheetResponce responce = new GSTU_SpreadsheetResponce(rawData); //if it contains merged cells then process a second set of json data to know what these cells are if (containsMergedCells) { StringBuilder sb = new StringBuilder(); sb.Append("https://sheets.googleapis.com/v4/spreadsheets"); sb.Append("/" + search.sheetId); sb.Append("?access_token=" + Config.gdr.access_token); UnityWebRequest request2 = UnityWebRequest.Get(sb.ToString()); yield return(request2.SendWebRequest()); SheetsRootObject root = JSON.Load(request2.downloadHandler.text).Make <SheetsRootObject>(); responce.sheetInfo = root.sheets.FirstOrDefault(x => x.properties.title == search.worksheetName); } if (callback != null) { callback(new GstuSpreadSheet(responce, search.titleColumn, search.titleRow)); } } }
protected static IEnumerator CopyData() { startTime = EditorApplication.timeSinceStartup; EditorCoroutineRunner.UpdateUITitle("Import 1/5: Sounds"); EditorCoroutineRunner.UpdateUILabel("Getting Background data"); TraverseNodes(sounds, "sound"); yield return(null); yield return(EditorCoroutineRunner.StartCoroutine(CopyAssets(targetPaths, ImportType.Sound))); targetPaths = new List <ImportAsset>(); EditorCoroutineRunner.UpdateUITitle("Import 2/5: Backgrounds"); EditorCoroutineRunner.UpdateUILabel("Getting Background data"); TraverseNodes(backgrounds, "background"); yield return(null); yield return(EditorCoroutineRunner.StartCoroutine(CopyAssets(targetPaths, ImportType.Background))); targetPaths = new List <ImportAsset>(); EditorCoroutineRunner.UpdateUITitle("Import 3/5: Sprites"); EditorCoroutineRunner.UpdateUILabel("Getting Sprite data"); TraverseNodes(sprites, "sprite"); yield return(null); yield return(EditorCoroutineRunner.StartCoroutine(CopyAssets(targetPaths, ImportType.Sprite))); targetPaths = new List <ImportAsset>(); EditorCoroutineRunner.UpdateUITitle("Import 4/5: Objects"); EditorCoroutineRunner.UpdateUILabel("Getting Object data"); TraverseNodes(objects, "object"); yield return(null); yield return(EditorCoroutineRunner.StartCoroutine(CopyAssets(targetPaths, ImportType.Object))); targetPaths = new List <ImportAsset>(); EditorCoroutineRunner.UpdateUITitle("Import 5/5: Rooms"); EditorCoroutineRunner.UpdateUILabel("Getting Room data"); TraverseNodes(rooms, "room"); yield return(null); yield return(EditorCoroutineRunner.StartCoroutine(CopyAssets(targetPaths, ImportType.Room))); TimeSpan timeSpan = TimeSpan.FromSeconds(EditorApplication.timeSinceStartup - startTime); string timeText = string.Format("{0:D2}:{1:D2}:{2:D2}", timeSpan.Hours, timeSpan.Minutes, timeSpan.Seconds); print("Project Imported! Total Time: <color=#22ffccff></color> " + "<color=#22ee22ff>" + timeText + "</color>"); }
/// <summary> /// Chekcs for a valid token and if its out of date attempt to refresh it /// </summary> /// <returns></returns> static IEnumerator CheckForRefreshToken() { if (Application.isPlaying) { yield return(new Task(GoogleAuthrisationHelper.CheckForRefreshOfToken())); } #if UNITY_EDITOR else { yield return(EditorCoroutineRunner.StartCoroutine(GoogleAuthrisationHelper.CheckForRefreshOfToken())); } #endif }
/// <summary> /// Child classes should call this once the auth token has been successfully retrieved.</summary> static void NotifyAuthTokenReceived(string authToken) { lock (_notifyAuthTokenLock) { // We're not directly calling _onComplete() here because we're still on HttpListener's async thread. // We need _onComplete() to be called on the main thread, so we store the auth token and set a flag // that will tell us when we should call _onComplete() in the Update() method, which always executes // on the main thread. _authToken = authToken; _shouldNotifyAuthTokenReceived = true; EditorCoroutineRunner.StartCoroutine(CheckForTokenRecieve()); } }
/// <summary> /// Reads information from a spreadsheet /// </summary> /// <param name="search"></param> /// <param name="callback"></param> /// <param name="containsMergedCells"> does the spreadsheet contain merged cells, will attempt to group these by titles</param> public static void Read(GSTU_Search search, UnityAction <GstuSpreadSheet> callback, bool containsMergedCells = false) { UnityWebRequest request = UnityWebRequest.Get(CreateReadRequestURI(search)); if (Application.isPlaying) { new Task(Read(request, search, containsMergedCells, callback)); } #if UNITY_EDITOR else { EditorCoroutineRunner.StartCoroutine(Read(request, search, containsMergedCells, callback)); } #endif }
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!!"); }
static void GetAuthComplete(string authToken) { string serverUrl = string.Format("http://127.0.0.1:{0}", SpreadsheetManager.Config.PORT); Debug.Log(authToken); Debug.Log("Auth Token = " + authToken); WWWForm f = new WWWForm(); f.AddField("code", authToken); f.AddField("client_id", SpreadsheetManager.Config.CLIENT_ID); f.AddField("client_secret", SpreadsheetManager.Config.CLIENT_SECRET); f.AddField("redirect_uri", serverUrl); f.AddField("grant_type", "authorization_code"); f.AddField("scope", ""); EditorCoroutineRunner.StartCoroutine(GetToken(f)); }
/// <summary> /// Reads information from a spreadsheet /// </summary> /// <param name="search"></param> /// <param name="callback"></param> /// <param name="containsMergedCells"> does the spreadsheet contain merged cells, will attempt to group these by titles</param> public static void Read(GSTU_Search search, UnityAction <GstuSpreadSheet> callback, bool containsMergedCells = false) { StringBuilder sb = new StringBuilder(); sb.Append("https://sheets.googleapis.com/v4/spreadsheets"); sb.Append("/" + search.sheetId); sb.Append("/values"); sb.Append("/" + search.worksheetName + "!" + search.startCell + ":" + search.endCell); sb.Append("?access_token=" + Config.gdr.access_token); UnityWebRequest request = UnityWebRequest.Get(sb.ToString()); if (Application.isPlaying) { new Task(Read(request, search, containsMergedCells, callback)); } #if UNITY_EDITOR else { EditorCoroutineRunner.StartCoroutine(Read(request, search, containsMergedCells, callback)); } #endif }
static IEnumerator Append(UnityWebRequest request, UnityAction callback) { if (Application.isPlaying) { yield return(new Task(CheckForRefreshToken())); } #if UNITY_EDITOR else { yield return(EditorCoroutineRunner.StartCoroutine(CheckForRefreshToken())); } #endif using (request) { yield return(request.SendWebRequest()); if (callback != null) { callback(); } } }
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(); } } } }
public static void PullLatestFromGoogleDocs(TextoSettingsData textoSettingsData) { EditorCoroutineRunner.StartCoroutine(PullRoutine(textoSettingsData)); }