AR Design
UBC EML collab with UBC SALA - visualizing IoT data in AR
AutoJoinSessionAndRoom.cs
Go to the documentation of this file.
1 // Copyright (c) Microsoft Corporation. All rights reserved.
2 // Licensed under the MIT License. See LICENSE in the project root for license information.
3 
4 using System;
5 using System.Collections;
6 using HoloToolkit.Unity;
7 using UnityEngine;
8 
9 namespace HoloToolkit.Sharing.Utilities
10 {
14  public class AutoJoinSessionAndRoom : Singleton<AutoJoinSessionAndRoom>
15  {
19  private long roomID = 1;
20 
24  public float Timeout = 1f;
25 
26  private static bool ShouldLocalUserCreateRoom
27  {
28  get
29  {
30  if (!SharingStage.IsInitialized || SharingStage.Instance.SessionUsersTracker == null)
31  {
32  return false;
33  }
34 
35  long localUserId;
36  using (User localUser = SharingStage.Instance.Manager.GetLocalUser())
37  {
38  localUserId = localUser.GetID();
39  }
40 
41  for (int i = 0; i < SharingStage.Instance.SessionUsersTracker.CurrentUsers.Count; i++)
42  {
43  if (SharingStage.Instance.SessionUsersTracker.CurrentUsers[i].GetID() < localUserId)
44  {
45  return false;
46  }
47  }
48 
49  return true;
50  }
51  }
52 
53  private void Start()
54  {
55  // SharingStage should be valid at this point, but we may not be connected.
56  if (SharingStage.Instance.IsConnected)
57  {
58  SharingManagerConnected();
59  }
60  else
61  {
62  SessionTrackerDisconnected();
63  }
64  }
65 
66  protected override void OnDestroy()
67  {
68  if (SharingStage.Instance != null)
69  {
70  SharingStage.Instance.SharingManagerConnected -= SharingManagerConnected;
71  SharingStage.Instance.SessionsTracker.ServerDisconnected -= SessionTrackerDisconnected;
72  }
73 
74  StopCoroutine(AutoConnect());
75 
76  base.OnDestroy();
77  }
78 
84  private void SharingManagerConnected(object sender = null, EventArgs e = null)
85  {
86  SharingStage.Instance.SharingManagerConnected -= SharingManagerConnected;
87  SharingStage.Instance.SessionsTracker.ServerDisconnected += SessionTrackerDisconnected;
88  }
89 
93  private void SessionTrackerDisconnected()
94  {
95  SharingStage.Instance.SharingManagerConnected += SharingManagerConnected;
96  SharingStage.Instance.SessionsTracker.ServerDisconnected -= SessionTrackerDisconnected;
97 
98  if (SharingStage.Instance.ClientRole == ClientRole.Primary)
99  {
100  StartCoroutine(AutoConnect());
101  }
102  }
103 
104  private IEnumerator AutoConnect()
105  {
106  if (SharingStage.Instance.ShowDetailedLogs)
107  {
108  Debug.Log("[AutoJoinSessionAndRoom] Attempting to connect...");
109  }
110 
111  yield return new WaitForSeconds(Timeout);
112 
113  if (!SharingStage.Instance.SessionsTracker.IsServerConnected)
114  {
115  if (SharingStage.Instance.ShowDetailedLogs)
116  {
117  Debug.LogWarning("[AutoJoinSessionAndRoom] Disconnected from server. Waiting for a connection... ");
118  }
119 
120  while (!SharingStage.Instance.SessionsTracker.IsServerConnected)
121  {
122  yield return null;
123  }
124 
125  if (SharingStage.Instance.ShowDetailedLogs)
126  {
127  Debug.Log("[AutoJoinSessionAndRoom] Connected!");
128  }
129  }
130 
131  if (SharingStage.Instance.ShowDetailedLogs)
132  {
133  Debug.LogFormat("[AutoJoinSessionAndRoom] Looking for {0}...", SharingStage.Instance.SessionName);
134 
135  Debug.LogFormat("[AutoJoinSessionAndRoom] Successfully connected to server with {0} Sessions.",
136  SharingStage.Instance.SessionsTracker.Sessions.Count.ToString());
137  }
138 
139  yield return new WaitForEndOfFrame();
140 
141  bool sessionExists = false;
142 
143  for (int i = 0; i < SharingStage.Instance.SessionsTracker.Sessions.Count; ++i)
144  {
145  if (SharingStage.Instance.SessionsTracker.Sessions[i].GetName().GetString() == SharingStage.Instance.SessionName)
146  {
147  sessionExists = true;
148  if (SharingStage.Instance.ShowDetailedLogs)
149  {
150  Debug.LogFormat("[AutoJoinSessionAndRoom] Joining session {0}...", SharingStage.Instance.SessionName);
151  }
152 
153  yield return SharingStage.Instance.SessionsTracker.JoinSession(SharingStage.Instance.SessionsTracker.Sessions[i]);
154 
155  yield return new WaitForEndOfFrame();
156  break;
157  }
158  }
159 
160  if (!sessionExists)
161  {
162  if (SharingStage.Instance.ShowDetailedLogs)
163  {
164  Debug.LogFormat("[AutoJoinSessionAndRoom] Didn't find session {0}, making a new one...", SharingStage.Instance.SessionName);
165  }
166 
167  if (!SharingStage.Instance.SessionsTracker.CreateSession(SharingStage.Instance.SessionName))
168  {
169  yield break;
170  }
171 
172  yield return new WaitForEndOfFrame();
173 
174  while (SharingStage.Instance.SessionsTracker.GetCurrentSession() == null)
175  {
176  yield return null;
177  }
178  }
179 
180  while (SharingStage.Instance.SessionsTracker.GetCurrentSession().GetMachineSessionState() != MachineSessionState.JOINED)
181  {
182  yield return null;
183  }
184 
185  if (SharingStage.Instance.ShowDetailedLogs)
186  {
187  Debug.LogFormat("[AutoJoinSessionAndRoom] Joined session {0} successfully!", SharingStage.Instance.SessionName);
188  }
189 
190  yield return new WaitForEndOfFrame();
191 
192  if (SharingStage.Instance.CurrentRoomManager.GetRoomCount() == 0)
193  {
194  // If we are the user with the lowest user ID, we will create the room.
195  if (ShouldLocalUserCreateRoom)
196  {
197  if (SharingStage.Instance.ShowDetailedLogs)
198  {
199  Debug.LogFormat("[AutoJoinSessionAndRoom] Creating room {0}...", SharingStage.Instance.RoomName);
200  }
201 
202  // To keep anchors alive even if all users have left the session...
203  // Pass in true instead of false in CreateRoom.
204  SharingStage.Instance.CurrentRoomManager.CreateRoom(
205  new XString(SharingStage.Instance.RoomName),
206  roomID,
207  SharingStage.Instance.KeepRoomAlive);
208  }
209  }
210  else if (SharingStage.Instance.CurrentRoomManager.GetRoomCount() > 0)
211  {
212  if (SharingStage.Instance.CurrentRoom != null)
213  {
214  SharingStage.Instance.CurrentRoomManager.LeaveRoom();
215  }
216 
217  yield return new WaitForEndOfFrame();
218 
219  // Look through the existing rooms and join the one that matches the room name provided.
220  for (int i = 0; i < SharingStage.Instance.CurrentRoomManager.GetRoomCount(); i++)
221  {
222  if (SharingStage.Instance.CurrentRoomManager.GetRoom(i).GetName().GetString().Equals(SharingStage.Instance.RoomName, StringComparison.OrdinalIgnoreCase))
223  {
224  SharingStage.Instance.CurrentRoomManager.JoinRoom(SharingStage.Instance.CurrentRoomManager.GetRoom(i));
225 
226  if (SharingStage.Instance.ShowDetailedLogs)
227  {
228  Debug.LogFormat("[AutoJoinSessionAndRoom] Joining room {0}...", SharingStage.Instance.CurrentRoomManager.GetRoom(i).GetName().GetString());
229  }
230 
231  break;
232  }
233  }
234  }
235 
236  while (SharingStage.Instance.CurrentRoom == null)
237  {
238  yield return null;
239  }
240 
241  if (SharingStage.Instance.ShowDetailedLogs)
242  {
243  Debug.LogFormat("[AutoJoinSessionAndRoom] Joined room {0} successfully!", SharingStage.Instance.CurrentRoom.GetName().GetString());
244  }
245 
246  yield return new WaitForEndOfFrame();
247 
248  SharingWorldAnchorManager.Instance.AttachAnchor(gameObject);
249  }
250  }
251 }
virtual int GetID()
Definition: User.cs:49
Wrapper around world anchor store to streamline some of the persistence API busy work.
Utility class for automatically joining shared sessions without needing to go through a lobby...
static T Instance
Returns the Singleton instance of the classes type. If no instance is found, then we search for an in...
Definition: Singleton.cs:26
override void OnDestroy()
Base OnDestroy method that destroys the Singleton&#39;s unique instance. Called by Unity when destroying ...
The SharingStage is in charge of managing the core networking layer for the application.
Definition: SharingStage.cs:14
static bool IsInitialized
Returns whether the instance has been initialized or not.
Definition: Singleton.cs:58
Singleton behaviour class, used for components that should only have one instance.
Definition: Singleton.cs:14