AR Design
UBC EML collab with UBC SALA - visualizing IoT data in AR
ImportExportAnchorManager.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 UnityEngine;
7 using HoloToolkit.Unity;
8 
9 #if UNITY_WSA && !UNITY_EDITOR
10 using System.Collections.Generic;
11 #if UNITY_2017_2_OR_NEWER
12 using UnityEngine.XR.WSA;
13 using UnityEngine.XR.WSA.Persistence;
14 using UnityEngine.XR.WSA.Sharing;
15 #else
16 using UnityEngine.VR.WSA;
17 using UnityEngine.VR.WSA.Persistence;
18 using UnityEngine.VR.WSA.Sharing;
19 #endif
20 #endif
21 
22 namespace HoloToolkit.Sharing.Tests
23 {
27  public class ImportExportAnchorManager : Singleton<ImportExportAnchorManager>
28  {
32  private enum ImportExportState
33  {
34  // Overall states
35  Start,
36  Failed,
37  Ready,
38  RoomApiInitializing,
39  RoomApiInitialized,
40  AnchorEstablished,
41  // AnchorStore states
42  AnchorStore_Initializing,
43  // Anchor creation values
44  InitialAnchorRequired,
45  CreatingInitialAnchor,
46  ReadyToExportInitialAnchor,
47  UploadingInitialAnchor,
48  // Anchor values
49  DataRequested,
50  DataReady,
51  Importing
52  }
53 
54  private ImportExportState currentState = ImportExportState.Start;
55 
56  public string StateName
57  {
58  get
59  {
60  return currentState.ToString();
61  }
62  }
63 
64  public bool AnchorEstablished
65  {
66  get
67  {
68  return currentState == ImportExportState.AnchorEstablished;
69  }
70  }
71 
75  public long RoomID
76  {
77  get
78  {
79  return roomID;
80  }
81 
82  set
83  {
84  if (currentRoom == null)
85  {
86  roomID = value;
87  }
88  }
89  }
90 
91  private static bool ShouldLocalUserCreateRoom
92  {
93  get
94  {
95  if (SharingStage.Instance == null || SharingStage.Instance.SessionUsersTracker == null)
96  {
97  return false;
98  }
99 
100  long localUserId;
101  using (User localUser = SharingStage.Instance.Manager.GetLocalUser())
102  {
103  localUserId = localUser.GetID();
104  }
105 
106  for (int i = 0; i < SharingStage.Instance.SessionUsersTracker.CurrentUsers.Count; i++)
107  {
108  if (SharingStage.Instance.SessionUsersTracker.CurrentUsers[i].GetID() < localUserId)
109  {
110  return false;
111  }
112  }
113 
114  return true;
115  }
116  }
117 
121  public event Action<bool> AnchorUploaded;
122 
123 #if UNITY_WSA && !UNITY_EDITOR
124 
128  public event Action AnchorLoaded;
129 
134  private WorldAnchorTransferBatch sharedAnchorInterface;
135 
140  private WorldAnchorStore anchorStore;
141 
145  private string exportingAnchorName;
146 
150  private List<byte> exportingAnchorBytes = new List<byte>();
151 
156  private const uint MinTrustworthySerializedAnchorDataSize = 100000;
157 
158 #endif
159 
163  private byte[] rawAnchorData;
164 
170  private bool sharingServiceReady;
171 
175  private RoomManager roomManager;
176 
181  private Room currentRoom;
182 
186  private long roomID = 8675309;
187 
191  public bool KeepRoomAlive;
192 
196  public string RoomName = "DefaultRoom";
197 
201  public TextMesh AnchorDebugText;
202 
206  private RoomManagerAdapter roomManagerListener;
207 
208  #region Unity APIs
209 
210  protected override void Awake()
211  {
212  base.Awake();
213 
214 #if UNITY_WSA && !UNITY_EDITOR
215  // We need to get our local anchor store started up.
216  currentState = ImportExportState.AnchorStore_Initializing;
217  WorldAnchorStore.GetAsync(AnchorStoreReady);
218 #else
219  currentState = ImportExportState.Ready;
220 #endif
221  }
222 
223  private void Start()
224  {
225  // SharingStage should be valid at this point, but we may not be connected.
226  if (SharingStage.Instance.IsConnected)
227  {
228  Connected();
229  }
230  else
231  {
232  SharingStage.Instance.SharingManagerConnected += Connected;
233  }
234  }
235 
236  private void Update()
237  {
238  switch (currentState)
239  {
240  // If the local anchor store is initialized.
241  case ImportExportState.Ready:
242  if (sharingServiceReady)
243  {
244  StartCoroutine(InitRoomApi());
245  }
246  break;
247  case ImportExportState.RoomApiInitialized:
248  StartAnchorProcess();
249  break;
250 #if UNITY_WSA && !UNITY_EDITOR
251  case ImportExportState.DataReady:
252  // DataReady is set when the anchor download completes.
253  currentState = ImportExportState.Importing;
254  WorldAnchorTransferBatch.ImportAsync(rawAnchorData, ImportComplete);
255  break;
256  case ImportExportState.InitialAnchorRequired:
257  currentState = ImportExportState.CreatingInitialAnchor;
258  CreateAnchorLocally();
259  break;
260  case ImportExportState.ReadyToExportInitialAnchor:
261  // We've created an anchor locally and it is ready to export.
262  currentState = ImportExportState.UploadingInitialAnchor;
263  Export();
264  break;
265 #endif
266  }
267  }
268 
269  protected override void OnDestroy()
270  {
271  if (SharingStage.Instance != null)
272  {
273  if (SharingStage.Instance.SessionsTracker != null)
274  {
275  SharingStage.Instance.SessionsTracker.CurrentUserJoined -= CurrentUserJoinedSession;
276  SharingStage.Instance.SessionsTracker.CurrentUserLeft -= CurrentUserLeftSession;
277  }
278  }
279 
280  if (roomManagerListener != null)
281  {
282  roomManagerListener.AnchorsChangedEvent -= RoomManagerCallbacks_AnchorsChanged;
283  roomManagerListener.AnchorsDownloadedEvent -= RoomManagerListener_AnchorsDownloaded;
284  roomManagerListener.AnchorUploadedEvent -= RoomManagerListener_AnchorUploaded;
285 
286  if (roomManager != null)
287  {
288  roomManager.RemoveListener(roomManagerListener);
289  }
290 
291  roomManagerListener.Dispose();
292  roomManagerListener = null;
293  }
294 
295  if (roomManager != null)
296  {
297  roomManager.Dispose();
298  roomManager = null;
299  }
300 
301  base.OnDestroy();
302  }
303 
304  #endregion
305 
306  #region Event Callbacks
307 
313  private void Connected(object sender = null, EventArgs e = null)
314  {
315  SharingStage.Instance.SharingManagerConnected -= Connected;
316 
317  if (SharingStage.Instance.ShowDetailedLogs)
318  {
319  Debug.Log("Anchor Manager: Starting...");
320  }
321 
322  if (AnchorDebugText != null)
323  {
324  AnchorDebugText.text += "\nConnected to Server";
325  }
326 
327  // Setup the room manager callbacks.
328  roomManager = SharingStage.Instance.Manager.GetRoomManager();
329  roomManagerListener = new RoomManagerAdapter();
330 
331  roomManagerListener.AnchorsChangedEvent += RoomManagerCallbacks_AnchorsChanged;
332  roomManagerListener.AnchorsDownloadedEvent += RoomManagerListener_AnchorsDownloaded;
333  roomManagerListener.AnchorUploadedEvent += RoomManagerListener_AnchorUploaded;
334 
335  roomManager.AddListener(roomManagerListener);
336 
337  // We will register for session joined and left to indicate when the sharing service
338  // is ready for us to make room related requests.
339  SharingStage.Instance.SessionsTracker.CurrentUserJoined += CurrentUserJoinedSession;
340  SharingStage.Instance.SessionsTracker.CurrentUserLeft += CurrentUserLeftSession;
341  }
342 
346  private void RoomManagerListener_AnchorUploaded(bool successful, XString failureReason)
347  {
348  if (successful)
349  {
350 
351  if (SharingStage.Instance.ShowDetailedLogs)
352  {
353  Debug.Log("Anchor Manager: Successfully uploaded anchor");
354  }
355 
356  if (AnchorDebugText != null)
357  {
358  AnchorDebugText.text += "\nSuccessfully uploaded anchor";
359  }
360 
361  currentState = ImportExportState.AnchorEstablished;
362  }
363  else
364  {
365  if (AnchorDebugText != null)
366  {
367  AnchorDebugText.text += string.Format("\n Upload failed " + failureReason);
368  }
369 
370  Debug.LogError("Anchor Manager: Upload failed " + failureReason);
371  currentState = ImportExportState.Failed;
372  }
373 
374  if (AnchorUploaded != null)
375  {
376  AnchorUploaded(successful);
377  }
378  }
379 
383  private void RoomManagerListener_AnchorsDownloaded(bool successful, AnchorDownloadRequest request, XString failureReason)
384  {
385  // If we downloaded anchor data successfully we should import the data.
386  if (successful)
387  {
388  int dataSize = request.GetDataSize();
389 
390  if (SharingStage.Instance.ShowDetailedLogs)
391  {
392  Debug.LogFormat("Anchor Manager: Anchor size: {0} bytes.", dataSize.ToString());
393  }
394 
395  if (AnchorDebugText != null)
396  {
397  AnchorDebugText.text += string.Format("\nAnchor size: {0} bytes.", dataSize.ToString());
398  }
399 
400  rawAnchorData = new byte[dataSize];
401 
402  request.GetData(rawAnchorData, dataSize);
403  currentState = ImportExportState.DataReady;
404  }
405  else
406  {
407  if (AnchorDebugText != null)
408  {
409  AnchorDebugText.text += string.Format("\nAnchor DL failed " + failureReason);
410  }
411 
412  // If we failed, we can ask for the data again.
413  Debug.LogWarning("Anchor Manager: Anchor DL failed " + failureReason);
414 #if UNITY_WSA && !UNITY_EDITOR
415  MakeAnchorDataRequest();
416 #endif
417  }
418  }
419 
424  private void RoomManagerCallbacks_AnchorsChanged(Room room)
425  {
426  if (SharingStage.Instance.ShowDetailedLogs)
427  {
428  Debug.LogFormat("Anchor Manager: Anchors in room {0} changed", room.GetName());
429  }
430 
431  if (AnchorDebugText != null)
432  {
433  AnchorDebugText.text += string.Format("\nAnchors in room {0} changed", room.GetName());
434  }
435 
436  // if we're currently in the room where the anchors changed
437  if (currentRoom == room)
438  {
439  ResetState();
440  }
441  }
442 
448  private void CurrentUserJoinedSession(Session session)
449  {
450  if (SharingStage.Instance.Manager.GetLocalUser().IsValid())
451  {
452  sharingServiceReady = true;
453  }
454  else
455  {
456  Debug.LogWarning("Unable to get local user on session joined");
457  }
458  }
459 
465  private void CurrentUserLeftSession(Session session)
466  {
467  sharingServiceReady = false;
468 
469  // Reset the state so that we join a new room when we eventually rejoin a session
470  ResetState();
471  }
472 
473  #endregion
474 
478  private void ResetState()
479  {
480 #if UNITY_WSA && !UNITY_EDITOR
481  if (anchorStore != null)
482  {
483  currentState = ImportExportState.Ready;
484  }
485  else
486  {
487  currentState = ImportExportState.AnchorStore_Initializing;
488  }
489 #else
490  currentState = ImportExportState.Ready;
491 #endif
492  }
493 
497  private IEnumerator InitRoomApi()
498  {
499  currentState = ImportExportState.RoomApiInitializing;
500  // First check if there is a current room
501  currentRoom = roomManager.GetCurrentRoom();
502 
503  while (currentRoom == null)
504  {
505  // If we have a room, we'll join the first room we see.
506  // If we are the user with the lowest user ID, we will create the room.
507  // Otherwise we will wait for the room to be created.
508  yield return new WaitForEndOfFrame();
509  if (roomManager.GetRoomCount() == 0)
510  {
511  if (ShouldLocalUserCreateRoom)
512  {
513  if (SharingStage.Instance.ShowDetailedLogs)
514  {
515  Debug.Log("Anchor Manager: Creating room " + RoomName);
516  }
517 
518  if (AnchorDebugText != null)
519  {
520  AnchorDebugText.text += string.Format("\nCreating room " + RoomName);
521  }
522 
523  // To keep anchors alive even if all users have left the session ...
524  // Pass in true instead of false in CreateRoom.
525  currentRoom = roomManager.CreateRoom(new XString(RoomName), roomID, KeepRoomAlive);
526  }
527  }
528  else
529  {
530  // Look through the existing rooms and join the one that matches the room name provided.
531  int roomCount = roomManager.GetRoomCount();
532  for (int i = 0; i < roomCount; i++)
533  {
534  Room room = roomManager.GetRoom(i);
535  if (room.GetName().GetString().Equals(RoomName, StringComparison.OrdinalIgnoreCase))
536  {
537  currentRoom = room;
538  roomManager.JoinRoom(currentRoom);
539 
540  if (SharingStage.Instance.ShowDetailedLogs)
541  {
542  Debug.Log("Anchor Manager: Joining room " + room.GetName().GetString());
543  }
544 
545  if (AnchorDebugText != null)
546  {
547  AnchorDebugText.text += string.Format("\nJoining room " + room.GetName().GetString());
548  }
549 
550  break;
551  }
552  }
553 
554  if (currentRoom == null)
555  {
556  // Couldn't locate a matching room, just join the first one.
557  currentRoom = roomManager.GetRoom(0);
558  roomManager.JoinRoom(currentRoom);
559  RoomName = currentRoom.GetName().GetString();
560  }
561 
562  currentState = ImportExportState.RoomApiInitialized;
563  }
564 
565  yield return new WaitForEndOfFrame();
566  }
567 
568  if (currentRoom.GetAnchorCount() == 0)
569  {
570 #if UNITY_WSA && !UNITY_EDITOR
571  // If the room has no anchors, request the initial anchor
572  currentState = ImportExportState.InitialAnchorRequired;
573 #else
574  currentState = ImportExportState.RoomApiInitialized;
575 #endif
576  }
577  else
578  {
579  // Room already has anchors
580  currentState = ImportExportState.RoomApiInitialized;
581  }
582 
583  if (SharingStage.Instance.ShowDetailedLogs)
584  {
585  Debug.LogFormat("Anchor Manager: In room {0} with ID {1}",
586  roomManager.GetCurrentRoom().GetName().GetString(),
587  roomManager.GetCurrentRoom().GetID().ToString());
588  }
589 
590  if (AnchorDebugText != null)
591  {
592  AnchorDebugText.text += string.Format("\nIn room {0} with ID {1}",
593  roomManager.GetCurrentRoom().GetName().GetString(),
594  roomManager.GetCurrentRoom().GetID().ToString());
595  }
596 
597  yield return null;
598  }
599 
603  private void StartAnchorProcess()
604  {
605  // First, are there any anchors in this room?
606  int anchorCount = currentRoom.GetAnchorCount();
607 
608  if (SharingStage.Instance.ShowDetailedLogs)
609  {
610  Debug.LogFormat("Anchor Manager: {0} anchors found.", anchorCount.ToString());
611  }
612 
613  if (AnchorDebugText != null)
614  {
615  AnchorDebugText.text += string.Format("\n{0} anchors found.", anchorCount.ToString());
616  }
617 
618 #if UNITY_WSA && !UNITY_EDITOR
619 
620  // If there are anchors, we should attach to the first one.
621  if (anchorCount > 0)
622  {
623  // Extract the name of the anchor.
624  XString storedAnchorString = currentRoom.GetAnchorName(0);
625  string storedAnchorName = storedAnchorString.GetString();
626 
627  // Attempt to attach to the anchor in our local anchor store.
628  if (AttachToCachedAnchor(storedAnchorName) == false)
629  {
630  if (SharingStage.Instance.ShowDetailedLogs)
631  {
632  Debug.Log("Anchor Manager: Starting room anchor download of " + storedAnchorString);
633  }
634 
635  if (AnchorDebugText != null)
636  {
637  AnchorDebugText.text += string.Format("\nStarting room anchor download of " + storedAnchorString);
638  }
639 
640  // If we cannot find the anchor by name, we will need the full data blob.
641  MakeAnchorDataRequest();
642  }
643  }
644 
645 #else
646 
647  currentState = ImportExportState.AnchorEstablished;
648 
649  if (AnchorDebugText != null)
650  {
651  AnchorDebugText.text += anchorCount > 0 ? "\n" + currentRoom.GetAnchorName(0).ToString() : "\nNo Anchors Found";
652  }
653 
654 #endif
655  }
656 
657  #region WSA Specific Methods
658 
659 #if UNITY_WSA && !UNITY_EDITOR
660 
665  private void MakeAnchorDataRequest()
666  {
667  if (roomManager.DownloadAnchor(currentRoom, currentRoom.GetAnchorName(0)))
668  {
669  currentState = ImportExportState.DataRequested;
670  }
671  else
672  {
673  Debug.LogError("Anchor Manager: Couldn't make the download request.");
674 
675  if (AnchorDebugText != null)
676  {
677  AnchorDebugText.text += string.Format("\nCouldn't make the download request.");
678  }
679 
680  currentState = ImportExportState.Failed;
681  }
682  }
683 
688  private void AnchorStoreReady(WorldAnchorStore store)
689  {
690  anchorStore = store;
691 
692  if (!KeepRoomAlive)
693  {
694  anchorStore.Clear();
695  }
696 
697  currentState = ImportExportState.Ready;
698  }
699 
703  private void CreateAnchorLocally()
704  {
705  WorldAnchor anchor = this.EnsureComponent<WorldAnchor>();
706  if (anchor.isLocated)
707  {
708  currentState = ImportExportState.ReadyToExportInitialAnchor;
709  }
710  else
711  {
712  anchor.OnTrackingChanged += Anchor_OnTrackingChanged_InitialAnchor;
713  }
714  }
715 
719  private void Anchor_OnTrackingChanged_InitialAnchor(WorldAnchor self, bool located)
720  {
721  if (located)
722  {
723  if (SharingStage.Instance.ShowDetailedLogs)
724  {
725  Debug.Log("Anchor Manager: Found anchor, ready to export");
726  }
727 
728  if (AnchorDebugText != null)
729  {
730  AnchorDebugText.text += string.Format("\nFound anchor, ready to export");
731  }
732 
733  currentState = ImportExportState.ReadyToExportInitialAnchor;
734  }
735  else
736  {
737  Debug.LogError("Anchor Manager: Failed to locate local anchor!");
738 
739  if (AnchorDebugText != null)
740  {
741  AnchorDebugText.text += string.Format("\nFailed to locate local anchor!");
742  }
743 
744  currentState = ImportExportState.Failed;
745  }
746 
747  self.OnTrackingChanged -= Anchor_OnTrackingChanged_InitialAnchor;
748  }
749 
754  private bool AttachToCachedAnchor(string anchorName)
755  {
756  if (SharingStage.Instance.ShowDetailedLogs)
757  {
758  Debug.LogFormat("Anchor Manager: Looking for cached anchor {0}...", anchorName);
759  }
760 
761  if (AnchorDebugText != null)
762  {
763  AnchorDebugText.text += string.Format("\nLooking for cached anchor {0}...", anchorName);
764  }
765 
766  string[] ids = anchorStore.GetAllIds();
767  for (int index = 0; index < ids.Length; index++)
768  {
769  if (ids[index] == anchorName)
770  {
771  if (SharingStage.Instance.ShowDetailedLogs)
772  {
773  Debug.LogFormat("Anchor Manager: Attempting to load cached anchor {0}...", anchorName);
774  }
775 
776  if (AnchorDebugText != null)
777  {
778  AnchorDebugText.text += string.Format("\nAttempting to load cached anchor {0}...", anchorName);
779  }
780 
781  WorldAnchor anchor = anchorStore.Load(ids[index], gameObject);
782 
783  if (anchor.isLocated)
784  {
785  AnchorLoadComplete();
786  }
787  else
788  {
789  if (AnchorDebugText != null)
790  {
791  AnchorDebugText.text += "\n"+anchorName;
792  }
793 
794  anchor.OnTrackingChanged += ImportExportAnchorManager_OnTrackingChanged_Attaching;
795  currentState = ImportExportState.AnchorEstablished;
796  }
797  return true;
798  }
799  }
800 
801  // Didn't find the anchor, so we'll download from room.
802  return false;
803  }
804 
810  private void ImportExportAnchorManager_OnTrackingChanged_Attaching(WorldAnchor self, bool located)
811  {
812  if (located)
813  {
814  AnchorLoadComplete();
815  }
816  else
817  {
818  Debug.LogWarning("Anchor Manager: Failed to find local anchor from cache.");
819 
820  if (AnchorDebugText != null)
821  {
822  AnchorDebugText.text += string.Format("\nFailed to find local anchor from cache.");
823  }
824 
825  MakeAnchorDataRequest();
826  }
827 
828  self.OnTrackingChanged -= ImportExportAnchorManager_OnTrackingChanged_Attaching;
829  }
830 
836  private void ImportComplete(SerializationCompletionReason status, WorldAnchorTransferBatch anchorBatch)
837  {
838  if (status == SerializationCompletionReason.Succeeded)
839  {
840  if (anchorBatch.GetAllIds().Length > 0)
841  {
842  string first = anchorBatch.GetAllIds()[0];
843 
844  if (SharingStage.Instance.ShowDetailedLogs)
845  {
846  Debug.Log("Anchor Manager: Successfully imported anchor " + first);
847  }
848 
849  if (AnchorDebugText != null)
850  {
851  AnchorDebugText.text += string.Format("\nSuccessfully imported anchor " + first);
852  }
853 
854  WorldAnchor anchor = anchorBatch.LockObject(first, gameObject);
855  anchorStore.Save(first, anchor);
856  }
857 
858  AnchorLoadComplete();
859  }
860  else
861  {
862  Debug.LogError("Anchor Manager: Import failed");
863 
864  if (AnchorDebugText != null)
865  {
866  AnchorDebugText.text += string.Format("\nImport failed");
867  }
868 
869  currentState = ImportExportState.DataReady;
870  }
871  }
872 
873  private void AnchorLoadComplete()
874  {
875  if (AnchorLoaded != null)
876  {
877  AnchorLoaded();
878  }
879 
880  currentState = ImportExportState.AnchorEstablished;
881  }
882 
886  private void Export()
887  {
888  WorldAnchor anchor = this.GetComponent<WorldAnchor>();
889  string guidString = Guid.NewGuid().ToString();
890  exportingAnchorName = guidString;
891 
892  // Save the anchor to our local anchor store.
893  if (anchor != null && anchorStore.Save(exportingAnchorName, anchor))
894  {
895  if (SharingStage.Instance.ShowDetailedLogs)
896  {
897  Debug.Log("Anchor Manager: Exporting anchor " + exportingAnchorName);
898  }
899 
900  if (AnchorDebugText != null)
901  {
902  AnchorDebugText.text += string.Format("\nExporting anchor {0}", exportingAnchorName);
903  }
904 
905  sharedAnchorInterface = new WorldAnchorTransferBatch();
906  sharedAnchorInterface.AddWorldAnchor(guidString, anchor);
907  WorldAnchorTransferBatch.ExportAsync(sharedAnchorInterface, WriteBuffer, ExportComplete);
908  }
909  else
910  {
911  Debug.LogWarning("Anchor Manager: Failed to export anchor, trying again...");
912 
913  if (AnchorDebugText != null)
914  {
915  AnchorDebugText.text += string.Format("\nFailed to export anchor, trying again...");
916  }
917 
918  currentState = ImportExportState.InitialAnchorRequired;
919  }
920  }
921 
926  private void WriteBuffer(byte[] data)
927  {
928  exportingAnchorBytes.AddRange(data);
929  }
930 
935  private void ExportComplete(SerializationCompletionReason status)
936  {
937  if (status == SerializationCompletionReason.Succeeded && exportingAnchorBytes.Count > MinTrustworthySerializedAnchorDataSize)
938  {
939  if (SharingStage.Instance.ShowDetailedLogs)
940  {
941  Debug.Log("Anchor Manager: Uploading anchor: " + exportingAnchorName);
942  }
943 
944  if (AnchorDebugText != null)
945  {
946  AnchorDebugText.text += string.Format("\nUploading anchor: " + exportingAnchorName);
947  }
948 
949  roomManager.UploadAnchor(
950  currentRoom,
951  new XString(exportingAnchorName),
952  exportingAnchorBytes.ToArray(),
953  exportingAnchorBytes.Count);
954  }
955  else
956  {
957  Debug.LogWarning("Anchor Manager: Failed to upload anchor, trying again...");
958 
959  if (AnchorDebugText != null)
960  {
961  AnchorDebugText.text += string.Format("\nFailed to upload anchor, trying again...");
962  }
963 
964  currentState = ImportExportState.InitialAnchorRequired;
965  }
966  }
967 
968 #endif // UNITY_WSA
969  #endregion // WSA Specific Methods
970  }
971 }
virtual Room CreateRoom(XString roomName, long roomID, bool keepOpenWhenEmpty)
Definition: RoomManager.cs:68
TextMesh AnchorDebugText
Debug text for displaying information.
Manages creating anchors and sharing the anchors with other clients.
System.Action< bool, AnchorDownloadRequest, XString > AnchorsDownloadedEvent
virtual bool UploadAnchor(Room room, XString anchorName, byte[] data, int dataSize)
Definition: RoomManager.cs:89
virtual int GetID()
Definition: User.cs:49
System.Action< bool, XString > AnchorUploadedEvent
Action< bool > AnchorUploaded
Called once the anchor has fully uploaded
virtual void AddListener(RoomManagerListener newListener)
Definition: RoomManager.cs:43
virtual XString GetAnchorName(int index)
Definition: Room.cs:78
override void Awake()
Base Awake method that sets the Singleton&#39;s unique instance. Called by Unity when initializing a Mono...
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 ...
virtual bool JoinRoom(Room room)
Definition: RoomManager.cs:74
virtual bool DownloadAnchor(Room room, XString anchorName)
Definition: RoomManager.cs:84
virtual Room GetRoom(int index)
Definition: RoomManager.cs:56
virtual XString GetName()
Definition: Room.cs:43
virtual long GetID()
Definition: Room.cs:49
Allows users of the RoomManager to register to receive event callbacks without having their classes i...
bool KeepRoomAlive
Indicates if the room should kept around even after all users leave
virtual int GetAnchorCount()
Definition: Room.cs:73
The SharingStage is in charge of managing the core networking layer for the application.
Definition: SharingStage.cs:14
virtual void RemoveListener(RoomManagerListener oldListener)
Definition: RoomManager.cs:47
virtual bool GetData(byte[] data, int dataSize)
override string ToString()
Definition: XString.cs:43
Singleton behaviour class, used for components that should only have one instance.
Definition: Singleton.cs:14