AR Design
UBC EML collab with UBC SALA - visualizing IoT data in AR
CustomMessages.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.Generic;
6 using HoloToolkit.Unity;
7 using UnityEngine;
8 
9 namespace HoloToolkit.Sharing.Tests
10 {
14  public class CustomMessages : Singleton<CustomMessages>
15  {
21  public enum TestMessageID : byte
22  {
23  HeadTransform = MessageID.UserMessageIDStart,
24  Max
25  }
26 
27  public enum UserMessageChannels
28  {
29  Anchors = MessageChannel.UserMessageChannelStart
30  }
31 
35  public long LocalUserID
36  {
37  get; set;
38  }
39 
40  public delegate void MessageCallback(NetworkInMessage msg);
41  private Dictionary<TestMessageID, MessageCallback> messageHandlers = new Dictionary<TestMessageID, MessageCallback>();
42  public Dictionary<TestMessageID, MessageCallback> MessageHandlers
43  {
44  get
45  {
46  return messageHandlers;
47  }
48  }
49 
54  private NetworkConnectionAdapter connectionAdapter;
55 
59  private NetworkConnection serverConnection;
60 
61  private void Start()
62  {
63  // SharingStage should be valid at this point, but we may not be connected.
64  if (SharingStage.Instance.IsConnected)
65  {
66  Connected();
67  }
68  else
69  {
70  SharingStage.Instance.SharingManagerConnected += Connected;
71  }
72  }
73 
74  private void Connected(object sender = null, EventArgs e = null)
75  {
76  SharingStage.Instance.SharingManagerConnected -= Connected;
77  InitializeMessageHandlers();
78  }
79 
80  private void InitializeMessageHandlers()
81  {
82  SharingStage sharingStage = SharingStage.Instance;
83 
84  if (sharingStage == null)
85  {
86  Debug.Log("Cannot Initialize CustomMessages. No SharingStage instance found.");
87  return;
88  }
89 
90  serverConnection = sharingStage.Manager.GetServerConnection();
91  if (serverConnection == null)
92  {
93  Debug.Log("Cannot initialize CustomMessages. Cannot get a server connection.");
94  return;
95  }
96 
97  connectionAdapter = new NetworkConnectionAdapter();
98  connectionAdapter.MessageReceivedCallback += OnMessageReceived;
99 
100  // Cache the local user ID
101  LocalUserID = SharingStage.Instance.Manager.GetLocalUser().GetID();
102 
103  for (byte index = (byte)TestMessageID.HeadTransform; index < (byte)TestMessageID.Max; index++)
104  {
105  if (MessageHandlers.ContainsKey((TestMessageID)index) == false)
106  {
107  MessageHandlers.Add((TestMessageID)index, null);
108  }
109 
110  serverConnection.AddListener(index, connectionAdapter);
111  }
112  }
113 
114  private NetworkOutMessage CreateMessage(byte messageType)
115  {
116  NetworkOutMessage msg = serverConnection.CreateMessage(messageType);
117  msg.Write(messageType);
118  // Add the local userID so that the remote clients know whose message they are receiving
119  msg.Write(LocalUserID);
120  return msg;
121  }
122 
123  public void SendHeadTransform(Vector3 position, Quaternion rotation)
124  {
125  // If we are connected to a session, broadcast our head info
126  if (serverConnection != null && serverConnection.IsConnected())
127  {
128  // Create an outgoing network message to contain all the info we want to send
129  NetworkOutMessage msg = CreateMessage((byte)TestMessageID.HeadTransform);
130 
131  AppendTransform(msg, position, rotation);
132 
133  // Send the message as a broadcast, which will cause the server to forward it to all other users in the session.
134  serverConnection.Broadcast(
135  msg,
136  MessagePriority.Immediate,
137  MessageReliability.UnreliableSequenced,
138  MessageChannel.Avatar);
139  }
140  }
141 
142  protected override void OnDestroy()
143  {
144  base.OnDestroy();
145 
146  if (serverConnection != null)
147  {
148  for (byte index = (byte)TestMessageID.HeadTransform; index < (byte)TestMessageID.Max; index++)
149  {
150  serverConnection.RemoveListener(index, connectionAdapter);
151  }
152  connectionAdapter.MessageReceivedCallback -= OnMessageReceived;
153  }
154  }
155 
156  private void OnMessageReceived(NetworkConnection connection, NetworkInMessage msg)
157  {
158  byte messageType = msg.ReadByte();
159  MessageCallback messageHandler = MessageHandlers[(TestMessageID)messageType];
160  if (messageHandler != null)
161  {
162  messageHandler(msg);
163  }
164  }
165 
166  #region HelperFunctionsForWriting
167 
168  private void AppendTransform(NetworkOutMessage msg, Vector3 position, Quaternion rotation)
169  {
170  AppendVector3(msg, position);
171  AppendQuaternion(msg, rotation);
172  }
173 
174  private void AppendVector3(NetworkOutMessage msg, Vector3 vector)
175  {
176  msg.Write(vector.x);
177  msg.Write(vector.y);
178  msg.Write(vector.z);
179  }
180 
181  private void AppendQuaternion(NetworkOutMessage msg, Quaternion rotation)
182  {
183  msg.Write(rotation.x);
184  msg.Write(rotation.y);
185  msg.Write(rotation.z);
186  msg.Write(rotation.w);
187  }
188 
189  #endregion
190 
191  #region HelperFunctionsForReading
192 
193  public Vector3 ReadVector3(NetworkInMessage msg)
194  {
195  return new Vector3(msg.ReadFloat(), msg.ReadFloat(), msg.ReadFloat());
196  }
197 
198  public Quaternion ReadQuaternion(NetworkInMessage msg)
199  {
200  return new Quaternion(msg.ReadFloat(), msg.ReadFloat(), msg.ReadFloat(), msg.ReadFloat());
201  }
202 
203  #endregion
204  }
205 }
virtual NetworkConnection GetServerConnection()
virtual void RemoveListener(byte messageType, NetworkConnectionListener oldListener)
void SendHeadTransform(Vector3 position, Quaternion rotation)
override void OnDestroy()
Base OnDestroy method that destroys the Singleton&#39;s unique instance. Called by Unity when destroying ...
TestMessageID
Message enum containing our information bytes to share. The first message type has to start with User...
virtual void Broadcast(NetworkOutMessage msg, MessagePriority priority, MessageReliability reliability, MessageChannel channel, bool releaseMessage)
virtual NetworkOutMessage CreateMessage(byte messageType)
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
Test class for demonstrating how to send custom messages between clients.
Vector3 ReadVector3(NetworkInMessage msg)
Allows users of NetworkConnection to register to receive event callbacks without having their classes...
SharingManager Manager
Sharing manager used by the application.
Definition: SharingStage.cs:97
Quaternion ReadQuaternion(NetworkInMessage msg)
The SharingStage is in charge of managing the core networking layer for the application.
Definition: SharingStage.cs:14
System.Action< NetworkConnection, NetworkInMessage > MessageReceivedCallback
virtual void AddListener(byte messageType, NetworkConnectionListener newListener)
Singleton behaviour class, used for components that should only have one instance.
Definition: Singleton.cs:14