|
|
- namespace Oculus.Platform.Samples.VrVoiceChat
- {
- using UnityEngine;
- using System;
- using System.Collections.Generic;
- using Oculus.Platform;
- using Oculus.Platform.Models;
-
- // Helper class to manage Room creation, membership and invites.
- // Rooms are a mechanism to help Oculus users create a shared experience.
- // Users can only be in one Room at a time. If the Owner of a room
- // leaves, then ownership is transferred to some other member.
- // Here we use rooms to create the notion of a 'call' to help us
- // invite a Friend and establish a VOIP and P2P connection.
- public class RoomManager
- {
- // the ID of the Room that I'm in
- private ulong m_roomID;
-
- // the other User in the Room
- private User m_remoteUser;
-
- // how often I should poll for invites
- private static readonly float INVITE_POLL_FREQ_SECONDS = 5.0f;
-
- // the next time I should poll Oculus Platform for valid Room Invite requests
- private float m_nextPollTime;
-
- public struct Invite
- {
- public readonly ulong RoomID;
- public readonly string OwnerID;
-
- public Invite(ulong roomID, string owner)
- {
- this.RoomID = roomID;
- this.OwnerID = owner;
- }
- }
-
- // cached list of rooms that I've been invited to and I'm waiting
- // for more information about
- private HashSet<ulong> m_pendingRoomRequests;
-
- // accumulation list of room invites and the room owner
- private List<Invite> m_invites;
-
- public RoomManager()
- {
- Rooms.SetRoomInviteAcceptedNotificationCallback(LaunchedFromAcceptingInviteCallback);
- Rooms.SetUpdateNotificationCallback(RoomUpdateCallback);
- }
-
- public ulong RemoteUserID
- {
- get
- {
- return m_remoteUser != null ? m_remoteUser.ID : 0;
- }
- }
-
- public String RemoteOculusID
- {
- get
- {
- return m_remoteUser != null ? m_remoteUser.OculusID : String.Empty;
- }
- }
-
- #region Launched Application from Accepting Invite
-
- // Callback to check whether the User accepted the invite as
- // a notification which caused the Application to launch. If so, then
- // we know we need to try to join that room.
- void LaunchedFromAcceptingInviteCallback(Message<string> msg)
- {
- if (msg.IsError)
- {
- PlatformManager.TerminateWithError(msg);
- return;
- }
-
- Debug.Log("Launched Invite to join Room: " + msg.Data);
-
- m_roomID = Convert.ToUInt64(msg.GetString());
- }
-
- // Check to see if the App was launched by accepting the Notication from the main Oculus app.
- // If so, we can directly join that room. (If it's still available.)
- public bool CheckForLaunchInvite()
- {
- if (m_roomID != 0)
- {
- JoinExistingRoom(m_roomID);
- return true;
- }
- else
- {
- return false;
- }
- }
-
- #endregion
-
- #region Create a Room and Invite Friend(s) from the Oculus Universal Menu
-
- public void CreateRoomAndLaunchInviteMenu()
- {
- Rooms.CreateAndJoinPrivate(RoomJoinPolicy.InvitedUsers, 2, true)
- .OnComplete(CreateAndJoinPrivateRoomCallback);
- }
-
- void CreateAndJoinPrivateRoomCallback(Message<Room> msg)
- {
- if (msg.IsError)
- {
- PlatformManager.TerminateWithError(msg);
- return;
- }
-
- m_roomID = msg.Data.ID;
- m_remoteUser = null;
- PlatformManager.TransitionToState(PlatformManager.State.WAITING_FOR_ANSWER);
-
- // launch the Room Invite workflow in the Oculus Univeral Menu
- Rooms.LaunchInvitableUserFlow(m_roomID).OnComplete(OnLaunchInviteWorkflowComplete);
- }
-
- void OnLaunchInviteWorkflowComplete(Message msg)
- {
- if (msg.IsError)
- {
- PlatformManager.TerminateWithError(msg);
- return;
- }
- }
-
- #endregion
-
- #region Polling for Invites
-
- public bool ShouldPollInviteList
- {
- get
- {
- return m_pendingRoomRequests == null && Time.time >= m_nextPollTime;
- }
- }
-
- public void UpdateActiveInvitesList()
- {
- m_nextPollTime = Time.time + INVITE_POLL_FREQ_SECONDS;
- m_pendingRoomRequests = new HashSet<ulong>();
- m_invites = new List<Invite>();
- Notifications.GetRoomInviteNotifications().OnComplete(GetRoomInviteNotificationsCallback);
- }
-
- // task 13572454: add the type to callback definition
- void GetRoomInviteNotificationsCallback(Message msg_untyped)
- {
- Message<RoomInviteNotificationList> msg = (Message<RoomInviteNotificationList>)msg_untyped;
-
- if (msg.IsError)
- {
- PlatformManager.TerminateWithError(msg);
- return;
- }
-
- // loop over all the rooms we're invited to and request more info
- foreach (RoomInviteNotification invite in msg.Data)
- {
- m_pendingRoomRequests.Add(invite.RoomID);
- Rooms.Get(invite.RoomID).OnComplete(GetRoomInfoCallback);
- }
-
- if (msg.Data.Count == 0)
- {
- m_pendingRoomRequests = null;
- PlatformManager.SetActiveInvites(m_invites);
- }
- }
-
- void GetRoomInfoCallback(Message<Room> msg)
- {
- if (msg.IsError)
- {
- PlatformManager.TerminateWithError(msg);
- return;
- }
-
- if (msg.Data.OwnerOptional != null)
- {
- Invite invite = new Invite(msg.Data.ID, msg.Data.OwnerOptional.OculusID);
- m_pendingRoomRequests.Remove(invite.RoomID);
-
- // make sure the room still looks usable
- // (e.g. they aren't currently talking to someone)
- if (msg.Data.UsersOptional != null && msg.Data.UsersOptional.Count == 1)
- {
- m_invites.Add(invite);
- }
- }
-
- // once we're received all the room info, let the platform update
- // its display
- if (m_pendingRoomRequests.Count == 0)
- {
- m_pendingRoomRequests = null;
- PlatformManager.SetActiveInvites(m_invites);
- }
- }
-
- #endregion
-
- #region Accept Invite
-
- public void JoinExistingRoom(ulong roomID)
- {
- Rooms.Join(roomID, true).OnComplete(JoinRoomCallback);
- }
-
- void JoinRoomCallback(Message<Room> msg)
- {
- if (msg.IsError)
- {
- // is reasonable if caller called more than 1 person, and I didn't answer first
- return;
- }
-
- string oculusOwnerID = msg.Data.OwnerOptional != null ? msg.Data.OwnerOptional.OculusID : "";
- int numUsers = msg.Data.UsersOptional != null ? msg.Data.UsersOptional.Count : 0;
-
- Debug.LogFormat("Joined room: {0} owner: {1} count: ",
- msg.Data.ID, oculusOwnerID, numUsers);
-
- m_roomID = msg.Data.ID;
-
- // if the caller left while I was in the process of joining, just hangup
- if (msg.Data.UsersOptional == null || msg.Data.UsersOptional.Count != 2)
- {
- PlatformManager.TransitionToState(PlatformManager.State.HANGUP);
- }
- else
- {
- foreach (User user in msg.Data.UsersOptional)
- {
- if (user.ID != PlatformManager.MyID)
- {
- m_remoteUser = user;
- }
- }
-
- PlatformManager.TransitionToState(PlatformManager.State.CONNECTED_IN_A_ROOM);
- }
-
- // update the invite list sooner
- m_nextPollTime = Time.time;
- }
-
- #endregion
-
- #region Room Updates
-
- void RoomUpdateCallback(Message<Room> msg)
- {
- if (msg.IsError)
- {
- PlatformManager.TerminateWithError(msg);
- return;
- }
-
- string oculusOwnerID = msg.Data.OwnerOptional != null ? msg.Data.OwnerOptional.OculusID : "";
- int numUsers = msg.Data.UsersOptional != null ? msg.Data.UsersOptional.Count : 0;
-
- Debug.LogFormat("Room {0} Update: {1} owner: {2} count: ",
- msg.Data.ID, oculusOwnerID, numUsers);
-
- // if the Room count is not 2 then the other party has left.
- // We'll just hangup the connection here.
- // If the other User created then room, ownership would switch to me.
- if (msg.Data.UsersOptional == null || msg.Data.UsersOptional.Count != 2)
- {
- PlatformManager.TransitionToState(PlatformManager.State.HANGUP);
- }
- else
- {
- foreach (User user in msg.Data.UsersOptional)
- {
- if (user.ID != PlatformManager.MyID)
- {
- m_remoteUser = user;
- }
- }
-
- PlatformManager.TransitionToState(PlatformManager.State.CONNECTED_IN_A_ROOM);
- }
- }
-
- #endregion
-
- #region Room Exit
-
- public void LeaveCurrentRoom()
- {
- if (m_roomID != 0)
- {
- Rooms.Leave(m_roomID);
- m_roomID = 0;
- m_remoteUser = null;
- }
- PlatformManager.TransitionToState(PlatformManager.State.WAITING_TO_CALL_OR_ANSWER);
- }
-
- #endregion
- }
- }
|