private static string ExecuteGameObjectsEmulation(string nameOrPath, string parent, string root, string upath, Func <List <GameObject>, string> onComplete) { var autoEvent = new AutoResetEvent(false); var response = ""; MainThreadHelper.QueueOnMainThread(() => { try { List <GameObject> listOfGOs; if (!string.IsNullOrEmpty(upath)) { listOfGOs = FindGameObjectHelper.FindGameObjectsByUPath(upath); } else { listOfGOs = FindGameObjectHelper.GetGameObjects(nameOrPath, root, parent); } response = onComplete(listOfGOs); } catch (Exception e) { Log(e); response = e.Message; } finally { // set the event to "unlock" the thread autoEvent.Set(); } }); // wait for the end of the 'action' executed in the main thread autoEvent.WaitOne(); return(response); }
private static string InvokeOnMainThreadAndWait(Action action) { // event used to wait the answer from the main thread. AutoResetEvent autoEvent = new AutoResetEvent(false); string response = SuccessResult; MainThreadHelper.QueueOnMainThread(() => { try { action(); } catch (Exception e) { Log(e); response = e.Message; } finally { // set the event to "unlock" the thread autoEvent.Set(); } }); // wait for the end of the 'action' executed in the main thread autoEvent.WaitOne(); return(response); }
private static string ExecuteGameObjectEmulation(string rootName, string nameOrPath, string parent, string upath, Func <GameObject, string> onComplete, string notFoundMsg = null) { // event used to wait the answer from the main thread. AutoResetEvent autoEvent = new AutoResetEvent(false); string response = ""; MainThreadHelper.QueueOnMainThread(() => { try { GameObject go; if (!string.IsNullOrEmpty(upath)) { go = FindGameObjectHelper.FindGameObjectByUPath(upath); } else { go = FindGameObjectHelper.FindGameObject(rootName, nameOrPath, parent); } if (go != null) { response = onComplete(go); } else { if (notFoundMsg != null) { response = notFoundMsg; } else { response = "not found (" + (parent != null ? parent + "/" : "") + nameOrPath + ")"; } } } catch (Exception e) { Log(e); response = e.Message; } finally { // set the event to "unlock" the thread autoEvent.Set(); } }); // wait for the end of the 'action' executed in the main thread autoEvent.WaitOne(); return(response); }
internal static DriverResponse HandleDriverRequest(DriverRequest request) { var response = new DriverResponse { method = request.method }; var session = GetSession(); switch (request.method.ToLowerInvariant()) { case "registereditor": if (string.IsNullOrEmpty(session)) { SaveSession(request.session); response.session = request.session; } else { response.session = session; } response.result = "unity"; break; case "exist": response.result = ExecuteGameObjectEmulation(request.root, request.name, request.parent, request.upath, gameObject => true.ToString()); break; case "active": response.result = ExecuteGameObjectEmulation(request.root, request.name, request.parent, request.upath, gameObject => gameObject.activeInHierarchy.ToString()); break; case "onscreen": response.result = ExecuteGameObjectEmulation(request.root, request.name, request.parent, request.upath, gameObject => ScreenHelper.IsOnScreen(gameObject).ToString()); break; case "graphicclickable": response.result = ExecuteGameObjectEmulation(request.root, request.name, request.parent, request.upath, gameObject => ScreenHelper.IsGraphicClickable(gameObject).ToString()); break; case "getcomponent": response.result = ExecuteGameObjectEmulation(request.root, request.name, request.parent, request.upath, gameObject => { var component = gameObject.GetComponent(request.value); return(component != null ? EditorJsonUtility.ToJson(component) : "null"); }); break; case "click": response.result = ExecuteGameObjectEmulation(request.root, request.name, request.parent, request.upath, gameObject => { var pointer = new PointerEventData(EventSystem.current); ExecuteEvents.Execute(gameObject, pointer, ExecuteEvents.pointerClickHandler); return(SuccessResult); }); break; case "isrendering": response.result = ExecuteGameObjectEmulation(request.root, request.name, request.parent, request.upath, go => { var renderer = go.GetComponent <Renderer>(); if (renderer != null) { return(renderer.isVisible.ToString()); } return(false.ToString()); }); break; case "count": response.result = ExecuteGameObjectsEmulation(request.root, request.name, request.parent, request.upath, goList => goList.Count.ToString()); break; case "deletepref": response.result = InvokeOnMainThreadAndWait(() => { PlayerPrefs.DeleteKey(request.value); PlayerPrefs.Save(); }); break; case "deleteallprefs": response.result = InvokeOnMainThreadAndWait(() => { PlayerPrefs.DeleteAll(); PlayerPrefs.Save(); }); break; case "getcoordinates": response.result = ExecuteGameObjectEmulation(request.root, request.name, request.parent, request.upath, gameObject => { var position = ScreenHelper.GetPositionOnScreen(gameObject); var coordinates = new ScreenCoordinates { X = position.x, Y = position.y }; return(JsonUtility.ToJson(coordinates)); }); break; case "swipe": var swipeDirection = Vector2.zero; switch (request.value) { case "up": swipeDirection = Vector2.up; break; case "down": swipeDirection = Vector2.down; break; case "left": swipeDirection = Vector2.left; break; case "right": swipeDirection = Vector2.right; break; } swipeDirection *= 100; response.result = ExecuteGameObjectEmulation(request.root, request.name, request.parent, request.upath, gameObject => { var pointer = new PointerEventData(EventSystem.current); gameObject.GetComponent <MonoBehaviour>().StartCoroutine(DragCoroutine(gameObject, pointer, (Vector2)ScreenHelper.GetPositionOnScreen(gameObject) + swipeDirection * 2)); return(SuccessResult); }); break; case "dragto": response.result = ExecuteGameObjectEmulation(request.root, request.name, request.parent, request.upath, gameObject => { var screenCoordinates = new ScreenCoordinates(); EditorJsonUtility.FromJsonOverwrite(request.value, screenCoordinates); var pointer = new PointerEventData(EventSystem.current); gameObject.GetComponent <MonoBehaviour>().StartCoroutine(DragCoroutine(gameObject, pointer, new Vector2 { x = screenCoordinates.X, y = screenCoordinates.Y })); return("OK"); }); break; case "sendkeys": response.result = ExecuteGameObjectEmulation(request.root, request.name, request.parent, request.upath, gameObject => { var input = gameObject.GetComponent <InputField>(); if (input != null) { input.text = request.value; } else { return("input not found"); } return(SuccessResult); }); break; case "startplaymode": EditorApplication.update += StartPlayMode; response.result = SuccessResult; break; case "stopplaymode": response.result = InvokeOnMainThreadAndWait(() => { //EditorApplication.UnlockReloadAssemblies(); EditorApplication.isPlaying = false; }); break; case "ping": response.result = "pong"; break; case "takescreenshot": var path = request.value; MainThreadHelper.QueueOnMainThread(() => { TakeScreenshot(path); }); response.result = SuccessResult; break; default: response.result = "Unknown method " + request.method + "."; break; } return(response); }
internal static DriverResponse HandleDriverRequest(DriverRequest request) { var response = new DriverResponse { method = request.method }; var session = GetSession(); switch (request.method.ToLowerInvariant()) { case "registereditor": if (string.IsNullOrEmpty(session)) { #if UNITY_EDITOR SaveSession(request.session); #endif response.session = request.session; } else { response.session = session; } response.result = "unity"; break; case "exist": response.result = MainThreadHelper.ExecuteGameObjectEmulation(request.upath, gameObject => true.ToString()); break; case "active": response.result = MainThreadHelper.ExecuteGameObjectEmulation(request.upath, gameObject => gameObject.activeInHierarchy.ToString()); break; case "onscreen": response.result = MainThreadHelper.ExecuteGameObjectEmulation(request.upath, gameObject => ScreenHelper.IsOnScreen(gameObject).ToString()); break; case "raycasted": response.result = MainThreadHelper.ExecuteGameObjectEmulation(request.upath, gameObject => { string result = null; switch (request.value) { case "graphicraycaster": result = ScreenHelper.IsRaycasted <GraphicRaycaster>(gameObject).ToString(); break; case "physicsraycaster": result = ScreenHelper.IsRaycasted <PhysicsRaycaster>(gameObject).ToString(); break; case "physics2draycaster": result = ScreenHelper.IsRaycasted <Physics2DRaycaster>(gameObject).ToString(); break; default: result = "Error: " + request.value + " is invalid raycaster"; break; } return(result); }); break; case "getcomponent": response.result = MainThreadHelper.ExecuteGameObjectEmulation(request.upath, gameObject => { var component = gameObject.GetComponent(request.value); #if UNITY_EDITOR return(component != null ? EditorJsonUtility.ToJson(component) : "null"); #else return(component != null ? JsonUtility.ToJson(component) : "null"); #endif }); break; case "click": response.result = MainThreadHelper.ExecuteGameObjectEmulation(request.upath, gameObject => { var pointer = new PointerEventData(EventSystem.current); ExecuteEvents.Execute(gameObject, pointer, ExecuteEvents.pointerClickHandler); return(ErrorMessages.SuccessResult); }); break; case "isrendering": response.result = MainThreadHelper.ExecuteGameObjectEmulation(request.upath, go => { var renderer = go.GetComponent <Renderer>(); if (renderer != null) { return(renderer.isVisible.ToString()); } return(false.ToString()); }); break; case "getscene": response.result = MainThreadHelper.InvokeOnMainThreadAndWait(() => SceneManager.GetActiveScene().name); break; case "openscene": response.result = MainThreadHelper.InvokeOnMainThreadAndWait( () => { try { SceneManager.LoadScene(request.key); return(ErrorMessages.SuccessResult); } catch (Exception e) { return(e.ToString()); } }); break; case "count": response.result = MainThreadHelper.ExecuteGameObjectsEmulation(request.upath, goList => goList.Count.ToString()); break; case "deleteplayerpref": response.result = MainThreadHelper.InvokeOnMainThreadAndWait(() => { PlayerPrefs.DeleteKey(request.key); PlayerPrefs.Save(); }); break; case "deleteallprefs": response.result = MainThreadHelper.InvokeOnMainThreadAndWait(() => { PlayerPrefs.DeleteAll(); PlayerPrefs.Save(); }); break; case "getfloatplayerpref": response.result = MainThreadHelper.InvokeOnMainThreadAndWait(() => PlayerPrefs.GetFloat(request.key).ToString(CultureInfo.InvariantCulture)); break; case "getintplayerpref": response.result = MainThreadHelper.InvokeOnMainThreadAndWait(() => PlayerPrefs.GetInt(request.key).ToString()); break; case "getstringplayerpref": response.result = MainThreadHelper.InvokeOnMainThreadAndWait(() => PlayerPrefs.GetString(request.key)); break; case "setfloatplayerpref": response.result = MainThreadHelper.InvokeOnMainThreadAndWait(() => { var result = ErrorMessages.SuccessResult; try { PlayerPrefs.SetFloat(request.key, float.Parse(request.value)); PlayerPrefs.Save(); } catch (Exception e) { result = e.ToString(); } return(result); }); break; case "setintplayerpref": response.result = MainThreadHelper.InvokeOnMainThreadAndWait(() => { var result = ErrorMessages.SuccessResult; try { PlayerPrefs.SetInt(request.key, int.Parse(request.value)); PlayerPrefs.Save(); } catch (Exception e) { result = e.ToString(); } return(result); }); break; case "setstringplayerpref": response.result = MainThreadHelper.InvokeOnMainThreadAndWait(() => { var result = ErrorMessages.SuccessResult; try { PlayerPrefs.SetFloat(request.key, float.Parse(request.value)); PlayerPrefs.Save(); } catch (Exception e) { result = e.ToString(); } return(result); }); break; case "playerprefhaskey": response.result = MainThreadHelper.InvokeOnMainThreadAndWait(() => { string result; try { result = PlayerPrefs.HasKey(request.key).ToString(); } catch (Exception e) { result = e.ToString(); } return(result); }); break; case "getcoordinates": response.result = MainThreadHelper.ExecuteGameObjectEmulation(request.upath, gameObject => { var position = ScreenHelper.GetPositionOnScreen(gameObject, Camera.main); var coordinates = new ScreenCoordinates { X = position.x, Y = position.y }; return(JsonUtility.ToJson(coordinates)); }); break; case "swipe": var swipeDirection = Vector2.zero; switch (request.value) { case "up": swipeDirection = Vector2.up; break; case "down": swipeDirection = Vector2.down; break; case "left": swipeDirection = Vector2.left; break; case "right": swipeDirection = Vector2.right; break; } swipeDirection *= 100; response.result = MainThreadHelper.ExecuteGameObjectEmulation(request.upath, gameObject => { var pointer = new PointerEventData(EventSystem.current); gameObject.GetComponent <MonoBehaviour>().StartCoroutine(DragCoroutine(gameObject, pointer, (Vector2)ScreenHelper.GetPositionOnScreen(gameObject, Camera.main) + swipeDirection * 2)); return(ErrorMessages.SuccessResult); }); break; case "dragto": response.result = MainThreadHelper.ExecuteGameObjectEmulation(request.upath, gameObject => { var screenCoordinates = new ScreenCoordinates(); JsonUtility.FromJsonOverwrite(request.value, screenCoordinates); var pointer = new PointerEventData(EventSystem.current); gameObject.GetComponent <MonoBehaviour>().StartCoroutine(DragCoroutine(gameObject, pointer, new Vector2 { x = screenCoordinates.X, y = screenCoordinates.Y })); return("OK"); }); break; case "sendkeys": response.result = MainThreadHelper.ExecuteGameObjectEmulation(request.upath, gameObject => { var input = gameObject.GetComponent <InputField>(); if (input != null) { input.text = request.value; } else { /*var tmpInput = gameObject.GetComponent<TMP_InputField>(); * if (tmpInput != null) * tmpInput.text = request.value; * else*/ return("input not found"); } return(ErrorMessages.SuccessResult); }); break; case "startplaymode": #if UNITY_EDITOR EditorApplication.update += StartPlayMode; response.result = ErrorMessages.SuccessResult; #else response.result = ErrorMessages.MethodIsNotSupported; #endif break; case "stopplaymode": #if UNITY_EDITOR response.result = MainThreadHelper.InvokeOnMainThreadAndWait(() => { //EditorApplication.UnlockReloadAssemblies(); EditorApplication.isPlaying = false; }); #else response.result = ErrorMessages.MethodIsNotSupported; #endif break; case "ping": response.result = "pong"; break; case "takescreenshot": var path = request.value; response.result = MainThreadHelper.InvokeOnMainThreadAndWait(() => { TakeScreenshot(path); }); break; case "isplaymode": response.result = MainThreadHelper.InvokeOnMainThreadAndWait(() => Application.isPlaying.ToString()); break; case "gamecustom": response.result = CustomDriverHandler.ProcessGameCustomMethod(request.key, request.value); break; case "gameobjectcustom": response.result = CustomDriverHandler.ProcessGameObjectCustomMethod(request.upath, request.key, request.value); break; case "getspritename": response.result = MainThreadHelper.ExecuteGameObjectEmulation(request.upath, gameObject => { var component = gameObject.GetComponent <SpriteRenderer>(); if (component != null) { return(component.sprite.name); } else { return("Component was not found"); } }); break; case "settimescale": response.result = MainThreadHelper.InvokeOnMainThreadAndWait(() => Time.timeScale = float.Parse(request.value)); break; case "getgameobjectinfo": response.result = MainThreadHelper.ExecuteGameObjectEmulation(request.upath, go => { #if UNITY_EDITOR return(EditorJsonUtility.ToJson(go)); #else return(JsonUtility.ToJson(go)); #endif }); break; default: response.result = "Unknown method " + request.method + "."; break; } return(response); }
private MainThreadHelper() { Instance = this; }
internal static DriverResponse HandleDriverRequest(DriverRequest request) { var response = new DriverResponse { method = request.method }; var session = GetSession(); switch (request.method.ToLowerInvariant()) { case "registereditor": if (string.IsNullOrEmpty(session)) { SaveSession(request.session); response.session = request.session; } else { response.session = session; } response.result = "unity"; break; case "exist": response.result = ExecuteGameObjectEmulation(request.root, request.name, request.parent, request.upath, gameObject => true.ToString(), false.ToString()); break; case "active": response.result = ExecuteGameObjectEmulation(request.root, request.name, request.parent, request.upath, gameObject => gameObject.activeInHierarchy.ToString(), false.ToString()); break; case "onscreen": response.result = ExecuteGameObjectEmulation(request.root, request.name, request.parent, request.upath, go => { return(ScreenHelper.IsOnScreen(go).ToString()); }, "False"); break; case "clickable": response.result = ExecuteGameObjectEmulation(request.root, request.name, request.parent, request.upath, go => { return(ScreenHelper.IsGraphicClickable(go).ToString()); }, "False"); break; case "getcomponent": response.result = ExecuteGameObjectEmulation(request.root, request.name, request.parent, request.upath, gameObject => { var component = gameObject.GetComponent(request.value); return(component != null ? EditorJsonUtility.ToJson(component) : "null"); }); break; case "click": response.result = ExecuteGameObjectEmulation(request.root, request.name, request.parent, request.upath, go => { var pointer = new PointerEventData(EventSystem.current); ExecuteEvents.Execute(go, pointer, ExecuteEvents.pointerClickHandler); return(SuccessResult); }); break; case "isrendering": response.result = ExecuteGameObjectEmulation(request.root, request.name, request.parent, request.upath, go => { var renderer = go.GetComponent <Renderer>(); if (renderer != null) { return(renderer.isVisible.ToString()); } return(false.ToString()); }); break; case "count": response.result = ExecuteGameObjectsEmulation(request.root, request.name, request.parent, request.upath, goList => goList.Count.ToString()); break; case "deletepref": response.result = InvokeOnMainThreadAndWait(() => { PlayerPrefs.DeleteKey(request.value); PlayerPrefs.Save(); }); break; case "deleteallprefs": response.result = InvokeOnMainThreadAndWait(() => { PlayerPrefs.DeleteAll(); PlayerPrefs.Save(); }); break; case "swipe": var swipeDirection = Vector2.zero; switch (request.value) { case "up": swipeDirection = Vector2.up; break; case "down": swipeDirection = Vector2.down; break; case "left": swipeDirection = Vector2.left; break; case "right": swipeDirection = Vector2.right; break; } swipeDirection *= 100; response.result = ExecuteGameObjectEmulation(request.root, request.name, request.parent, request.upath, go => { var pointer = new PointerEventData(EventSystem.current); var rt = (RectTransform)go.transform; Vector3[] corners = new Vector3[4]; rt.GetWorldCorners(corners); var bottomLeft = Camera.main.WorldToScreenPoint(corners[0]); var topLeft = Camera.main.WorldToScreenPoint(corners[1]); var topRight = Camera.main.WorldToScreenPoint(corners[2]); var bottomRight = Camera.main.WorldToScreenPoint(corners[3]); var center = new Vector2(topLeft.x + (bottomRight.x - topLeft.x) / 2, bottomRight.y + (topLeft.y - bottomRight.y) / 2); go.GetComponent <MonoBehaviour>() .StartCoroutine(DragCoroutine(go, pointer, center, swipeDirection)); return(SuccessResult); }); break; case "sendkeys": response.result = ExecuteGameObjectEmulation(request.root, request.name, request.parent, request.upath, go => { var input = go.GetComponent <InputField>(); if (input != null) { input.text = request.value; } else { return("input not found"); } return(SuccessResult); }); break; case "startplaymode": EditorApplication.update += StartPlayMode; response.result = SuccessResult; break; case "stopplaymode": response.result = InvokeOnMainThreadAndWait(() => { EditorApplication.UnlockReloadAssemblies(); EditorApplication.isPlaying = false; }); break; case "ping": response.result = "pong"; break; case "takescreenshot": var path = request.value; MainThreadHelper.QueueOnMainThread(() => { TakeScreenshot(path); }); response.result = SuccessResult; break; default: response.result = "Unknown method " + request.method + "."; break; } return(response); }