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 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 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)) { 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); }