FittsLaw/Assets/GoogleVR/Scripts/Controller/Internal/Emulator/EmulatorManager.cs
2018-10-08 23:54:11 -04:00

251 lines
7.5 KiB
C#

// Copyright 2016 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// This class is only used in the Editor, so make sure to only compile it on that platform.
// Additionally, it depends on EmulatorClientSocket which is only compiled in the editor.
// This MonoBehaviour is only ever instantiated dynamically, so it is fine that it is only compiled in the Editor,
// Otherwise it would cause serialization issues.
#if UNITY_EDITOR
using System.Collections;
using UnityEngine;
using proto;
/// @cond
namespace Gvr.Internal {
class EmulatorManager : MonoBehaviour {
private IEnumerator emulatorUpdate;
private WaitForEndOfFrame waitForEndOfFrame = new WaitForEndOfFrame();
public static EmulatorManager Instance {
get {
if (instance == null) {
var gameObject = new GameObject("PhoneRemote");
instance = gameObject.AddComponent<EmulatorManager>();
// This object should survive all scene transitions.
GameObject.DontDestroyOnLoad(instance);
}
return instance;
}
}
private static EmulatorManager instance = null;
public delegate void OnGyroEvent(EmulatorGyroEvent gyroEvent);
public event OnGyroEvent gyroEventListeners {
add {
if (value != null) {
value(currentGyroEvent);
}
gyroEventListenersInternal += value;
}
remove {
gyroEventListenersInternal -= value;
}
}
public delegate void OnAccelEvent(EmulatorAccelEvent accelEvent);
public event OnAccelEvent accelEventListeners {
add {
if (value != null) {
value(currentAccelEvent);
}
accelEventListenersInternal += value;
}
remove {
accelEventListenersInternal -= value;
}
}
public delegate void OnTouchEvent(EmulatorTouchEvent touchEvent);
public event OnTouchEvent touchEventListeners {
add {
if (value != null
&& currentTouchEvent.pointers != null /* null only during init */) {
value(currentTouchEvent);
}
touchEventListenersInternal += value;
}
remove {
touchEventListenersInternal -= value;
}
}
public delegate void OnOrientationEvent(EmulatorOrientationEvent orientationEvent);
public event OnOrientationEvent orientationEventListeners {
add {
if (value != null) {
value(currentOrientationEvent);
}
orientationEventListenersInternal += value;
}
remove {
orientationEventListenersInternal -= value;
}
}
public delegate void OnButtonEvent(EmulatorButtonEvent buttonEvent);
public event OnButtonEvent buttonEventListeners {
add {
if (value != null) {
value(currentButtonEvent);
}
buttonEventListenersInternal += value;
}
remove {
buttonEventListenersInternal -= value;
}
}
private void onGyroEvent(EmulatorGyroEvent e) {
currentGyroEvent = e;
if (gyroEventListenersInternal != null) {
gyroEventListenersInternal(e);
}
}
private void onAccelEvent(EmulatorAccelEvent e) {
currentAccelEvent = e;
if (accelEventListenersInternal != null) {
accelEventListenersInternal(e);
}
}
private void onTouchEvent(EmulatorTouchEvent e) {
currentTouchEvent = e;
if (touchEventListenersInternal != null) {
touchEventListenersInternal(e);
}
}
private void onOrientationEvent(EmulatorOrientationEvent e) {
currentOrientationEvent = e;
if (orientationEventListenersInternal != null) {
orientationEventListenersInternal(e);
}
}
private void onButtonEvent(EmulatorButtonEvent e) {
currentButtonEvent = e;
if (buttonEventListenersInternal != null) {
buttonEventListenersInternal(e);
}
}
EmulatorGyroEvent currentGyroEvent;
EmulatorAccelEvent currentAccelEvent;
EmulatorTouchEvent currentTouchEvent;
EmulatorOrientationEvent currentOrientationEvent;
EmulatorButtonEvent currentButtonEvent;
private event OnGyroEvent gyroEventListenersInternal;
private event OnAccelEvent accelEventListenersInternal;
private event OnTouchEvent touchEventListenersInternal;
private event OnOrientationEvent orientationEventListenersInternal;
private event OnButtonEvent buttonEventListenersInternal;
private Queue pendingEvents = Queue.Synchronized(new Queue());
private EmulatorClientSocket socket;
private long lastDownTimeMs;
public bool Connected {
get {
return socket != null && socket.connected == EmulatorClientSocketConnectionState.Connected;
}
}
public bool Connecting {
get {
return socket != null && socket.connected == EmulatorClientSocketConnectionState.Connecting;
}
}
public void Awake() {
if (instance == null) {
instance = this;
}
if (instance != this) {
Debug.LogWarning("PhoneRemote must be a singleton.");
enabled = false;
return;
}
}
public void Start() {
socket = gameObject.AddComponent<EmulatorClientSocket>();
socket.Init(this);
emulatorUpdate = EndOfFrame();
StartCoroutine(emulatorUpdate);
}
IEnumerator EndOfFrame() {
while (true) {
yield return waitForEndOfFrame;
lock (pendingEvents.SyncRoot) {
while (pendingEvents.Count > 0) {
PhoneEvent phoneEvent = (PhoneEvent) pendingEvents.Dequeue();
ProcessEventAtEndOfFrame(phoneEvent);
}
}
}
}
public void OnPhoneEvent(PhoneEvent e) {
pendingEvents.Enqueue(e);
}
private void ProcessEventAtEndOfFrame(PhoneEvent e) {
switch (e.Type) {
case PhoneEvent.Types.Type.MOTION:
EmulatorTouchEvent touchEvent = new EmulatorTouchEvent(e.MotionEvent, lastDownTimeMs);
onTouchEvent(touchEvent);
if (touchEvent.getActionMasked() == EmulatorTouchEvent.Action.kActionDown) {
lastDownTimeMs = e.MotionEvent.Timestamp;
}
break;
case PhoneEvent.Types.Type.GYROSCOPE:
EmulatorGyroEvent gyroEvent = new EmulatorGyroEvent(e.GyroscopeEvent);
onGyroEvent(gyroEvent);
break;
case PhoneEvent.Types.Type.ACCELEROMETER:
EmulatorAccelEvent accelEvent = new EmulatorAccelEvent(e.AccelerometerEvent);
onAccelEvent(accelEvent);
break;
case PhoneEvent.Types.Type.ORIENTATION:
EmulatorOrientationEvent orientationEvent =
new EmulatorOrientationEvent(e.OrientationEvent);
onOrientationEvent(orientationEvent);
break;
case PhoneEvent.Types.Type.KEY:
EmulatorButtonEvent buttonEvent = new EmulatorButtonEvent(e.KeyEvent);
onButtonEvent(buttonEvent);
break;
default:
Debug.Log("Unsupported PhoneEvent type: " + e.Type);
break;
}
}
}
}
/// @endcond
#endif // UNITY_EDITOR