From 8f7441ec164bfdda580cdeeeb29e001f61df073b Mon Sep 17 00:00:00 2001 From: Gersh Payzer Date: Tue, 24 Apr 2018 11:05:39 -0700 Subject: [PATCH 1/3] 1st checkin for new controls infrastructure This is the 1st checkin for the infrastructure for new controls. --- .../Source/DLLs/Win32/x64/simplewebsocket.dll | Bin 606208 -> 100864 bytes .../InteractiveCoordinatesChangedEventArgs.cs | 35 ++ ...ractiveCoordinatesChangedEventArgs.cs.meta | 13 + .../Source/Scripts/InteractiveEventType.cs | 10 + .../InteractiveMouseButtonEventArgs.cs | 33 ++ .../InteractiveMouseButtonEventArgs.cs.meta | 13 + .../Source/Scripts/InteractivityManager.cs | 166 ++++++++- .../Source/Scripts/MixerInteractive.cs | 345 +++++++++++++++++- .../Source/Scripts/MixerInteractiveHelper.cs | 3 + 9 files changed, 613 insertions(+), 5 deletions(-) create mode 100644 Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/InteractiveCoordinatesChangedEventArgs.cs create mode 100644 Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/InteractiveCoordinatesChangedEventArgs.cs.meta create mode 100644 Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/InteractiveMouseButtonEventArgs.cs create mode 100644 Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/InteractiveMouseButtonEventArgs.cs.meta diff --git a/Source/InteractiveSDK/Assets/MixerInteractive/Source/DLLs/Win32/x64/simplewebsocket.dll b/Source/InteractiveSDK/Assets/MixerInteractive/Source/DLLs/Win32/x64/simplewebsocket.dll index 32af813c52877eba9c822a29b8da6eb9694997fb..262d7bcec7dcece64c9d9868d5b5247ee0eb38be 100644 GIT binary patch literal 100864 zcmeFadwdkt`9HqNCS-xYEJ`FIn571Z#!Dbxf{U_CvM>v~5Q|Y%E~zNSdrEe>2uN@f zVLEQbs?~m~Exp*SN`+J->>QTkdp~O_}PtqmLZDbaUeO_yfP({1Bc4k6iNNgL1v-#UILb)QkTm*Wwp{g6n(8Uy17@ zM=#l&h3m|RuXyoMxnBC>!*XreY+f&x=WpLKyNYcb+oN)y&35B`y==dl_vUqpyu-F{ zx%#H}?`u1PlpmU@9UtQAl>1tA+q_S=*?LJ**VWdBTp|~Zp#g`k>q$=Agq+3-m+18q7YeBigXQkPyC86g(mHBD5j?^q?n$6%qpWxpG zp_>+jkayQV@Q3ZO?^Zu>C;wbFTjd3FZ~RW^I~e!dkc2vIx8wS$WGDZ4Kt30k#cTzq zBDogj`r|qW*OY%A^zwpgv!L`5eYKr}0-@u|c`le+Gj}$!+L+aVKft~1zMjh6bo*T> zNE{JYQf|d@<;EfR|NjRJsL_6xW60aL|J7#Oj(_Wjs!hBz|9PgWkq=y|zF*Zhs?n(q zl=o+(*;K7>@fKCr`$uIp3YSM@7VAoEGSQ@>kPd>d0T(S)i^ z&v#rSZA3Fava^m(RZG)fQzMP2^?cNNWK&wG--cWQtM4@S?B}&v)u-ndv9Vd*>)U8{ zBLV*Q;s#aoIst)Op!O1&mA%=4G*xfhv>lHN*(x5g=x=1R$3kikVAh>za?~rs;9-voh#M)hL94_Z5v1gs@~#_BQ3JIBn8E)zL}#{tu}jBOBLEQ zhpJUORsGZABU<%Ssty#_H-v}IQSQq812Fe@WocP{rDsJbzg&%$<(Efirp2lPx>^vd z-xAIUMAagetWT8mup|a{TYQd^R|Y8Jo4h3#ogO|)#3B7NWqvMc#uLyt`So4#oKw+H zyfdUI=1}!L#*iEE4%#VtmJC91+LQrVic@te1Ex3y&Sp=pf}AFsEwU}+$foqrjL17* zsCrqxszy4TbH}Lh1{3#}lMT)tailRX4E%UIRCi;|DQaPh8fkZ^kM^e6Y~!S>KLn|~-FW#`j!1JLIz7MIuV3%< z>ovK4{hec|-=aqsNU4}aj%ll<9od)`>a)RxP8&azT2d#eMNiR8`!VH7Jl zH3?BGAbmQK7k*dOQO=zF(ab4;!E>Z3P1Ukg9o2zN5Dc=3-@PLEI*vnluLkuNu{9O& z%**8L0BP!nRQj`Y+n_#;Sh7YRsN5Y!}I%-n!2Q`3#2{PtHrk2HCyqM75N0hn;aHEfRL^}E`zB|&<_nw%QrGFGNdxk#IQQEUuSLUuf;`pg0%sZiCYx&mb1lblASu%PRi5q>|` zU)3iA&ke=9jS0wrc+uxMRrf!Y`YI_$3Ni;DBb^*q@S~~Mc(1~sR;v0!XHaj$EN@fw zg8{9&HK2bI&=#}=q6%8A)16!jA!3@4i z62Tx{#?8nOnrGb}H9860FO;wP-P=Pq_#=z+bJ6eZb2EZ^cD^5!h0c0&RrkL6mvf$x zt3jfSR<&!LtXgGbe2k%0Dq~N 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 literal 606208 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

!m*XX0fDoFw-N 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 diff --git a/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/InteractiveCoordinatesChangedEventArgs.cs b/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/InteractiveCoordinatesChangedEventArgs.cs new file mode 100644 index 0000000..bcef06f --- /dev/null +++ b/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/InteractiveCoordinatesChangedEventArgs.cs @@ -0,0 +1,35 @@ +using UnityEngine; + +namespace Microsoft.Mixer +{ + public class InteractiveCoordinatesChangedEventArgs : InteractiveEventArgs + { + public string ControlID + { + get; + private set; + } + + public InteractiveParticipant Participant + { + get; + private set; + } + + public Vector3 Position + { + get; + private set; + } + + internal InteractiveCoordinatesChangedEventArgs( + string id, + InteractiveParticipant participant, + Vector3 position) : base(InteractiveEventType.Coordinates) + { + ControlID = id; + Participant = participant; + Position = position; + } + } +} \ No newline at end of file diff --git a/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/InteractiveCoordinatesChangedEventArgs.cs.meta b/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/InteractiveCoordinatesChangedEventArgs.cs.meta new file mode 100644 index 0000000..879778d --- /dev/null +++ b/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/InteractiveCoordinatesChangedEventArgs.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 927658e1e9f511b449b5aa567cb9855c +timeCreated: 1524533777 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/InteractiveEventType.cs b/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/InteractiveEventType.cs index f13691d..129ba68 100644 --- a/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/InteractiveEventType.cs +++ b/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/InteractiveEventType.cs @@ -61,6 +61,16 @@ public enum InteractiveEventType /// Joystick, + /// + /// Events representing mouse button input. + /// + MouseButton, + + /// + /// Events representing coordinate input, where input are x, y, z values from 0 to 1. + /// + Coordinates, + /// /// Events representing text input. /// diff --git a/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/InteractiveMouseButtonEventArgs.cs b/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/InteractiveMouseButtonEventArgs.cs new file mode 100644 index 0000000..fa2b1e3 --- /dev/null +++ b/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/InteractiveMouseButtonEventArgs.cs @@ -0,0 +1,33 @@ +namespace Microsoft.Mixer +{ + public class InteractiveMouseButtonEventArgs : InteractiveEventArgs + { + public string ControlID + { + get; + private set; + } + + public InteractiveParticipant Participant + { + get; + private set; + } + + public bool IsPressed + { + get; + private set; + } + + internal InteractiveMouseButtonEventArgs( + string id, + InteractiveParticipant participant, + bool isPressed) : base(InteractiveEventType.MouseButton) + { + ControlID = id; + Participant = participant; + IsPressed = isPressed; + } + } +} \ No newline at end of file diff --git a/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/InteractiveMouseButtonEventArgs.cs.meta b/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/InteractiveMouseButtonEventArgs.cs.meta new file mode 100644 index 0000000..30a17d2 --- /dev/null +++ b/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/InteractiveMouseButtonEventArgs.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 11da6e7dc970a3543bea15caf3cbba00 +timeCreated: 1524533777 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/InteractivityManager.cs b/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/InteractivityManager.cs index 7289e6a..59884dd 100644 --- a/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/InteractivityManager.cs +++ b/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/InteractivityManager.cs @@ -29,7 +29,10 @@ using System.Net; using System.Net.Security; using System.Text; +using System.Threading; using UnityEngine; +using UnityEngine.Networking; +using System.Collections; #if UNITY_WSA && !UNITY_EDITOR using Windows.System.Threading; using System.Threading.Tasks; @@ -44,6 +47,7 @@ #endif #if UNITY_EDITOR || UNITY_STANDALONE || UNITY_IOS || UNITY_ANDROID using System.Security.Cryptography.X509Certificates; +using System.Timers; using WebSocketSharp; using Microsoft.Win32; using System.Collections.Specialized; @@ -77,12 +81,21 @@ public partial class InteractivityManager : IDisposable public delegate void OnInteractiveJoystickControlEventHandler(object sender, InteractiveJoystickEventArgs e); public event OnInteractiveJoystickControlEventHandler OnInteractiveJoystickControlEvent; + public delegate void OnInteractiveMouseButtonEventHandler(object sender, InteractiveMouseButtonEventArgs e); + public event OnInteractiveMouseButtonEventHandler OnInteractiveMouseButtonEvent; + + public delegate void OnInteractiveCoordinatesChangedHandler(object sender, InteractiveCoordinatesChangedEventArgs e); + public event OnInteractiveCoordinatesChangedHandler OnInteractiveCoordinatesChangedEvent; + internal delegate void OnInteractiveTextControlEventHandler(object sender, InteractiveTextEventArgs e); internal event OnInteractiveTextControlEventHandler OnInteractiveTextControlEvent; public delegate void OnInteractiveMessageEventHandler(object sender, InteractiveMessageEventArgs e); public event OnInteractiveMessageEventHandler OnInteractiveMessageEvent; + public delegate void OnInteractiveDoWorkEventHandler(object sender, InteractiveEventArgs e); + public event OnInteractiveDoWorkEventHandler OnInteractiveDoWorkEvent; + private static InteractivityManager _singletonInstance; /// @@ -172,7 +185,7 @@ public IList Participants } } - private IList Controls + internal IList Controls { get { @@ -1280,6 +1293,18 @@ private void RaiseQueuedInteractiveEvents() OnInteractiveJoystickControlEvent(this, interactiveEvent as InteractiveJoystickEventArgs); } break; + case InteractiveEventType.MouseButton: + if (OnInteractiveMouseButtonEvent != null) + { + OnInteractiveMouseButtonEvent(this, interactiveEvent as InteractiveMouseButtonEventArgs); + } + break; + case InteractiveEventType.Coordinates: + if (OnInteractiveCoordinatesChangedEvent != null) + { + OnInteractiveCoordinatesChangedEvent(this, interactiveEvent as InteractiveCoordinatesChangedEventArgs); + } + break; case InteractiveEventType.TextInput: if (OnInteractiveTextControlEvent != null) { @@ -2514,6 +2539,44 @@ private void HandleGiveInput(JsonReader jsonReader) uint participantID = participant.UserID; + // Handle screen input + if (inputEvent.Kind == CONTROL_KIND_SCREEN) + { + // Update x, y coordinates + if (inputEvent.Event == EVENT_NAME_MOVE) + { + Vector2 newMousePosition = new Vector2(inputEvent.X, inputEvent.Y); + // Translate the position to screen space. + newMousePosition.x *= Screen.width; + newMousePosition.y *= Screen.height; + if (_mousePositionsByParticipant.ContainsKey(participantID)) + { + _mousePositionsByParticipant[participantID] = newMousePosition; + } + else + { + _mousePositionsByParticipant.Add(participantID, newMousePosition); + } + InteractiveCoordinatesChangedEventArgs mouseMoveEventArgs = new InteractiveCoordinatesChangedEventArgs( + inputEvent.ControlID, + participant, + newMousePosition + ); + _queuedEvents.Add(mouseMoveEventArgs); + } + else if (inputEvent.Event == EVENT_NAME_MOUSE_DOWN || + inputEvent.Event == EVENT_NAME_MOUSE_UP) + { + InteractiveMouseButtonEventArgs mouseButtonEventArgs = new InteractiveMouseButtonEventArgs( + inputEvent.ControlID, + participant, + inputEvent.IsPressed + ); + _queuedEvents.Add(mouseButtonEventArgs); + UpdateInternalMouseButtonState(mouseButtonEventArgs); + } + } + // Put the input key values in the control data structure. string controlID = inputEvent.ControlID; string controlType = inputEvent.Kind; @@ -2797,6 +2860,13 @@ private bool TryGetJoystickStateByParticipant(uint userID, string controlID, out return joystickExists; } + internal InternalMouseButtonState TryGetMouseButtonState(uint userID) + { + InternalMouseButtonState mouseButtonState = new InternalMouseButtonState(); + _mouseButtonStateByParticipant.TryGetValue(userID, out mouseButtonState); + return mouseButtonState; + } + internal string GetText(string controlID, uint userID) { string text = string.Empty; @@ -3442,11 +3512,11 @@ private void SendJsonString(string jsonString) private const string WS_MESSAGE_KEY_Y = "y"; // Values - private const string WS_MESSAGE_VALUE_CONTROL_TYPE_BUTTON = "button"; + internal const string WS_MESSAGE_VALUE_CONTROL_TYPE_BUTTON = "button"; internal const string WS_MESSAGE_VALUE_DISABLED = "disabled"; internal const string WS_MESSAGE_VALUE_DEFAULT_GROUP_ID = "default"; internal const string WS_MESSAGE_VALUE_DEFAULT_SCENE_ID = "default"; - private const string WS_MESSAGE_VALUE_CONTROL_TYPE_JOYSTICK = "joystick"; + internal const string WS_MESSAGE_VALUE_CONTROL_TYPE_JOYSTICK = "joystick"; internal const string WS_MESSAGE_VALUE_CONTROL_TYPE_LABEL = "label"; internal const string WS_MESSAGE_VALUE_CONTROL_TYPE_TEXTBOX = "textbox"; private const bool WS_MESSAGE_VALUE_TRUE = true; @@ -3493,6 +3563,7 @@ private void SendJsonString(string jsonString) internal const string CONTROL_TYPE_JOYSTICK = "joystick"; internal const string CONTROL_KIND_LABEL = "label"; internal const string CONTROL_KIND_TEXTBOX = "textbox"; + internal const string CONTROL_KIND_SCREEN = "screen"; // Event names private const string EVENT_NAME_MOUSE_DOWN = "mousedown"; @@ -3519,6 +3590,8 @@ private void SendJsonString(string jsonString) internal static Dictionary _joystickStates; internal static Dictionary> _joystickStatesByParticipant; internal static Dictionary> _textboxValuesByParticipant; + internal static Dictionary _mouseButtonStateByParticipant; + internal static Dictionary _mousePositionsByParticipant; // Generic data structures for storing any control data internal static Dictionary>> _giveInputControlDataByParticipant; @@ -3583,6 +3656,8 @@ private void InitializeInternal() _joystickStates = new Dictionary(); _joystickStatesByParticipant = new Dictionary>(); + _mouseButtonStateByParticipant = new Dictionary(); + _mousePositionsByParticipant = new Dictionary(); _participantsWhoTriggeredGiveInput = new Dictionary(); _queuedControlPropertyUpdates = new Dictionary>(); @@ -3695,6 +3770,56 @@ private void ClearPreviousControlState() } } + // Mouse button state + List _mouseButtonStateByParticipantKeys = new List(_mouseButtonStateByParticipant.Keys); + foreach (uint _mouseButtonStateByParticipantKey in _mouseButtonStateByParticipantKeys) + { + InternalMouseButtonState oldMouseButtonState = _mouseButtonStateByParticipant[_mouseButtonStateByParticipantKey]; + InternalMouseButtonState newMouseButtonState = new InternalMouseButtonState(); + // If we just recieved a mouse down, but not an up, then the state is pressed + if (oldMouseButtonState.NextIsDown) + { + newMouseButtonState.IsDown = true; + newMouseButtonState.IsPressed = true; + newMouseButtonState.IsUp = false; + + newMouseButtonState.NextIsDown = false; + newMouseButtonState.NextIsPressed = true; + newMouseButtonState.NextIsUp = false; + } + else if (oldMouseButtonState.NextIsUp) + { + newMouseButtonState.IsDown = false; + newMouseButtonState.IsPressed = false; + newMouseButtonState.IsUp = true; + + newMouseButtonState.NextIsDown = false; + newMouseButtonState.NextIsPressed = false; + newMouseButtonState.NextIsUp = false; + } + else if (oldMouseButtonState.NextIsPressed) + { + newMouseButtonState.IsDown = false; + newMouseButtonState.IsPressed = true; + newMouseButtonState.IsUp = false; + + newMouseButtonState.NextIsDown = false; + newMouseButtonState.NextIsPressed = true; + newMouseButtonState.NextIsUp = false; + } + else + { + newMouseButtonState.IsDown = false; + newMouseButtonState.IsPressed = false; + newMouseButtonState.IsUp = false; + + newMouseButtonState.NextIsDown = false; + newMouseButtonState.NextIsPressed = false; + newMouseButtonState.NextIsUp = false; + } + _mouseButtonStateByParticipant[_mouseButtonStateByParticipantKey] = newMouseButtonState; + } + var controlIDKeys = new List(_participantsWhoTriggeredGiveInput.Keys); foreach (string controlIDKey in controlIDKeys) { @@ -3904,6 +4029,31 @@ private void UpdateInternalTextBoxState(InteractiveTextEventArgs e) _textboxValuesByParticipant[e.Participant.UserID][e.ControlID] = text; } + private void UpdateInternalMouseButtonState(InteractiveMouseButtonEventArgs e) + { + // Make sure the entry exists + uint participantId = e.Participant.UserID; + bool isPressed = e.IsPressed; + InternalMouseButtonState buttonState; + bool participantEntryExists = _mouseButtonStateByParticipant.TryGetValue(participantId, out buttonState); + if (!participantEntryExists) + { + buttonState = new InternalMouseButtonState(); + buttonState.IsDown = false; + buttonState.IsPressed = false; + buttonState.IsUp = false; + buttonState.NextIsDown = e.IsPressed; + buttonState.NextIsPressed = e.IsPressed; + buttonState.NextIsUp = !e.IsPressed; + _mouseButtonStateByParticipant.Add(participantId, buttonState); + } + InternalMouseButtonState newState = _mouseButtonStateByParticipant[participantId]; + newState.NextIsDown = isPressed; + newState.NextIsPressed = isPressed; + newState.NextIsUp = !isPressed; + _mouseButtonStateByParticipant[participantId] = newState; + } + internal void _QueuePropertyUpdate(string sceneID, string controlID, string name, bool value) { KnownControlPropertyPrimitiveTypes type = KnownControlPropertyPrimitiveTypes.Boolean; @@ -4110,6 +4260,16 @@ internal struct InternalJoystickState internal int countOfUniqueJoystickInputs; } + internal struct InternalMouseButtonState + { + internal bool IsDown; + internal bool IsPressed; + internal bool IsUp; + internal bool NextIsDown; + internal bool NextIsPressed; + internal bool NextIsUp; + } + internal struct InternalParticipantTrackingState { internal InteractiveParticipant previousParticpant; diff --git a/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/MixerInteractive.cs b/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/MixerInteractive.cs index fa3ea7a..3e4e1e2 100644 --- a/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/MixerInteractive.cs +++ b/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/MixerInteractive.cs @@ -31,18 +31,22 @@ using UnityEngine.Networking; using System.Collections; using System; +using System.Reflection; using Microsoft; #if UNITY_WSA && !UNITY_EDITOR using Windows.UI.Core; using Windows.ApplicationModel.Core; +using System; using Windows.Security.Credentials; using Windows.Security.Authentication.Web.Core; using System.Threading.Tasks; #endif #if UNITY_XBOXONE && !UNITY_EDITOR +using System; using System.Runtime.InteropServices; using System.Text; using System.IO; +using System.Collections; #endif public class MixerInteractive : MonoBehaviour @@ -93,6 +97,14 @@ public class MixerInteractive : MonoBehaviour private static bool hasFiredGoInteractiveEvent; private static bool shouldCheckForOutstandingRequests; + // Custom controls + public GameObject addNewRpcMethodSource; + // Unity doesn't handle serialization of dictionaries easily + // so we keep 2 lists of strings instead. + public List rpcOwningMonoBehaviorNames; + public List rpcMethodNames; + + private static List outboundMessages; internal static Websocket websocket; #if !UNITY_WSA || UNITY_EDITOR @@ -101,6 +113,7 @@ public class MixerInteractive : MonoBehaviour private const string DEFAULT_GROUP_ID = "default"; private const float CHECK_FOR_OUTSTANDING_REQUESTS_INTERVAL = 1f; + internal const float DEFAULT_MIXER_SYNCVAR_UPDATE_INTERVAL = 1f; void Awake() { @@ -174,6 +187,7 @@ private void Initialize() outstandingRequestsCompleted = false; shouldCheckForOutstandingRequests = false; lastCheckForOutstandingRequestsTime = -1; + outboundMessages = new List(); #if !UNITY_WSA backgroundWorker = new BackgroundWorker(); #endif @@ -221,6 +235,201 @@ private static void HandleInteractiveMessageEvent(object sender, InteractiveEven queuedEvents.Add(e); } + // Called when a remote RPC messages is sent + internal static void InvokeRpcMethod(string methodName, List mixerParameterInfos) + { + // See if we can find the method. If not, refresh the method cache and try again. + bool methodFound = FindAndInvokeRpcMethod(methodName, mixerParameterInfos); + if (!methodFound) + { + RefreshRPCMethods(); + FindAndInvokeRpcMethod(methodName, mixerParameterInfos); + } + } + + private static bool FindAndInvokeRpcMethod(string methodName, List mixerParameterInfos) + { + bool found = false; + RpcCachedMethodInfo rpcCachedMethodInfo = new RpcCachedMethodInfo(); + var helper = MixerInteractiveHelper.SingletonInstance; + if (helper.cachedRPCMethods.TryGetValue(methodName, out rpcCachedMethodInfo)) + { + // Invoke the function + MethodInfo methodInfo = rpcCachedMethodInfo.methodInfo; + ParameterInfo[] parametersInfo = methodInfo.GetParameters(); + object[] methodParameters = new object[parametersInfo.Length]; + for (int i = 0; i < parametersInfo.Length; i++) + { + ParameterInfo parameterInfo = parametersInfo[i]; + string parameterAsString = mixerParameterInfos[i].typeValue; + methodParameters[i] = Convert.ChangeType(parameterAsString, parameterInfo.ParameterType); + } + + found = true; + try + { + methodInfo.Invoke((object)rpcCachedMethodInfo.owningMonoBehavior, methodParameters); + } + catch (Exception e) + { + Debug.Log("Error calling method " + rpcCachedMethodInfo.owningMonoBehavior.name + "." + methodInfo.Name + ". Details: " + e.Message); + } + } + return found; + } + + public static void AddRpcMethodsFromTheEditor(GameObject owningGameObject, List rpcMethodNames) + { + if (rpcMethodNames.Count == 0) + { + return; + } + + var helper = MixerInteractiveHelper.SingletonInstance; + // TODO: Need to performance profile this for 1000 game objects. + MonoBehaviour[] activeBehaviors = owningGameObject.GetComponents(); + foreach (string rpcMethodName in rpcMethodNames) + { + string trimmedMethodName = TrimMethodName(rpcMethodName); + foreach (MonoBehaviour monoBehavior in activeBehaviors) + { + Type monoType = monoBehavior.GetType(); + MethodInfo[] methods = monoType.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); + foreach (MethodInfo method in methods) + { + if (method.Name == trimmedMethodName) + { + if (!helper.cachedRPCMethods.ContainsKey(method.Name)) + { + helper.cachedRPCMethods.Add(method.Name, new RpcCachedMethodInfo + { + owningMonoBehavior = monoBehavior, + methodInfo = method + }); + } + } + } + } + } + } + + internal static string TrimMethodName(string unTrimmedMethodName) + { + return unTrimmedMethodName.Split('(')[0].Trim(); + } + + private static void RefreshRPCMethods(bool includeMethodsFromTheInspector = false) + { + // Add all methods with the "MixerRpcMethod" to our method cache. + var helper = MixerInteractiveHelper.SingletonInstance; + MonoBehaviour[] activeBehaviors = FindObjectsOfType(); + foreach (MonoBehaviour monoBehavior in activeBehaviors) + { + Type monoType = monoBehavior.GetType(); + MethodInfo[] methods = monoType.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); + foreach (MethodInfo method in methods) + { + if (method.IsDefined(typeof(MixerRpcMethod), false)) + { + if (!helper.cachedRPCMethods.ContainsKey(method.Name)) + { + helper.cachedRPCMethods.Add(method.Name, new RpcCachedMethodInfo + { + owningMonoBehavior = monoBehavior, + methodInfo = method + }); + } + } + + // Check for inspector methods + if (includeMethodsFromTheInspector) + { + string currentMonoBehaviorName = monoBehavior.name; + for (int i = 0; i < helper.rpcOwningMonoBehaviorNames.Count; i++) + { + if (helper.rpcOwningMonoBehaviorNames[i] == currentMonoBehaviorName && + helper.rpcMethodNames[i] == method.Name) + { + if (!helper.cachedRPCMethods.ContainsKey(method.Name)) + { + helper.cachedRPCMethods.Add(method.Name, new RpcCachedMethodInfo + { + owningMonoBehavior = monoBehavior, + methodInfo = method + }); + } + } + } + } + } + } + } + + public static void FlushUpdates() + { + // Send all the outbound messages regardless of time. + SendOutboundMessages(); + } + + internal static void SendOutboundMessages() + { + foreach (string message in outboundMessages) + { + InteractivityManager.SingletonInstance.SendMessage(message); + } + } + + private static void SerializeSyncVars() + { + // Get all syncvars + // TODO: We need an editor version of this so devs can set properties on the + // syncvars like how often they get sent. + MonoBehaviour[] activeBehaviors = GameObject.FindObjectsOfType(); + foreach (MonoBehaviour monoBehavior in activeBehaviors) + { + Type monoType = monoBehavior.GetType(); + + // Get the fields + FieldInfo[] behaviorFields = monoType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.Instance); + foreach (FieldInfo field in behaviorFields) + { + MixerSyncVar attribute = Attribute.GetCustomAttribute(field, typeof(MixerSyncVar)) as MixerSyncVar; + if (attribute != null) + { + object valueAsObject = field.GetValue(monoBehavior); + string valueAsString = string.Empty; + if (valueAsObject != null) + { + valueAsString = valueAsObject.ToString(); + } + ParseAndSendCustomMessage(field.Name, valueAsString); + } + } + } + } + + private static void ParseAndSendCustomMessage(string name, string value) + { + InteractivityManager.SingletonInstance.SendMessage("{" + + " name: " + name + + " value: " + value + + "}"); + } + + internal static void QueueCustomMessage(string newMessage) + { + if (outboundMessages == null) + { + outboundMessages = new List(); + } + outboundMessages.Add(newMessage); + } + + internal static int GetTimeSinceStartUpInMilliSeconds() + { + return (int)Time.realtimeSinceStartup * 1000; + } + /// /// Gets and sets the token used for authentication with Mixer. /// You can set the token manually that the SDK will use. @@ -316,6 +525,31 @@ public static bool ManuallyHandleSparkTransactions set; } + /// + /// Returns the current mouse position in Unity's screen space. + /// + public static Vector3 MousePosition + { + get + { + Vector3 mousePosition = Vector3.zero; + Dictionary mousePositionsByParticipant = InteractivityManager._mousePositionsByParticipant; + var mousePositionByParticipantKeys = mousePositionsByParticipant.Keys; + float totalX = 0; + float totalY = 0; + foreach (var mousePositionByParticipantKey in mousePositionByParticipantKeys) + { + totalX += mousePositionsByParticipant[mousePositionByParticipantKey].x; + totalY += mousePositionsByParticipant[mousePositionByParticipantKey].y; + } + // We average all the mouse positions. Z in always zero. + mousePosition.x = totalX / mousePositionByParticipantKeys.Count; + mousePosition.y = totalY / mousePositionByParticipantKeys.Count; + + return mousePosition; + } + } + /// /// The string the broadcaster needs to enter in the Mixer website to /// authorize the interactive session. @@ -426,6 +660,9 @@ public static void StopInteractive() public static void DoWork() { InteractivityManager.SingletonInstance.DoWork(); + + // Send any outstanding custom controls messages that are queued. + SendOutboundMessages(); } /// @@ -486,7 +723,7 @@ void Update() outstandingRequestsCompleted = CheckForOutStandingRequestsCompleted(); } - InteractivityManager.SingletonInstance.DoWork(); + DoWork(); List processedEvents = new List(); if (queuedEvents != null) @@ -682,6 +919,75 @@ public static float GetJoystickY(string controlID) return (float)InteractivityManager.SingletonInstance.GetJoystick(controlID).Y; } + /// + /// Returns whether the mouse button down event occured. + /// + /// + /// The index of the mouse button. Only 1 value is supported right now + /// which is 0. 0 corresponds to the left mouse button. + /// + public static bool GetMouseButtonDown(int buttonIndex = 0) + { + bool getButtonDownResult = false; + Dictionary mouseButtonStateByParticipant = InteractivityManager._mouseButtonStateByParticipant; + var mouseButtonStateByParticipantKeys = mouseButtonStateByParticipant.Keys; + foreach (uint mouseButtonStateByParticipantKey in mouseButtonStateByParticipantKeys) + { + if (mouseButtonStateByParticipant[mouseButtonStateByParticipantKey].IsDown) + { + getButtonDownResult = true; + break; + } + } + return getButtonDownResult; + } + + /// + /// Returns whether the mouse button is currently pressed. + /// + /// + /// The index of the mouse button. Only 1 value is supported right now + /// which is 0. 0 corresponds to the left mouse button. + /// + public static bool GetMouseButton(int buttonIndex = 0) + { + bool getButtonDownResult = false; + Dictionary mouseButtonStateByParticipant = InteractivityManager._mouseButtonStateByParticipant; + var mouseButtonStateByParticipantKeys = mouseButtonStateByParticipant.Keys; + foreach (uint mouseButtonStateByParticipantKey in mouseButtonStateByParticipantKeys) + { + if (mouseButtonStateByParticipant[mouseButtonStateByParticipantKey].IsPressed) + { + getButtonDownResult = true; + break; + } + } + return getButtonDownResult; + } + + /// + /// Returns whether the mouse button up event occured. + /// + /// + /// The index of the mouse button. Only 1 value is supported right now + /// which is 0. 0 corresponds to the left mouse button. + /// + public static bool GetMouseButtonUp(int buttonIndex = 0) + { + bool getButtonDownResult = false; + Dictionary mouseButtonStateByParticipant = InteractivityManager._mouseButtonStateByParticipant; + var mouseButtonStateByParticipantKeys = mouseButtonStateByParticipant.Keys; + foreach (uint mouseButtonStateByParticipantKey in mouseButtonStateByParticipantKeys) + { + if (mouseButtonStateByParticipant[mouseButtonStateByParticipantKey].IsUp) + { + getButtonDownResult = true; + break; + } + } + return getButtonDownResult; + } + /// /// Gets a button control object by ID. /// @@ -1093,4 +1399,39 @@ void OnApplicationQuit() { StopInteractive(); } -} \ No newline at end of file + + // Custom controls + public class RpcCachedMethodInfo + { + public MonoBehaviour owningMonoBehavior; + public MethodInfo methodInfo; + } + + public class ObservedCachedFieldInfo + { + public FieldInfo fieldInfo; + public object owningObject; + public float updateInterval; + public float lastSendTime; + public string previousValueAsString; + } + + public struct MixerHelperParameterInfo + { + public string typeName; + public string typeValue; + } +} + +[AttributeUsage(AttributeTargets.Field)] +public class MixerSyncVar : Attribute +{ + public float updateInterval; + public MixerSyncVar(double newUpdateInterval = MixerInteractive.DEFAULT_MIXER_SYNCVAR_UPDATE_INTERVAL) + { + updateInterval = (float)newUpdateInterval; + } +} + +[AttributeUsage(AttributeTargets.Method)] +public class MixerRpcMethod : Attribute { } \ No newline at end of file diff --git a/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/MixerInteractiveHelper.cs b/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/MixerInteractiveHelper.cs index d30d544..3ac83f5 100644 --- a/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/MixerInteractiveHelper.cs +++ b/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/MixerInteractiveHelper.cs @@ -34,6 +34,9 @@ internal class MixerInteractiveHelper: MonoBehaviour internal bool runInBackgroundIfInteractive = true; internal string defaultSceneID; internal Dictionary groupSceneMapping = new Dictionary(); + internal List rpcOwningMonoBehaviorNames = new List(); + internal List rpcMethodNames = new List(); + internal Dictionary cachedRPCMethods = new Dictionary(); public delegate void OnInternalWebRequestStateChangedEventHandler(object sender, InternalWebRequestStateChangedEventArgs e); public event OnInternalWebRequestStateChangedEventHandler OnInternalWebRequestStateChanged; From a09347c4fd4f8f4a7c4c67266d0ffbb3284f998f Mon Sep 17 00:00:00 2001 From: Gersh Payzer Date: Mon, 30 Apr 2018 07:00:44 -0700 Subject: [PATCH 2/3] New Control Infrastructure, metaproperties, screen control This change includes: * Support for metaproperties * Screen control * Infrastructure to support future controls * Most of the diffs are using underscores for internal variables --- .../Scripts/InteractiveButtonControl.cs | 43 +- .../Source/Scripts/InteractiveControl.cs | 50 +- .../Source/Scripts/InteractiveGroup.cs | 12 +- .../Scripts/InteractiveJoystickControl.cs | 19 +- .../Source/Scripts/InteractiveLabelControl.cs | 6 +- .../InteractiveMouseButtonEventArgs.cs | 14 +- .../Source/Scripts/InteractiveParticipant.cs | 24 +- .../Source/Scripts/InteractiveScene.cs | 8 +- .../Source/Scripts/InteractiveTextControl.cs | 5 +- .../Source/Scripts/InteractivityManager.cs | 605 ++++++++++-------- .../Source/Scripts/MixerInteractive.cs | 114 ++-- .../Source/Scripts/MixerInteractiveHelper.cs | 32 +- 12 files changed, 525 insertions(+), 407 deletions(-) diff --git a/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/InteractiveButtonControl.cs b/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/InteractiveButtonControl.cs index 4b25505..dba2be2 100644 --- a/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/InteractiveButtonControl.cs +++ b/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/InteractiveButtonControl.cs @@ -62,7 +62,7 @@ public int RemainingCooldown get { Int64 now = (Int64)DateTime.UtcNow.ToUniversalTime().Subtract(new DateTime(1970, 1, 1)).TotalMilliseconds; - int timeRemaining = (int)(cooldownExpirationTime - now); + int timeRemaining = (int)(_cooldownExpirationTime - now); if (timeRemaining < 0) { timeRemaining = 0; @@ -90,7 +90,7 @@ public bool ButtonDown bool isDown = false; if (ControlID != null) { - InternalButtonCountState ButtonCountState; + _InternalButtonCountState ButtonCountState; if (InteractivityManager._buttonStates.TryGetValue(ControlID, out ButtonCountState)) { isDown = ButtonCountState.CountOfButtonDownEvents > 0; @@ -110,7 +110,7 @@ public bool ButtonPressed bool isPressed = false; if (ControlID != null) { - InternalButtonCountState ButtonCountState; + _InternalButtonCountState ButtonCountState; if (InteractivityManager._buttonStates.TryGetValue(ControlID, out ButtonCountState)) { isPressed = ButtonCountState.CountOfButtonPressEvents > 0; @@ -130,7 +130,7 @@ public bool ButtonUp bool isUp = false; if (ControlID != null) { - InternalButtonCountState ButtonCountState; + _InternalButtonCountState ButtonCountState; if (InteractivityManager._buttonStates.TryGetValue(ControlID, out ButtonCountState)) { isUp = ButtonCountState.CountOfButtonUpEvents > 0; @@ -150,7 +150,7 @@ public uint CountOfButtonDowns uint countOfButtonDownEvents = 0; if (ControlID != null) { - InternalButtonCountState ButtonCountState; + _InternalButtonCountState ButtonCountState; if (InteractivityManager._buttonStates.TryGetValue(ControlID, out ButtonCountState)) { countOfButtonDownEvents = ButtonCountState.CountOfButtonDownEvents; @@ -170,7 +170,7 @@ public uint CountOfButtonPresses uint countOfButtonPressEvents = 0; if (ControlID != null) { - InternalButtonCountState ButtonCountState; + _InternalButtonCountState ButtonCountState; if (InteractivityManager._buttonStates.TryGetValue(ControlID, out ButtonCountState)) { countOfButtonPressEvents = ButtonCountState.CountOfButtonPressEvents; @@ -190,7 +190,7 @@ public uint CountOfButtonUps uint countOfButtonPressEvents = 0; if (ControlID != null) { - InternalButtonCountState ButtonCountState; + _InternalButtonCountState ButtonCountState; if (InteractivityManager._buttonStates.TryGetValue(ControlID, out ButtonCountState)) { countOfButtonPressEvents = ButtonCountState.CountOfButtonUpEvents; @@ -206,9 +206,9 @@ public uint CountOfButtonUps /// Value from 0.0 to 1.0. public void SetProgress(float progress) { - InteractivityManager.SingletonInstance.SendSetButtonControlProperties( + InteractivityManager.SingletonInstance._SendSetButtonControlProperties( ControlID, - InteractivityManager.WS_MESSAGE_KEY_PROGRESS, + InteractivityManager._WS_MESSAGE_KEY_PROGRESS, false, progress, string.Empty, @@ -221,9 +221,9 @@ public void SetProgress(float progress) /// String to display on the button. public void SetText(string text) { - InteractivityManager.SingletonInstance.SendSetButtonControlProperties( + InteractivityManager.SingletonInstance._SendSetButtonControlProperties( ControlID, - InteractivityManager.WS_MESSAGE_KEY_TEXT, + InteractivityManager._WS_MESSAGE_KEY_TEXT, false, 0, text, @@ -236,9 +236,9 @@ public void SetText(string text) /// The number of sparks for this action. public void SetCost(uint cost) { - InteractivityManager.SingletonInstance.SendSetButtonControlProperties( + InteractivityManager.SingletonInstance._SendSetButtonControlProperties( ControlID, - InteractivityManager.WS_MESSAGE_KEY_COST, + InteractivityManager._WS_MESSAGE_KEY_COST, false, 0, string.Empty, @@ -251,7 +251,7 @@ public void SetCost(uint cost) /// The ID of the user who used the input control. public bool GetButtonDown(uint userID) { - return InteractivityManager.SingletonInstance.GetButtonDown(ControlID, userID); + return InteractivityManager.SingletonInstance._GetButtonDown(ControlID, userID); } /// @@ -260,7 +260,7 @@ public bool GetButtonDown(uint userID) /// The ID of the user who used the input control. public bool GetButtonPressed(uint userID) { - return InteractivityManager.SingletonInstance.GetButtonPressed(ControlID, userID); + return InteractivityManager.SingletonInstance._GetButtonPressed(ControlID, userID); } /// @@ -269,7 +269,7 @@ public bool GetButtonPressed(uint userID) /// The ID of the user who used the input control. public bool GetButtonUp(uint userID) { - return InteractivityManager.SingletonInstance.GetButtonUp(ControlID, userID); + return InteractivityManager.SingletonInstance._GetButtonUp(ControlID, userID); } /// @@ -278,7 +278,7 @@ public bool GetButtonUp(uint userID) /// The ID of the user who used the input control. public uint GetCountOfButtonDowns(uint userID) { - return InteractivityManager.SingletonInstance.GetCountOfButtonDowns(ControlID, userID); + return InteractivityManager.SingletonInstance._GetCountOfButtonDowns(ControlID, userID); } /// @@ -287,7 +287,7 @@ public uint GetCountOfButtonDowns(uint userID) /// The ID of the user who used the input control. public uint GetCountOfButtonPresses(uint userID) { - return InteractivityManager.SingletonInstance.GetCountOfButtonPresses(ControlID, userID); + return InteractivityManager.SingletonInstance._GetCountOfButtonPresses(ControlID, userID); } /// @@ -296,7 +296,7 @@ public uint GetCountOfButtonPresses(uint userID) /// The ID of the user who used the input control. public uint GetCountOfButtonUps(uint userID) { - return InteractivityManager.SingletonInstance.GetCountOfButtonUps(ControlID, userID); + return InteractivityManager.SingletonInstance._GetCountOfButtonUps(ControlID, userID); } /// @@ -308,8 +308,9 @@ public void TriggerCooldown(int cooldown) InteractivityManager.SingletonInstance.TriggerCooldown(ControlID, cooldown); } - internal Int64 cooldownExpirationTime; - public InteractiveButtonControl(string controlID, InteractiveEventType type, bool disabled, string helpText, uint cost, string eTag, string sceneID) : base(controlID, InteractivityManager.CONTROL_TYPE_BUTTON, type, disabled, helpText, eTag, sceneID) + internal Int64 _cooldownExpirationTime; + public InteractiveButtonControl(string controlID, InteractiveEventType type, bool disabled, string helpText, uint cost, string eTag, string sceneID, Dictionary metaproperties) : + base(controlID, InteractivityManager._CONTROL_TYPE_BUTTON, type, disabled, helpText, eTag, sceneID, metaproperties) { Cost = cost; } diff --git a/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/InteractiveControl.cs b/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/InteractiveControl.cs index a610224..2955b83 100644 --- a/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/InteractiveControl.cs +++ b/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/InteractiveControl.cs @@ -22,6 +22,8 @@ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ +using System.Collections.Generic; + namespace Microsoft.Mixer { /// Base class for Interactivity controls. All controls are created and @@ -59,10 +61,19 @@ public string HelpText private set; } - internal string ETag; - internal string SceneID; - internal string Kind; - internal InteractiveEventType Type; + /// + /// Returns a read only dictionary of name, value pairs for the control's metadata. + /// + public IDictionary MetaProperties + { + get; + private set; + } + + internal string _eTag; + internal string _sceneID; + internal string _kind; + internal InteractiveEventType _type; internal int participantID; /// @@ -72,9 +83,9 @@ public string HelpText public void SetDisabled(bool disabled) { Disabled = disabled; - InteractivityManager.SingletonInstance.SendSetButtonControlProperties( + InteractivityManager.SingletonInstance._SendSetButtonControlProperties( ControlID, - InteractivityManager.WS_MESSAGE_VALUE_DISABLED, + InteractivityManager._WS_MESSAGE_VALUE_DISABLED, disabled, 0, string.Empty, @@ -89,28 +100,28 @@ public void SetDisabled(bool disabled) public void SetProperty(InteractiveControlProperty name, bool value) { SetPropertyImpl( - InteractivityManager.SingletonInstance.InteractiveControlPropertyToString(name), + InteractivityManager.SingletonInstance._InteractiveControlPropertyToString(name), value ); } public void SetProperty(InteractiveControlProperty name, double value) { SetPropertyImpl( - InteractivityManager.SingletonInstance.InteractiveControlPropertyToString(name), + InteractivityManager.SingletonInstance._InteractiveControlPropertyToString(name), value ); } public void SetProperty(InteractiveControlProperty name, string value) { SetPropertyImpl( - InteractivityManager.SingletonInstance.InteractiveControlPropertyToString(name), + InteractivityManager.SingletonInstance._InteractiveControlPropertyToString(name), value ); } public void SetProperty(InteractiveControlProperty name, object value) { SetPropertyImpl( - InteractivityManager.SingletonInstance.InteractiveControlPropertyToString(name), + InteractivityManager.SingletonInstance._InteractiveControlPropertyToString(name), value ); } @@ -139,31 +150,32 @@ public void SetProperty(string name, object value) private void SetPropertyImpl(string name, bool value) { - InteractivityManager.SingletonInstance._QueuePropertyUpdate(SceneID, ControlID, name, value); + InteractivityManager.SingletonInstance._QueuePropertyUpdate(_sceneID, ControlID, name, value); } private void SetPropertyImpl(string name, double value) { - InteractivityManager.SingletonInstance._QueuePropertyUpdate(SceneID, ControlID, name, value); + InteractivityManager.SingletonInstance._QueuePropertyUpdate(_sceneID, ControlID, name, value); } private void SetPropertyImpl(string name, string value) { - InteractivityManager.SingletonInstance._QueuePropertyUpdate(SceneID, ControlID, name, value); + InteractivityManager.SingletonInstance._QueuePropertyUpdate(_sceneID, ControlID, name, value); } private void SetPropertyImpl(string name, object value) { - InteractivityManager.SingletonInstance._QueuePropertyUpdate(SceneID, ControlID, name, value); + InteractivityManager.SingletonInstance._QueuePropertyUpdate(_sceneID, ControlID, name, value); } - internal InteractiveControl(string controlID, string kind, InteractiveEventType type, bool disabled, string helpText, string eTag, string sceneID) + internal InteractiveControl(string controlID, string kind, InteractiveEventType type, bool disabled, string helpText, string eTag, string sceneID, Dictionary metaProperties) { ControlID = controlID; - Kind = kind; - Type = type; + _kind = kind; + _type = type; Disabled = disabled; HelpText = helpText; - ETag = eTag; - SceneID = sceneID; + _eTag = eTag; + _sceneID = sceneID; participantID = -1; + MetaProperties = metaProperties; } } } diff --git a/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/InteractiveGroup.cs b/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/InteractiveGroup.cs index 8ecb1be..69ab524 100644 --- a/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/InteractiveGroup.cs +++ b/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/InteractiveGroup.cs @@ -61,7 +61,7 @@ public List Participants List allParticipants = InteractivityManager.SingletonInstance.Participants as List; foreach (InteractiveParticipant participant in allParticipants) { - if (participant.groupID == GroupID) + if (participant._groupID == GroupID) { participantsInGroup.Add(participant); } @@ -85,10 +85,10 @@ public string SceneID public void SetScene(string sceneID) { SceneID = sceneID; - InteractivityManager.SingletonInstance.SetCurrentSceneInternal(this, sceneID); + InteractivityManager.SingletonInstance._SetCurrentSceneInternal(this, sceneID); } - internal string etag; + internal string _etag; /// /// Function to construct a InteractiveGroup object. @@ -102,7 +102,7 @@ public InteractiveGroup(string groupID) } GroupID = groupID; - InteractivityManager.SingletonInstance.SendCreateGroupsMessage(GroupID, InteractivityManager.WS_MESSAGE_VALUE_DEFAULT_SCENE_ID); + InteractivityManager.SingletonInstance._SendCreateGroupsMessage(GroupID, InteractivityManager._WS_MESSAGE_VALUE_DEFAULT_SCENE_ID); } /// @@ -118,12 +118,12 @@ public InteractiveGroup(string groupID, string sceneID) GroupID = groupID; SceneID = sceneID; - InteractivityManager.SingletonInstance.SendCreateGroupsMessage(GroupID, SceneID); + InteractivityManager.SingletonInstance._SendCreateGroupsMessage(GroupID, SceneID); } internal InteractiveGroup(string newEtag, string sceneID, string groupID) { - etag = newEtag; + _etag = newEtag; SceneID = sceneID; GroupID = groupID; } diff --git a/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/InteractiveJoystickControl.cs b/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/InteractiveJoystickControl.cs index ce6930b..4fd7c55 100644 --- a/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/InteractiveJoystickControl.cs +++ b/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/InteractiveJoystickControl.cs @@ -45,7 +45,7 @@ public double X double x = 0; if (ControlID != null) { - InternalJoystickState joystickState; + _InternalJoystickState joystickState; if (InteractivityManager._joystickStates.TryGetValue(ControlID, out joystickState)) { x = joystickState.X; @@ -65,7 +65,7 @@ public double Y double y = 0; if (ControlID != null) { - InternalJoystickState joystickState; + _InternalJoystickState joystickState; if (InteractivityManager._joystickStates.TryGetValue(ControlID, out joystickState)) { y = joystickState.Y; @@ -90,7 +90,7 @@ public double Intensity /// The ID of the participant who used the input control. public double GetX(uint userID) { - return InteractivityManager.SingletonInstance.GetJoystickX(ControlID, userID); + return InteractivityManager.SingletonInstance._GetJoystickX(ControlID, userID); } /// @@ -99,21 +99,22 @@ public double GetX(uint userID) /// The ID of the participant who used the input control. public double GetY(uint userID) { - return InteractivityManager.SingletonInstance.GetJoystickY(ControlID, userID); + return InteractivityManager.SingletonInstance._GetJoystickY(ControlID, userID); } - public InteractiveJoystickControl(string controlID, InteractiveEventType type, bool enabled, string helpText, string eTag, string sceneID) : base(controlID, InteractivityManager.CONTROL_TYPE_JOYSTICK, type, enabled, helpText, eTag, sceneID) + public InteractiveJoystickControl(string controlID, InteractiveEventType type, bool enabled, string helpText, string eTag, string sceneID, Dictionary metaproperties) : + base(controlID, InteractivityManager._CONTROL_TYPE_JOYSTICK, type, enabled, helpText, eTag, sceneID, metaproperties) { } - internal uint UserID; + internal uint _userID; - private bool TryGetJoystickStateByParticipant(uint userID, string controlID, out InternalJoystickState joystickState) + private bool TryGetJoystickStateByParticipant(uint userID, string controlID, out _InternalJoystickState joystickState) { - joystickState = new InternalJoystickState(); + joystickState = new _InternalJoystickState(); bool joystickExists = false; bool participantExists = false; - Dictionary participantControls; + Dictionary participantControls; participantExists = InteractivityManager._joystickStatesByParticipant.TryGetValue(userID, out participantControls); if (participantExists) { diff --git a/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/InteractiveLabelControl.cs b/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/InteractiveLabelControl.cs index c656f36..d711a03 100644 --- a/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/InteractiveLabelControl.cs +++ b/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/InteractiveLabelControl.cs @@ -53,13 +53,13 @@ public void SetText(string text) { InteractivityManager interactivityManager = InteractivityManager.SingletonInstance; interactivityManager._QueuePropertyUpdate( - SceneID, + _sceneID, ControlID, - interactivityManager.InteractiveControlPropertyToString(InteractiveControlProperty.Text), + interactivityManager._InteractiveControlPropertyToString(InteractiveControlProperty.Text), text); } - public InteractiveLabelControl(string controlID, string text, string sceneID) : base(controlID, InteractivityManager.CONTROL_KIND_LABEL, InteractiveEventType.Unknown, false, "", "", sceneID) + public InteractiveLabelControl(string controlID, string text, string sceneID) : base(controlID, InteractivityManager._CONTROL_KIND_LABEL, InteractiveEventType.Unknown, false, "", "", sceneID, new Dictionary()) { Text = text; } diff --git a/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/InteractiveMouseButtonEventArgs.cs b/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/InteractiveMouseButtonEventArgs.cs index fa2b1e3..610c8ff 100644 --- a/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/InteractiveMouseButtonEventArgs.cs +++ b/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/InteractiveMouseButtonEventArgs.cs @@ -1,4 +1,6 @@ -namespace Microsoft.Mixer +using UnityEngine; + +namespace Microsoft.Mixer { public class InteractiveMouseButtonEventArgs : InteractiveEventArgs { @@ -20,14 +22,22 @@ public bool IsPressed private set; } + public Vector3 Position + { + get; + private set; + } + internal InteractiveMouseButtonEventArgs( string id, InteractiveParticipant participant, - bool isPressed) : base(InteractiveEventType.MouseButton) + bool isPressed, + Vector3 position) : base(InteractiveEventType.MouseButton) { ControlID = id; Participant = participant; IsPressed = isPressed; + Position = position; } } } \ No newline at end of file diff --git a/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/InteractiveParticipant.cs b/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/InteractiveParticipant.cs index 90a15ef..a27d2f5 100644 --- a/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/InteractiveParticipant.cs +++ b/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/InteractiveParticipant.cs @@ -82,7 +82,7 @@ public InteractiveGroup Group List allGroups = InteractivityManager.SingletonInstance.Groups as List; foreach (InteractiveGroup group in allGroups) { - if (group.GroupID == groupID) + if (group.GroupID == _groupID) { return group; } @@ -93,11 +93,11 @@ public InteractiveGroup Group { if (value == null) { - InteractivityManager.SingletonInstance.LogError("Error: You cannot assign 'null' as the group value."); + InteractivityManager.SingletonInstance._LogError("Error: You cannot assign 'null' as the group value."); return; } - groupID = value.GroupID; - InteractivityManager.SingletonInstance.SendUpdateParticipantsMessage(this); + _groupID = value.GroupID; + InteractivityManager.SingletonInstance._SendUpdateParticipantsMessage(this); } } @@ -145,7 +145,7 @@ public IList Buttons get { List buttonsForParticipant = new List(); - Dictionary buttonState; + Dictionary buttonState; bool participantEntryExists = InteractivityManager._buttonStatesByParticipant.TryGetValue(UserID, out buttonState); if (participantEntryExists) { @@ -175,7 +175,7 @@ public IList Joysticks get { List joysticksForParticipant = new List(); - Dictionary joystickByParticipant; + Dictionary joystickByParticipant; bool participantEntryExists = InteractivityManager._joystickStatesByParticipant.TryGetValue(UserID, out joystickByParticipant); if (participantEntryExists) { @@ -206,14 +206,14 @@ public InteractiveParticipantState State internal set; } - internal string etag; - internal string groupID; - internal string sessionID; + internal string _etag; + internal string _groupID; + internal string _sessionID; private List channelGroups; internal InteractiveParticipant(string newSessionID, string newEtag, uint userID, string newGroupID, string userName, List newChannelGroups, uint level, DateTime lastInputAt, DateTime connectedAt, bool inputDisabled, InteractiveParticipantState state) { - sessionID = newSessionID; + _sessionID = newSessionID; UserID = userID; UserName = userName; channelGroups = newChannelGroups; @@ -222,8 +222,8 @@ internal InteractiveParticipant(string newSessionID, string newEtag, uint userID ConnectedAt = connectedAt; InputDisabled = inputDisabled; State = state; - groupID = newGroupID; - etag = newEtag; + _groupID = newGroupID; + _etag = newEtag; } } } \ No newline at end of file diff --git a/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/InteractiveScene.cs b/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/InteractiveScene.cs index f1d4b21..b52f661 100644 --- a/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/InteractiveScene.cs +++ b/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/InteractiveScene.cs @@ -55,7 +55,7 @@ public IList Buttons List allButtons = InteractivityManager.SingletonInstance.Buttons as List; foreach (InteractiveButtonControl button in allButtons) { - if (button.SceneID == SceneID) + if (button._sceneID == SceneID) { buttonsInScene.Add(button); } @@ -75,7 +75,7 @@ public IList Joysticks List allJoysticks = InteractivityManager.SingletonInstance.Joysticks as List; foreach (InteractiveJoystickControl joystick in allJoysticks) { - if (joystick.SceneID == SceneID) + if (joystick._sceneID == SceneID) { joysticksInScene.Add(joystick); } @@ -120,12 +120,12 @@ public InteractiveJoystickControl GetJoystick(string controlID) return InteractivityManager.SingletonInstance.GetJoystick(controlID); } - internal string etag; + internal string _etag; internal InteractiveScene(string sceneID = "", string newEtag = "") { SceneID = sceneID; - etag = newEtag; + _etag = newEtag; } } } diff --git a/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/InteractiveTextControl.cs b/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/InteractiveTextControl.cs index d6536f1..c19b1f5 100644 --- a/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/InteractiveTextControl.cs +++ b/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/InteractiveTextControl.cs @@ -19,11 +19,12 @@ public IList TextResults { get { - return InteractivityManager.SingletonInstance.GetText(ControlID); + return InteractivityManager.SingletonInstance._GetText(ControlID); } } - public InteractiveTextControl(string controlID, InteractiveEventType type, bool disabled, string helpText, string eTag, string sceneID) : base(controlID, InteractivityManager.CONTROL_KIND_TEXTBOX, type, disabled, helpText, eTag, sceneID) + public InteractiveTextControl(string controlID, InteractiveEventType type, bool disabled, string helpText, string eTag, string sceneID, Dictionary metaproperties) : + base(controlID, InteractivityManager._CONTROL_KIND_TEXTBOX, type, disabled, helpText, eTag, sceneID, metaproperties) { } } diff --git a/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/InteractivityManager.cs b/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/InteractivityManager.cs index 59884dd..931fcce 100644 --- a/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/InteractivityManager.cs +++ b/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/InteractivityManager.cs @@ -185,7 +185,7 @@ public IList Participants } } - internal IList Controls + internal IList _Controls { get { @@ -301,7 +301,7 @@ public void Initialize( bool getXTokenSucceeded = MixerEraNativePlugin_GetXToken(dataPointer); if (!getXTokenSucceeded) { - LogError("Error: Could not get a Xbox Live token. Make sure you have a user signed in."); + _LogError("Error: Could not get a Xbox Live token. Make sure you have a user signed in."); } _authToken = Marshal.PtrToStringAnsi(dataPointer); pinnedMemory.Free(); @@ -356,13 +356,13 @@ private void InitiateConnection() { mixerInteractiveHelper.OnInternalWebRequestStateChanged -= OnRequestWebSocketHostsCompleted; mixerInteractiveHelper.OnInternalWebRequestStateChanged += OnRequestWebSocketHostsCompleted; - mixerInteractiveHelper.MakeWebRequest( + mixerInteractiveHelper._MakeWebRequest( "OnRequestWebSocketHostsCompleted", WEBSOCKET_DISCOVERY_URL); } catch (Exception ex) { - LogError("Error: Could not retrieve the URL for the websocket. Exception details: " + ex.Message); + _LogError("Error: Could not retrieve the URL for the websocket. Exception details: " + ex.Message); } } @@ -412,7 +412,7 @@ private void OnTryGetAuthTokensFromCacheCompleted(MixerInteractiveHelper.TryGetA } } - private void OnRequestWebSocketHostsCompleted(object sender, MixerInteractiveHelper.InternalWebRequestStateChangedEventArgs e) + private void OnRequestWebSocketHostsCompleted(object sender, MixerInteractiveHelper._InternalWebRequestStateChangedEventArgs e) { if (e.RequestID != "OnRequestWebSocketHostsCompleted") { @@ -425,7 +425,7 @@ private void OnRequestWebSocketHostsCompleted(object sender, MixerInteractiveHel } else { - LogError("Error: Could not retrieve the URL for the websocket. Exception details: " + e.ErrorMessage); + _LogError("Error: Could not retrieve the URL for the websocket. Exception details: " + e.ErrorMessage); } } @@ -482,7 +482,7 @@ private void PopulateConfigData() } catch { - LogError("Error: interactiveconfig.json file could not be read. Make sure it is valid JSON and has the correct format."); + _LogError("Error: interactiveconfig.json file could not be read. Make sure it is valid JSON and has the correct format."); } } else @@ -498,11 +498,11 @@ private void OnInternalCheckAuthStatusTimerCallback(object sender, MixerInteract private void TryGetTokenAsync() { - Log("Trying to obtain a new OAuth token. This is an expected and repeated call."); + _Log("Trying to obtain a new OAuth token. This is an expected and repeated call."); mixerInteractiveHelper.OnInternalWebRequestStateChanged -= OnRequestOAuthExchangeTokenCompleted; mixerInteractiveHelper.OnInternalWebRequestStateChanged += OnRequestOAuthExchangeTokenCompleted; - mixerInteractiveHelper.MakeWebRequest( + mixerInteractiveHelper._MakeWebRequest( "OnRequestOAuthExchangeTokenCompleted", API_CHECK_SHORT_CODE_AUTH_STATUS_PATH + _authShortCodeRequestHandle, new Dictionary() @@ -512,7 +512,7 @@ private void TryGetTokenAsync() ); } - private void OnRequestOAuthExchangeTokenCompleted(object sender, MixerInteractiveHelper.InternalWebRequestStateChangedEventArgs e) + private void OnRequestOAuthExchangeTokenCompleted(object sender, MixerInteractiveHelper._InternalWebRequestStateChangedEventArgs e) { if (e.RequestID != "OnRequestOAuthExchangeTokenCompleted") { @@ -525,7 +525,7 @@ private void OnRequestOAuthExchangeTokenCompleted(object sender, MixerInteractiv } else { - LogError("Error: Failed to request an OAuth exchange token. Error message: " + e.ErrorMessage); + _LogError("Error: Failed to request an OAuth exchange token. Error message: " + e.ErrorMessage); } } @@ -570,12 +570,12 @@ private string ParseOAuthExchangeCodeFromStringResponse(string responseText) private void GetOauthToken(string exchangeCode) { - Log("Retrieved an OAuth exchange token. Exchange token: " + exchangeCode + " Using AppID: " + AppID + " with exchange code: " + exchangeCode); + _Log("Retrieved an OAuth exchange token. Exchange token: " + exchangeCode + " Using AppID: " + AppID + " with exchange code: " + exchangeCode); string postData = "{ \"client_id\": \"" + AppID + "\", \"code\": \"" + exchangeCode + "\", \"grant_type\": \"authorization_code\" }"; mixerInteractiveHelper.OnInternalWebRequestStateChanged -= OnRequestOAuthTokenCompleted; mixerInteractiveHelper.OnInternalWebRequestStateChanged += OnRequestOAuthTokenCompleted; - mixerInteractiveHelper.MakeWebRequest( + mixerInteractiveHelper._MakeWebRequest( "OnRequestOAuthTokenCompleted", API_GET_OAUTH_TOKEN_PATH, new Dictionary() @@ -587,7 +587,7 @@ private void GetOauthToken(string exchangeCode) ); } - private void OnRequestOAuthTokenCompleted(object sender, MixerInteractiveHelper.InternalWebRequestStateChangedEventArgs e) + private void OnRequestOAuthTokenCompleted(object sender, MixerInteractiveHelper._InternalWebRequestStateChangedEventArgs e) { if (e.RequestID != "OnRequestOAuthTokenCompleted") { @@ -600,7 +600,7 @@ private void OnRequestOAuthTokenCompleted(object sender, MixerInteractiveHelper. } else { - LogError("Error: Failed to request an OAuth token. Error message: " + e.ErrorMessage); + _LogError("Error: Failed to request an OAuth token. Error message: " + e.ErrorMessage); } } @@ -608,7 +608,7 @@ private void CompleteGetOAuthToken(long statusCode, string getCodeServerResponse { if (statusCode == 400) { - LogError("Error: " + getCodeServerResponse + " while requesting an OAuth token."); + _LogError("Error: " + getCodeServerResponse + " while requesting an OAuth token."); return; } string refreshToken = string.Empty; @@ -638,7 +638,7 @@ private void CompleteGetOAuthToken(long statusCode, string getCodeServerResponse mixerInteractiveHelper.WriteAuthTokensToCache(_authToken, _oauthRefreshToken); - Log("Retrieved a new OAuth token. Token: " + _authToken); + _Log("Retrieved a new OAuth token. Token: " + _authToken); mixerInteractiveHelper.StopTimer(MixerInteractiveHelper.InteractiveTimerType.RefreshShortCode); mixerInteractiveHelper.StopTimer(MixerInteractiveHelper.InteractiveTimerType.CheckAuthStatus); @@ -651,7 +651,7 @@ private void RefreshShortCode() string postData = "{ \"client_id\": \"" + AppID + "\", \"scope\": \"interactive:robot:self\" }"; mixerInteractiveHelper.OnInternalWebRequestStateChanged -= OnRequestRefresheShortCodeCompleted; mixerInteractiveHelper.OnInternalWebRequestStateChanged += OnRequestRefresheShortCodeCompleted; - mixerInteractiveHelper.MakeWebRequest( + mixerInteractiveHelper._MakeWebRequest( "OnRequestRefresheShortCodeCompleted", API_GET_SHORT_CODE_PATH, new Dictionary() @@ -663,7 +663,7 @@ private void RefreshShortCode() ); } - private void OnRequestRefresheShortCodeCompleted(object sender, MixerInteractiveHelper.InternalWebRequestStateChangedEventArgs e) + private void OnRequestRefresheShortCodeCompleted(object sender, MixerInteractiveHelper._InternalWebRequestStateChangedEventArgs e) { if (e.RequestID != "OnRequestRefresheShortCodeCompleted") { @@ -674,14 +674,14 @@ private void OnRequestRefresheShortCodeCompleted(object sender, MixerInteractive { if (e.ResponseCode == 404) { - LogError("Error: OAuth Client ID not found. Make sure the OAuth Client ID you specified in the Unity editor matches the one in Interactive Studio."); + _LogError("Error: OAuth Client ID not found. Make sure the OAuth Client ID you specified in the Unity editor matches the one in Interactive Studio."); return; } CompleteRefreshShortCode(e.ResponseText); } else { - LogError("Error: Failed to retrieve a short code for short code authentication. Error message: " + e.ErrorMessage); + _LogError("Error: Failed to retrieve a short code for short code authentication. Error message: " + e.ErrorMessage); } } @@ -750,7 +750,7 @@ private void VerifyAuthToken() { mixerInteractiveHelper.OnInternalWebRequestStateChanged -= OnVerifyAuthTokenRequestCompleted; mixerInteractiveHelper.OnInternalWebRequestStateChanged += OnVerifyAuthTokenRequestCompleted; - mixerInteractiveHelper.MakeWebRequest( + mixerInteractiveHelper._MakeWebRequest( "OnVerifyAuthTokenRequestCompleted", _interactiveWebSocketUrl.Replace("wss", "https"), new Dictionary() @@ -763,7 +763,7 @@ private void VerifyAuthToken() return; } - private void OnVerifyAuthTokenRequestCompleted(object sender, MixerInteractiveHelper.InternalWebRequestStateChangedEventArgs e) + private void OnVerifyAuthTokenRequestCompleted(object sender, MixerInteractiveHelper._InternalWebRequestStateChangedEventArgs e) { if (e.RequestID != "OnVerifyAuthTokenRequestCompleted") { @@ -786,13 +786,13 @@ private void OnVerifyAuthTokenRequestCompleted(object sender, MixerInteractiveHe } else { - LogError("Error: Failed to while trying to validate a cached auth token. Error code: " + e.ResponseCode); + _LogError("Error: Failed to while trying to validate a cached auth token. Error code: " + e.ResponseCode); } CompleteVerifyAuthTokenRequestStart(isTokenValid); } else { - LogError("Error: Failed to verify the auth token. Error message: " + e.ErrorMessage); + _LogError("Error: Failed to verify the auth token. Error message: " + e.ErrorMessage); } } @@ -827,7 +827,7 @@ private void ConnectToWebsocket() { shareCodeDebugLogString = ", Share Code: " + ShareCode; } - Log("Connecting to websocket with Project Version ID: " + ProjectVersionID + + _Log("Connecting to websocket with Project Version ID: " + ProjectVersionID + shareCodeDebugLogString + ", OAuth Client ID: " + AppID + " and Auth Token: " + _authToken + "."); @@ -932,7 +932,7 @@ private void OnWebSocketError(object sender, WebSocketSharp.ErrorEventArgs args) #endif { UpdateInteractivityState(InteractivityState.InteractivityDisabled); - LogError("Error: Websocket OnError: " + args.Message); + _LogError("Error: Websocket OnError: " + args.Message); } #if UNITY_WSA && !UNITY_EDITOR @@ -946,17 +946,17 @@ private void OnWebSocketClose(object sender, WebSocketSharp.CloseEventArgs args) UpdateInteractivityState(InteractivityState.InteractivityDisabled); if (args.Code == 4019) { - LogError("Connection failed (error code 4019): You don't have access to this project. Make sure that the account you are signed in with has " + + _LogError("Connection failed (error code 4019): You don't have access to this project. Make sure that the account you are signed in with has " + "access to this Version ID. If you are using a share code, make sure that the share code value matches the one in Interactive Studio for this project."); } else if (args.Code == 4020) { - LogError("Connection failed (error code 4020): The interactive version was not found or you do not have access to it. Make sure that the account you are signed in with has " + + _LogError("Connection failed (error code 4020): The interactive version was not found or you do not have access to it. Make sure that the account you are signed in with has " + "access to this Version ID. If you are using a share code, make sure that the share code value matches the one in Interactive Studio for this project."); } else if (args.Code == 4021) { - LogError("Connection failed (error code 4021): You are connected to this session somewhere else. Please disconnect from that session and try again."); + _LogError("Connection failed (error code 4021): You are connected to this session somewhere else. Please disconnect from that session and try again."); } else { @@ -980,7 +980,7 @@ private void RefreshAuthToken() string postData = "{ \"client_id\": \"" + AppID + "\", \"refresh_token\": \"" + _oauthRefreshToken + "\", \"grant_type\": \"refresh_token\" }"; mixerInteractiveHelper.OnInternalWebRequestStateChanged -= OnRequestRefreshedAuthTokenCompleted; mixerInteractiveHelper.OnInternalWebRequestStateChanged += OnRequestRefreshedAuthTokenCompleted; - mixerInteractiveHelper.MakeWebRequest( + mixerInteractiveHelper._MakeWebRequest( "OnRequestRefreshedAuthTokenCompleted", API_GET_OAUTH_TOKEN_PATH, new Dictionary() @@ -992,7 +992,7 @@ private void RefreshAuthToken() ); } - private void OnRequestRefreshedAuthTokenCompleted(object sender, MixerInteractiveHelper.InternalWebRequestStateChangedEventArgs e) + private void OnRequestRefreshedAuthTokenCompleted(object sender, MixerInteractiveHelper._InternalWebRequestStateChangedEventArgs e) { if (e.RequestID != "OnRequestRefreshedAuthTokenCompleted") { @@ -1005,7 +1005,7 @@ private void OnRequestRefreshedAuthTokenCompleted(object sender, MixerInteractiv } else { - LogError("Error: Web request to refresh the Auth token failed. Error message: " + e.ErrorMessage); + _LogError("Error: Web request to refresh the Auth token failed. Error message: " + e.ErrorMessage); } } @@ -1013,7 +1013,7 @@ private void CompleteRefreshAuthToken(long statusCode, string getCodeServerRespo { if (statusCode == 400) { - LogError("Error: " + getCodeServerResponse + " trying to refresh the auth token."); + _LogError("Error: " + getCodeServerResponse + " trying to refresh the auth token."); } string accessToken = string.Empty; string refreshToken = string.Empty; @@ -1054,7 +1054,7 @@ private void UpdateInteractivityState(InteractivityState state) private InteractiveControl ControlFromControlID(string controlID) { - var controls = Controls; + var controls = _Controls; foreach (InteractiveControl control in controls) { if (control.ControlID == controlID) @@ -1073,7 +1073,7 @@ internal void CaptureTransaction(string transactionID) { return; } - SendCaptureTransactionMessage(transactionID); + _SendCaptureTransactionMessage(transactionID); } /// @@ -1090,7 +1090,7 @@ public void TriggerCooldown(string controlID, int cooldown) if (cooldown < 1000) { - Log("Info: Did you mean to use a cooldown of " + (float)cooldown / 1000 + " seconds? Remember, cooldowns are in milliseconds."); + _Log("Info: Did you mean to use a cooldown of " + (float)cooldown / 1000 + " seconds? Remember, cooldowns are in milliseconds."); } // Get the control from our data structure to find it's etag @@ -1102,11 +1102,11 @@ public void TriggerCooldown(string controlID, int cooldown) InteractiveButtonControl button = control as InteractiveButtonControl; if (button != null) { - controlSceneID = control.SceneID; + controlSceneID = control._sceneID; } else { - LogError("Error: The control is not a button. You can only trigger a cooldown on a button."); + _LogError("Error: The control is not a button. You can only trigger a cooldown on a button."); return; } } @@ -1123,7 +1123,7 @@ public void TriggerCooldown(string controlID, int cooldown) var controlAsButton = control as InteractiveButtonControl; if (controlAsButton != null) { - controlAsButton.cooldownExpirationTime = computedCooldown; + controlAsButton._cooldownExpirationTime = computedCooldown; } // Send an update control message @@ -1326,9 +1326,15 @@ private void RaiseQueuedInteractiveEvents() } } _queuedEvents.Clear(); + + // Raise an event for any other controls listening for DoWork. + if (OnInteractiveDoWorkEvent != null) + { + OnInteractiveDoWorkEvent(this, new InteractiveEventArgs()); + } } - public void SendQueuedSetControlPropertyUpdates() + private void SendQueuedSetControlPropertyUpdates() { var sceneKeys = _queuedControlPropertyUpdates.Keys; foreach (string sceneID in sceneKeys) @@ -1359,17 +1365,17 @@ public void SendQueuedSetControlPropertyUpdates() jsonWriter.WriteStartObject(); jsonWriter.WritePropertyName(WS_MESSAGE_KEY_CONTROL_ID); jsonWriter.WriteValue(controlID); - Dictionary controlPropertyData = _queuedControlPropertyUpdates[sceneID][controlID].properties; + Dictionary controlPropertyData = _queuedControlPropertyUpdates[sceneID][controlID].properties; var controlPropertyDataKeys = controlPropertyData.Keys; foreach (string controlPropertyDataKey in controlPropertyDataKeys) { jsonWriter.WritePropertyName(controlPropertyDataKey); - InternalControlPropertyMetaData controlPropertyMetaData = controlPropertyData[controlPropertyDataKey]; - if (controlPropertyMetaData.type == KnownControlPropertyPrimitiveTypes.Boolean) + _InternalControlPropertyMetaData controlPropertyMetaData = controlPropertyData[controlPropertyDataKey]; + if (controlPropertyMetaData.type == _KnownControlPropertyPrimitiveTypes.Boolean) { jsonWriter.WriteValue(controlPropertyMetaData.boolValue); } - else if (controlPropertyMetaData.type == KnownControlPropertyPrimitiveTypes.Number) + else if (controlPropertyMetaData.type == _KnownControlPropertyPrimitiveTypes.Number) { jsonWriter.WriteValue(controlPropertyMetaData.numberValue); } @@ -1461,9 +1467,9 @@ private void ProcessWebSocketMessage(string messageText) } catch { - LogError("Error: Failed to process message: " + messageText); + _LogError("Error: Failed to process message: " + messageText); } - Log(messageText); + _Log(messageText); _queuedEvents.Add(new InteractiveMessageEventArgs(messageText)); } @@ -1520,14 +1526,14 @@ private void ProcessMethod(JsonReader jsonReader) } catch (Exception ex) { - LogError("Error: Error while processing method: " + methodName + ". Error message: " + ex.Message); + _LogError("Error: Error while processing method: " + methodName + ". Error message: " + ex.Message); } } } } catch (Exception ex) { - LogError("Error: Error processing websocket message. Error message: " + ex.Message); + _LogError("Error: Error processing websocket message. Error message: " + ex.Message); } } @@ -1553,7 +1559,7 @@ private void ProcessReply(JsonReader jsonReader, int messageIDAsInt) } catch { - LogError("Error: Failed to get the message ID from the reply message."); + _LogError("Error: Failed to get the message ID from the reply message."); } } string replyMessgeMethod = string.Empty; @@ -1581,7 +1587,7 @@ private void ProcessReply(JsonReader jsonReader, int messageIDAsInt) } catch { - LogError("Error: An error occured while processing the reply: " + replyMessgeMethod); + _LogError("Error: An error occured while processing the reply: " + replyMessgeMethod); } } @@ -1623,7 +1629,7 @@ private void HandlePossibleError(JsonReader jsonReader) if (errorCode != 0 && errorMessage != string.Empty) { - LogError(errorMessage, errorCode); + _LogError(errorMessage, errorCode); } } @@ -1700,7 +1706,7 @@ private void UpdateControls(JsonReader jsonReader, string sceneID) { var updatedControl = ReadControl(jsonReader, sceneID); InteractiveControl oldControl = null; - var controls = Controls; + var controls = _Controls; foreach (InteractiveControl control in controls) { if (control.ControlID == updatedControl.ControlID) @@ -1739,7 +1745,7 @@ private void UpdateControls(JsonReader jsonReader, string sceneID) } catch { - LogError("Error: Failed reading controls for scene: " + sceneID + "."); + _LogError("Error: Failed reading controls for scene: " + sceneID + "."); } } @@ -1804,7 +1810,7 @@ private void ProcessGroups(JsonReader jsonReader) private void CloneGroupValues(InteractiveGroup source, InteractiveGroup destination) { - destination.etag = source.etag; + destination._etag = source._etag; destination.SceneID = source.SceneID; destination.GroupID = source.GroupID; } @@ -1854,7 +1860,7 @@ private List ReadParticipants(JsonReader jsonReader) private void CloneParticipantValues(InteractiveParticipant source, InteractiveParticipant destination) { - destination.sessionID = source.sessionID; + destination._sessionID = source._sessionID; destination.UserID = source.UserID; destination.UserName = source.UserName; destination.Level = source.Level; @@ -1862,8 +1868,8 @@ private void CloneParticipantValues(InteractiveParticipant source, InteractivePa destination.ConnectedAt = source.ConnectedAt; destination.InputDisabled = source.InputDisabled; destination.State = source.State; - destination.groupID = source.groupID; - destination.etag = source.etag; + destination._groupID = source._groupID; + destination._etag = source._etag; } private InteractiveParticipant ReadParticipant(JsonReader jsonReader) @@ -2046,6 +2052,50 @@ private InteractiveGroup ReadGroup(JsonReader jsonReader) return new InteractiveGroup(etag, sceneID, groupID); } + private Dictionary ReadMetaProperties(JsonReader jsonReader) + { + Dictionary metaProperties = new Dictionary(); + while (jsonReader.Read()) + { + if (jsonReader.TokenType == JsonToken.EndObject) + { + break; + } + if (jsonReader.Value != null) + { + string metaPropertyKey = jsonReader.Value.ToString(); + ReadMetaProperty(jsonReader, metaPropertyKey, metaProperties); + } + } + return metaProperties; + } + + private void ReadMetaProperty(JsonReader jsonReader, string metaPropertyKey, Dictionary metaProperties) + { + string metaPropertValue = string.Empty; + while (jsonReader.Read()) + { + if (jsonReader.TokenType == JsonToken.EndObject || + metaPropertValue != string.Empty) + { + break; + } + if (jsonReader.Value != null) + { + string key = jsonReader.Value.ToString(); + if (key == WS_MESSAGE_KEY_VALUE) + { + jsonReader.Read(); + if (jsonReader.Value != null) + { + metaPropertValue = jsonReader.Value.ToString(); + } + } + } + } + metaProperties.Add(metaPropertyKey, metaPropertValue); + } + private void HandleGetScenes(JsonReader jsonReader) { while (jsonReader.Read()) @@ -2108,7 +2158,7 @@ private InteractiveScene ReadScene(JsonReader jsonReader) jsonReader.ReadAsString(); if (jsonReader.Value != null) { - scene.etag = jsonReader.Value.ToString(); + scene._etag = jsonReader.Value.ToString(); } break; case WS_MESSAGE_KEY_CONTROLS: @@ -2123,7 +2173,7 @@ private InteractiveScene ReadScene(JsonReader jsonReader) } catch { - LogError("Error: Error reading scene " + scene.SceneID + "."); + _LogError("Error: Error reading scene " + scene.SceneID + "."); } return scene; @@ -2155,7 +2205,7 @@ private void ReadControls(JsonReader jsonReader, InteractiveScene scene) } catch { - LogError("Error: Failed reading controls for scene: " + scene.SceneID + "."); + _LogError("Error: Failed reading controls for scene: " + scene.SceneID + "."); } } @@ -2169,6 +2219,7 @@ private InteractiveControl ReadControl(JsonReader jsonReader, string sceneID = " string text = string.Empty; string eTag = string.Empty; string kind = string.Empty; + Dictionary metaProperties = new Dictionary(); try { while (jsonReader.Read() && jsonReader.Depth > startDepth) @@ -2186,7 +2237,7 @@ private InteractiveControl ReadControl(JsonReader jsonReader, string sceneID = " jsonReader.ReadAsBoolean(); disabled = (bool)jsonReader.Value; break; - case WS_MESSAGE_KEY_TEXT: + case _WS_MESSAGE_KEY_TEXT: jsonReader.Read(); text = jsonReader.Value.ToString(); break; @@ -2198,10 +2249,20 @@ private InteractiveControl ReadControl(JsonReader jsonReader, string sceneID = " jsonReader.Read(); kind = jsonReader.Value.ToString(); break; - case WS_MESSAGE_KEY_COST: + case _WS_MESSAGE_KEY_COST: jsonReader.ReadAsInt32(); cost = Convert.ToUInt32(jsonReader.Value); break; + case WS_MESSAGE_KEY_META: + while (jsonReader.Read()) + { + if (jsonReader.TokenType == JsonToken.StartObject) + { + metaProperties = ReadMetaProperties(jsonReader); + break; + } + } + break; default: // No-op break; @@ -2211,34 +2272,34 @@ private InteractiveControl ReadControl(JsonReader jsonReader, string sceneID = " } catch { - LogError("Error: Error reading control " + controlID + "."); + _LogError("Error: Error reading control " + controlID + "."); } - if (kind == WS_MESSAGE_VALUE_CONTROL_TYPE_BUTTON) + if (kind == _WS_MESSAGE_VALUE_CONTROL_TYPE_BUTTON) { - newControl = new InteractiveButtonControl(controlID, InteractiveEventType.Button, disabled, text, cost, eTag, sceneID); + newControl = new InteractiveButtonControl(controlID, InteractiveEventType.Button, disabled, text, cost, eTag, sceneID, metaProperties); } - else if (kind == WS_MESSAGE_VALUE_CONTROL_TYPE_JOYSTICK) + else if (kind == _WS_MESSAGE_VALUE_CONTROL_TYPE_JOYSTICK) { - newControl = new InteractiveJoystickControl(controlID, InteractiveEventType.Joystick, disabled, text, eTag, sceneID); + newControl = new InteractiveJoystickControl(controlID, InteractiveEventType.Joystick, disabled, text, eTag, sceneID, metaProperties); } - else if (kind == WS_MESSAGE_VALUE_CONTROL_TYPE_TEXTBOX) + else if (kind == _WS_MESSAGE_VALUE_CONTROL_TYPE_TEXTBOX) { - newControl = new InteractiveTextControl(controlID, InteractiveEventType.TextInput, disabled, text, eTag, sceneID); + newControl = new InteractiveTextControl(controlID, InteractiveEventType.TextInput, disabled, text, eTag, sceneID, metaProperties); } - else if (kind == WS_MESSAGE_VALUE_CONTROL_TYPE_LABEL) + else if (kind == _WS_MESSAGE_VALUE_CONTROL_TYPE_LABEL) { newControl = new InteractiveLabelControl(controlID, text, sceneID); } else { - newControl = new InteractiveControl(controlID, kind, InteractiveEventType.Unknown, disabled, text, eTag, sceneID); + newControl = new InteractiveControl(controlID, kind, InteractiveEventType.Unknown, disabled, text, eTag, sceneID, metaProperties); } return newControl; } - private InputEvent ReadInputObject(JsonReader jsonReader) + private _InputEvent ReadInputObject(JsonReader jsonReader) { - InputEvent inputEvent = new InputEvent(); + _InputEvent inputEvent = new _InputEvent(); while (jsonReader.Read()) { if (jsonReader.TokenType == JsonToken.StartObject) @@ -2249,12 +2310,11 @@ private InputEvent ReadInputObject(JsonReader jsonReader) return inputEvent; } - private InputEvent ReadInputInnerObject(JsonReader jsonReader) + private _InputEvent ReadInputInnerObject(JsonReader jsonReader) { int startDepth = jsonReader.Depth; string controlID = string.Empty; string eventName = string.Empty; - string kind = string.Empty; object rawValue = null; bool isPressed = false; float x = 0; @@ -2277,19 +2337,19 @@ private InputEvent ReadInputInnerObject(JsonReader jsonReader) } break; case WS_MESSAGE_KEY_EVENT: - string eventValue = jsonReader.ReadAsString(); - if (eventValue == EVENT_NAME_MOUSE_DOWN || - eventValue == EVENT_NAME_MOUSE_UP || - eventValue == EVENT_NAME_KEY_DOWN || - eventValue == EVENT_NAME_KEY_UP) + eventName = jsonReader.ReadAsString(); + if (eventName == EVENT_NAME_MOUSE_DOWN || + eventName == EVENT_NAME_MOUSE_UP || + eventName == EVENT_NAME_KEY_DOWN || + eventName == EVENT_NAME_KEY_UP) { - if (eventValue == EVENT_NAME_MOUSE_DOWN || - eventValue == EVENT_NAME_KEY_DOWN) + if (eventName == EVENT_NAME_MOUSE_DOWN || + eventName == EVENT_NAME_KEY_DOWN) { isPressed = true; } - else if (eventValue == EVENT_NAME_MOUSE_UP || - eventValue == EVENT_NAME_KEY_UP) + else if (eventName == EVENT_NAME_MOUSE_UP || + eventName == EVENT_NAME_KEY_UP) { isPressed = false; } @@ -2301,10 +2361,6 @@ private InputEvent ReadInputInnerObject(JsonReader jsonReader) case WS_MESSAGE_KEY_Y: y = (float)jsonReader.ReadAsDouble(); break; - case WS_MESSAGE_KEY_KIND: - jsonReader.Read(); - kind = jsonReader.Value.ToString(); - break; case WS_MESSAGE_KEY_VALUE: jsonReader.Read(); rawValue = jsonReader.Value; @@ -2327,7 +2383,7 @@ private InputEvent ReadInputInnerObject(JsonReader jsonReader) } catch { - LogError("Error: Error reading input from control " + controlID + "."); + _LogError("Error: Error reading input from control " + controlID + "."); } uint cost = 0; InteractiveControl control = ControlFromControlID(controlID); @@ -2341,7 +2397,7 @@ private InputEvent ReadInputInnerObject(JsonReader jsonReader) { textValue = rawValue.ToString(); } - return new InputEvent(controlID, control.Kind, eventName, controlType, isPressed, x, y, cost, string.Empty, textValue, rawValue); + return new _InputEvent(controlID, control._kind, eventName, controlType, isPressed, x, y, cost, string.Empty, textValue); } private void HandleParticipantJoin(JsonReader jsonReader) @@ -2405,7 +2461,7 @@ private void HandleParticipantLeave(JsonReader jsonReader) } catch { - LogError("Error: Error while processing participant leave message."); + _LogError("Error: Error while processing participant leave message."); } } @@ -2428,7 +2484,7 @@ private void HandleParticipantUpdate(JsonReader jsonReader) } } } - internal struct InputEvent + internal struct _InputEvent { internal string ControlID; internal string Kind; @@ -2442,9 +2498,8 @@ internal struct InputEvent internal float X; internal float Y; internal string TextValue; - object Value; - internal InputEvent( + internal _InputEvent( string controlID, string kind, string eventName, @@ -2454,8 +2509,7 @@ internal InputEvent( float y, uint cost, string transactionID, - string textValue, - object value + string textValue ) { ControlID = controlID; @@ -2468,7 +2522,6 @@ object value X = x; Y = y; TextValue = textValue; - Value = value; } }; @@ -2476,7 +2529,7 @@ private void HandleGiveInput(JsonReader jsonReader) { string participantSessionID = string.Empty; string transactionID = string.Empty; - InputEvent inputEvent = new InputEvent(); + _InputEvent inputEvent = new _InputEvent(); while (jsonReader.Read()) { @@ -2515,7 +2568,7 @@ private void HandleGiveInput(JsonReader jsonReader) InteractiveParticipant participant = ParticipantBySessionId(participantSessionID); if (!_participantsWhoTriggeredGiveInput.ContainsKey(inputEvent.ControlID)) { - _participantsWhoTriggeredGiveInput.Add(inputEvent.ControlID, new InternalParticipantTrackingState(participant)); + _participantsWhoTriggeredGiveInput.Add(inputEvent.ControlID, new _InternalParticipantTrackingState(participant)); } participant.LastInputAt = DateTime.UtcNow; if (inputEvent.Type == InteractiveEventType.Button) @@ -2540,15 +2593,15 @@ private void HandleGiveInput(JsonReader jsonReader) uint participantID = participant.UserID; // Handle screen input - if (inputEvent.Kind == CONTROL_KIND_SCREEN) + if (inputEvent.Kind == _CONTROL_KIND_SCREEN) { // Update x, y coordinates if (inputEvent.Event == EVENT_NAME_MOVE) { Vector2 newMousePosition = new Vector2(inputEvent.X, inputEvent.Y); // Translate the position to screen space. - newMousePosition.x *= Screen.width; - newMousePosition.y *= Screen.height; + newMousePosition.x = newMousePosition.x * Screen.width; + newMousePosition.y = newMousePosition.y * Screen.height; if (_mousePositionsByParticipant.ContainsKey(participantID)) { _mousePositionsByParticipant[participantID] = newMousePosition; @@ -2567,10 +2620,15 @@ private void HandleGiveInput(JsonReader jsonReader) else if (inputEvent.Event == EVENT_NAME_MOUSE_DOWN || inputEvent.Event == EVENT_NAME_MOUSE_UP) { + Vector2 newMousePosition = new Vector2(inputEvent.X, inputEvent.Y); + // Translate the position to screen space. + newMousePosition.x = newMousePosition.x * Screen.width; + newMousePosition.y = newMousePosition.y * Screen.height; InteractiveMouseButtonEventArgs mouseButtonEventArgs = new InteractiveMouseButtonEventArgs( inputEvent.ControlID, participant, - inputEvent.IsPressed + inputEvent.IsPressed, + newMousePosition ); _queuedEvents.Add(mouseButtonEventArgs); UpdateInternalMouseButtonState(mouseButtonEventArgs); @@ -2635,7 +2693,7 @@ private InteractiveParticipant ParticipantBySessionId(string sessionID) var existingParticipants = Participants; foreach (InteractiveParticipant participant in existingParticipants) { - if (participant.sessionID == sessionID) + if (participant._sessionID == sessionID) { target = participant; break; @@ -2644,7 +2702,7 @@ private InteractiveParticipant ParticipantBySessionId(string sessionID) return target; } - internal InteractiveParticipant ParticipantByUserId(uint userID) + internal InteractiveParticipant _ParticipantByUserId(uint userID) { InteractiveParticipant target = null; var existingParticipants = Participants; @@ -2659,16 +2717,16 @@ internal InteractiveParticipant ParticipantByUserId(uint userID) return target; } - internal bool GetButtonDown(string controlID, uint userID) + internal bool _GetButtonDown(string controlID, uint userID) { bool getButtonDownResult = false; bool participantExists = false; - Dictionary participantControls; + Dictionary participantControls; participantExists = _buttonStatesByParticipant.TryGetValue(userID, out participantControls); if (participantExists) { bool controlExists = false; - InternalButtonState buttonState; + _InternalButtonState buttonState; controlExists = participantControls.TryGetValue(controlID, out buttonState); if (controlExists) { @@ -2682,16 +2740,16 @@ internal bool GetButtonDown(string controlID, uint userID) return getButtonDownResult; } - internal bool GetButtonPressed(string controlID, uint userID) + internal bool _GetButtonPressed(string controlID, uint userID) { bool getButtonResult = false; bool participantExists = false; - Dictionary participantControls; + Dictionary participantControls; participantExists = _buttonStatesByParticipant.TryGetValue(userID, out participantControls); if (participantExists) { bool controlExists = false; - InternalButtonState buttonState; + _InternalButtonState buttonState; controlExists = participantControls.TryGetValue(controlID, out buttonState); if (controlExists) { @@ -2705,16 +2763,16 @@ internal bool GetButtonPressed(string controlID, uint userID) return getButtonResult; } - internal bool GetButtonUp(string controlID, uint userID) + internal bool _GetButtonUp(string controlID, uint userID) { bool getButtonUpResult = false; bool participantExists = false; - Dictionary participantControls; + Dictionary participantControls; participantExists = _buttonStatesByParticipant.TryGetValue(userID, out participantControls); if (participantExists) { bool controlExists = false; - InternalButtonState buttonState; + _InternalButtonState buttonState; controlExists = participantControls.TryGetValue(controlID, out buttonState); if (controlExists) { @@ -2728,16 +2786,16 @@ internal bool GetButtonUp(string controlID, uint userID) return getButtonUpResult; } - internal uint GetCountOfButtonDowns(string controlID, uint userID) + internal uint _GetCountOfButtonDowns(string controlID, uint userID) { uint countOfButtonDownEvents = 0; bool participantExists = false; - Dictionary participantControls; + Dictionary participantControls; participantExists = _buttonStatesByParticipant.TryGetValue(userID, out participantControls); if (participantExists) { bool controlExists = false; - InternalButtonState buttonState; + _InternalButtonState buttonState; controlExists = participantControls.TryGetValue(controlID, out buttonState); if (controlExists) { @@ -2747,16 +2805,16 @@ internal uint GetCountOfButtonDowns(string controlID, uint userID) return countOfButtonDownEvents; } - internal uint GetCountOfButtonPresses(string controlID, uint userID) + internal uint _GetCountOfButtonPresses(string controlID, uint userID) { uint countOfButtonPressEvents = 0; bool participantExists = false; - Dictionary participantControls; + Dictionary participantControls; participantExists = _buttonStatesByParticipant.TryGetValue(userID, out participantControls); if (participantExists) { bool controlExists = false; - InternalButtonState buttonState; + _InternalButtonState buttonState; controlExists = participantControls.TryGetValue(controlID, out buttonState); if (controlExists) { @@ -2766,12 +2824,12 @@ internal uint GetCountOfButtonPresses(string controlID, uint userID) return countOfButtonPressEvents; } - internal uint GetCountOfButtonUps(string controlID, uint userID) + internal uint _GetCountOfButtonUps(string controlID, uint userID) { uint countOfButtonUpEvents = 0; - InternalButtonState buttonState; + _InternalButtonState buttonState; bool participantExists = false; - Dictionary participantControls; + Dictionary participantControls; participantExists = _buttonStatesByParticipant.TryGetValue(userID, out participantControls); if (participantExists) { @@ -2785,12 +2843,12 @@ internal uint GetCountOfButtonUps(string controlID, uint userID) return countOfButtonUpEvents; } - internal bool TryGetButtonStateByParticipant(uint userID, string controlID, out InternalButtonState buttonState) + internal bool _TryGetButtonStateByParticipant(uint userID, string controlID, out _InternalButtonState buttonState) { - buttonState = new InternalButtonState(); + buttonState = new _InternalButtonState(); bool buttonExists = false; bool participantExists = false; - Dictionary participantControls; + Dictionary participantControls; participantExists = _buttonStatesByParticipant.TryGetValue(userID, out participantControls); if (participantExists) { @@ -2804,9 +2862,9 @@ internal bool TryGetButtonStateByParticipant(uint userID, string controlID, out return buttonExists; } - internal InteractiveJoystickControl GetJoystick(string controlID, uint userID) + internal InteractiveJoystickControl _GetJoystick(string controlID, uint userID) { - InteractiveJoystickControl joystick = new InteractiveJoystickControl(controlID, InteractiveEventType.Joystick, true, string.Empty, string.Empty, string.Empty); + InteractiveJoystickControl joystick = new InteractiveJoystickControl(controlID, InteractiveEventType.Joystick, true, string.Empty, string.Empty, string.Empty, new Dictionary()); var joysticks = Joysticks; foreach (InteractiveJoystickControl potential in joysticks) { @@ -2815,14 +2873,14 @@ internal InteractiveJoystickControl GetJoystick(string controlID, uint userID) joystick = potential; } } - joystick.UserID = userID; + joystick._userID = userID; return joystick; } - internal double GetJoystickX(string controlID, uint userID) + internal double _GetJoystickX(string controlID, uint userID) { double joystickX = 0; - InternalJoystickState joystickState; + _InternalJoystickState joystickState; if (TryGetJoystickStateByParticipant(userID, controlID, out joystickState)) { joystickX = joystickState.X; @@ -2830,10 +2888,10 @@ internal double GetJoystickX(string controlID, uint userID) return joystickX; } - internal double GetJoystickY(string controlID, uint userID) + internal double _GetJoystickY(string controlID, uint userID) { double joystickY = 0; - InternalJoystickState joystickState; + _InternalJoystickState joystickState; if (TryGetJoystickStateByParticipant(userID, controlID, out joystickState)) { joystickY = joystickState.Y; @@ -2841,12 +2899,12 @@ internal double GetJoystickY(string controlID, uint userID) return joystickY; } - private bool TryGetJoystickStateByParticipant(uint userID, string controlID, out InternalJoystickState joystickState) + private bool TryGetJoystickStateByParticipant(uint userID, string controlID, out _InternalJoystickState joystickState) { - joystickState = new InternalJoystickState(); + joystickState = new _InternalJoystickState(); bool joystickExists = false; bool participantExists = false; - Dictionary participantControls; + Dictionary participantControls; participantExists = _joystickStatesByParticipant.TryGetValue(userID, out participantControls); if (participantExists) { @@ -2860,9 +2918,9 @@ private bool TryGetJoystickStateByParticipant(uint userID, string controlID, out return joystickExists; } - internal InternalMouseButtonState TryGetMouseButtonState(uint userID) + internal _InternalMouseButtonState TryGetMouseButtonState(uint userID) { - InternalMouseButtonState mouseButtonState = new InternalMouseButtonState(); + _InternalMouseButtonState mouseButtonState = new _InternalMouseButtonState(); _mouseButtonStateByParticipant.TryGetValue(userID, out mouseButtonState); return mouseButtonState; } @@ -2879,10 +2937,10 @@ internal string GetText(string controlID, uint userID) return text; } - internal InteractiveControl GetControl(string controlID) + internal InteractiveControl _GetControl(string controlID) { - InteractiveControl control = new InteractiveControl(controlID, "", InteractiveEventType.Unknown, true, "", "", ""); - var controls = Controls; + InteractiveControl control = new InteractiveControl(controlID, "", InteractiveEventType.Unknown, true, "", "", "", new Dictionary()); + var controls = _Controls; foreach (InteractiveControl currentControl in controls) { if (currentControl.ControlID == controlID) @@ -2901,7 +2959,7 @@ internal InteractiveControl GetControl(string controlID) /// public InteractiveButtonControl GetButton(string controlID) { - InteractiveButtonControl buttonControl = new InteractiveButtonControl(controlID, InteractiveEventType.Button, false, string.Empty, 0, string.Empty, string.Empty); + InteractiveButtonControl buttonControl = new InteractiveButtonControl(controlID, InteractiveEventType.Button, false, string.Empty, 0, string.Empty, string.Empty, new Dictionary()); var buttons = Buttons; foreach (InteractiveButtonControl currentButtonControl in buttons) { @@ -2921,7 +2979,7 @@ public InteractiveButtonControl GetButton(string controlID) /// public InteractiveJoystickControl GetJoystick(string controlID) { - InteractiveJoystickControl joystickControl = new InteractiveJoystickControl(controlID, InteractiveEventType.Joystick, true, "", "", ""); + InteractiveJoystickControl joystickControl = new InteractiveJoystickControl(controlID, InteractiveEventType.Joystick, true, "", "", "", new Dictionary()); var joysticks = Joysticks; foreach (InteractiveJoystickControl currentJoystick in joysticks) { @@ -2940,7 +2998,7 @@ public InteractiveJoystickControl GetJoystick(string controlID) /// public string GetCurrentScene() { - InteractiveGroup group = GroupFromID(WS_MESSAGE_VALUE_DEFAULT_GROUP_ID); + InteractiveGroup group = GroupFromID(_WS_MESSAGE_VALUE_DEFAULT_GROUP_ID); return group.SceneID; } @@ -2950,14 +3008,14 @@ public string GetCurrentScene() /// The ID of the scene to change to. public void SetCurrentScene(string sceneID) { - InteractiveGroup defaultGroup = GroupFromID(WS_MESSAGE_VALUE_DEFAULT_GROUP_ID); + InteractiveGroup defaultGroup = GroupFromID(_WS_MESSAGE_VALUE_DEFAULT_GROUP_ID); if (defaultGroup != null) { defaultGroup.SetScene(sceneID); } } - internal IList GetText(string controlID) + internal IList _GetText(string controlID) { List interactiveTextResults = new List(); InteractivityManager interactivityManager = InteractivityManager.SingletonInstance; @@ -2969,21 +3027,21 @@ internal IList GetText(string controlID) string text = string.Empty; textboxValues.TryGetValue(controlID, out text); var newTextResult = new InteractiveTextResult(); - newTextResult.Participant = interactivityManager.ParticipantByUserId(participantUserId); + newTextResult.Participant = interactivityManager._ParticipantByUserId(participantUserId); newTextResult.Text = text; interactiveTextResults.Add(newTextResult); } return interactiveTextResults; } - internal void SetCurrentSceneInternal(InteractiveGroup group, string sceneID) + internal void _SetCurrentSceneInternal(InteractiveGroup group, string sceneID) { - SendSetUpdateGroupsMessage(group.GroupID, sceneID, group.etag); + _SendSetUpdateGroupsMessage(group.GroupID, sceneID, group._etag); } private InteractiveGroup GroupFromID(string groupID) { - InteractiveGroup target = new InteractiveGroup("", groupID, WS_MESSAGE_VALUE_DEFAULT_GROUP_ID); + InteractiveGroup target = new InteractiveGroup("", groupID, _WS_MESSAGE_VALUE_DEFAULT_GROUP_ID); var groups = Groups; foreach (InteractiveGroup group in groups) { @@ -3018,7 +3076,7 @@ private InteractiveEventType InteractiveEventTypeFromID(string controlID) { if (controlID == control.ControlID) { - type = control.Type; + type = control._type; break; } } @@ -3051,7 +3109,7 @@ private void SendReady(bool isReady) _outstandingMessages.Add(messageID, WS_MESSAGE_METHOD_READY); } - internal void SendCaptureTransactionMessage(string transactionID) + internal void _SendCaptureTransactionMessage(string transactionID) { var messageID = _currentmessageID++; StringBuilder stringBuilder = new StringBuilder(); @@ -3076,7 +3134,7 @@ internal void SendCaptureTransactionMessage(string transactionID) _outstandingMessages.Add(messageID, WS_MESSAGE_METHOD_SET_CAPTURE_TRANSACTION); } - internal void SendCreateGroupsMessage(string groupID, string sceneID) + internal void _SendCreateGroupsMessage(string groupID, string sceneID) { var messageID = _currentmessageID++; StringBuilder stringBuilder = new StringBuilder(); @@ -3108,7 +3166,7 @@ internal void SendCreateGroupsMessage(string groupID, string sceneID) _outstandingMessages.Add(messageID, WS_MESSAGE_METHOD_SET_CURRENT_SCENE); } - internal void SendSetUpdateGroupsMessage(string groupID, string sceneID, string groupEtag) + internal void _SendSetUpdateGroupsMessage(string groupID, string sceneID, string groupEtag) { var messageID = _currentmessageID++; StringBuilder stringBuilder = new StringBuilder(); @@ -3142,7 +3200,7 @@ internal void SendSetUpdateGroupsMessage(string groupID, string sceneID, string _outstandingMessages.Add(messageID, WS_MESSAGE_METHOD_SET_CURRENT_SCENE); } - internal void SendSetUpdateScenesMessage(InteractiveScene scene) + internal void _SendSetUpdateScenesMessage(InteractiveScene scene) { var messageID = _currentmessageID++; StringBuilder stringBuilder = new StringBuilder(); @@ -3164,7 +3222,7 @@ internal void SendSetUpdateScenesMessage(InteractiveScene scene) jsonWriter.WritePropertyName(WS_MESSAGE_KEY_SCENE_ID); jsonWriter.WriteValue(scene.SceneID); jsonWriter.WritePropertyName(WS_MESSAGE_KEY_ETAG); - jsonWriter.WriteValue(scene.etag); + jsonWriter.WriteValue(scene._etag); jsonWriter.WriteEndObject(); jsonWriter.WriteEndArray(); jsonWriter.WriteEndObject(); @@ -3174,7 +3232,7 @@ internal void SendSetUpdateScenesMessage(InteractiveScene scene) _outstandingMessages.Add(messageID, WS_MESSAGE_METHOD_SET_CURRENT_SCENE); } - internal void SendUpdateParticipantsMessage(InteractiveParticipant participant) + internal void _SendUpdateParticipantsMessage(InteractiveParticipant participant) { var messageID = _currentmessageID++; StringBuilder stringBuilder = new StringBuilder(); @@ -3194,11 +3252,11 @@ internal void SendUpdateParticipantsMessage(InteractiveParticipant participant) jsonWriter.WriteStartArray(); jsonWriter.WriteStartObject(); jsonWriter.WritePropertyName(WS_MESSAGE_KEY_SESSION_ID); - jsonWriter.WriteValue(participant.sessionID); + jsonWriter.WriteValue(participant._sessionID); jsonWriter.WritePropertyName(WS_MESSAGE_KEY_ETAG); - jsonWriter.WriteValue(participant.etag); + jsonWriter.WriteValue(participant._etag); jsonWriter.WritePropertyName(WS_MESSAGE_KEY_GROUP_ID); - jsonWriter.WriteValue(participant.groupID); + jsonWriter.WriteValue(participant._groupID); jsonWriter.WriteEndObject(); jsonWriter.WriteEndArray(); jsonWriter.WriteEndObject(); @@ -3235,7 +3293,7 @@ private void SendSetCompressionMessage() _outstandingMessages.Add(messageID, WS_MESSAGE_METHOD_SET_COMPRESSION); } - internal void SendSetJoystickSetCoordinates(string controlID, double x, double y) + internal void _SendSetJoystickSetCoordinates(string controlID, double x, double y) { InteractiveControl control = ControlFromControlID(controlID); if (control == null) @@ -3257,14 +3315,14 @@ internal void SendSetJoystickSetCoordinates(string controlID, double x, double y jsonWriter.WritePropertyName(WS_MESSAGE_KEY_PARAMETERS); jsonWriter.WriteStartObject(); jsonWriter.WritePropertyName(WS_MESSAGE_KEY_SCENE_ID); - jsonWriter.WriteValue(control.SceneID); + jsonWriter.WriteValue(control._sceneID); jsonWriter.WritePropertyName(WS_MESSAGE_KEY_CONTROLS); jsonWriter.WriteStartArray(); jsonWriter.WriteStartObject(); jsonWriter.WritePropertyName(WS_MESSAGE_KEY_CONTROL_ID); jsonWriter.WriteValue(controlID); jsonWriter.WritePropertyName(WS_MESSAGE_KEY_ETAG); - jsonWriter.WriteValue(control.ETag); + jsonWriter.WriteValue(control._eTag); jsonWriter.WritePropertyName(WS_MESSAGE_KEY_X); jsonWriter.WriteValue(x); jsonWriter.WritePropertyName(WS_MESSAGE_KEY_Y); @@ -3278,7 +3336,7 @@ internal void SendSetJoystickSetCoordinates(string controlID, double x, double y _outstandingMessages.Add(messageID, WS_MESSAGE_METHOD_SET_JOYSTICK_COORDINATES); } - internal void SendSetButtonControlProperties( + internal void _SendSetButtonControlProperties( string controlID, string propertyName, bool disabled, @@ -3307,32 +3365,32 @@ uint cost jsonWriter.WritePropertyName(WS_MESSAGE_KEY_PARAMETERS); jsonWriter.WriteStartObject(); jsonWriter.WritePropertyName(WS_MESSAGE_KEY_SCENE_ID); - jsonWriter.WriteValue(control.SceneID); + jsonWriter.WriteValue(control._sceneID); jsonWriter.WritePropertyName(WS_MESSAGE_KEY_CONTROLS); jsonWriter.WriteStartArray(); jsonWriter.WriteStartObject(); jsonWriter.WritePropertyName(WS_MESSAGE_KEY_CONTROL_ID); jsonWriter.WriteValue(controlID); jsonWriter.WritePropertyName(WS_MESSAGE_KEY_ETAG); - jsonWriter.WriteValue(control.ETag); - if (propertyName == WS_MESSAGE_VALUE_DISABLED) + jsonWriter.WriteValue(control._eTag); + if (propertyName == _WS_MESSAGE_VALUE_DISABLED) { - jsonWriter.WritePropertyName(WS_MESSAGE_VALUE_DISABLED); + jsonWriter.WritePropertyName(_WS_MESSAGE_VALUE_DISABLED); jsonWriter.WriteValue(disabled); } - if (propertyName == WS_MESSAGE_KEY_PROGRESS) + if (propertyName == _WS_MESSAGE_KEY_PROGRESS) { - jsonWriter.WritePropertyName(WS_MESSAGE_KEY_PROGRESS); + jsonWriter.WritePropertyName(_WS_MESSAGE_KEY_PROGRESS); jsonWriter.WriteValue(progress); } - if (propertyName == WS_MESSAGE_KEY_TEXT) + if (propertyName == _WS_MESSAGE_KEY_TEXT) { - jsonWriter.WritePropertyName(WS_MESSAGE_KEY_TEXT); + jsonWriter.WritePropertyName(_WS_MESSAGE_KEY_TEXT); jsonWriter.WriteValue(text); } - if (propertyName == WS_MESSAGE_KEY_COST) + if (propertyName == _WS_MESSAGE_KEY_COST) { - jsonWriter.WritePropertyName(WS_MESSAGE_KEY_COST); + jsonWriter.WritePropertyName(_WS_MESSAGE_KEY_COST); jsonWriter.WriteValue(cost); } jsonWriter.WriteEndObject(); @@ -3385,7 +3443,7 @@ private void SendCallMethodMessage(string method) catch (Exception e) { var foo = e.Message; - LogError("Error: Unable to send message: " + method); + _LogError("Error: Unable to send message: " + method); } } _outstandingMessages.Add(messageID, method); @@ -3407,7 +3465,7 @@ private void SendJsonString(string jsonString) #else _websocket.Send(jsonString); #endif - Log(jsonString); + _Log(jsonString); } List _queuedEvents = new List(); @@ -3468,7 +3526,7 @@ private void SendJsonString(string jsonString) private const string WS_MESSAGE_KEY_CONNECTED_AT = "connectedAt"; private const string WS_MESSAGE_KEY_CONTROLS = "controls"; private const string WS_MESSAGE_KEY_CONTROL_ID = "controlID"; - internal const string WS_MESSAGE_KEY_COST = "cost"; + internal const string _WS_MESSAGE_KEY_COST = "cost"; private const string WS_MESSAGE_KEY_DISABLED = "disabled"; private const string WS_MESSAGE_KEY_ERROR_CODE = "code"; private const string WS_MESSAGE_KEY_ERROR_MESSAGE = "message"; @@ -3489,18 +3547,19 @@ private void SendJsonString(string jsonString) private const string WS_MESSAGE_KEY_LEVEL = "level"; private const string WS_MESSAGE_KEY_REFRESH_TOKEN = "refresh_token"; private const string WS_MESSAGE_KEY_REFRESH_TOKEN_FROM_FILE = "RefreshToken"; - private const string WS_MESSAGE_KEY_RESULT = "result"; + private const string WS_MESSAGE_KEY_META = "meta"; private const string WS_MESSAGE_KEY_PARTICIPANT_ID = "participantID"; private const string WS_MESSAGE_KEY_PARTICIPANTS = "participants"; private const string WS_MESSAGE_KEY_PARAMETERS = "params"; - internal const string WS_MESSAGE_KEY_PROGRESS = "progress"; + internal const string _WS_MESSAGE_KEY_PROGRESS = "progress"; private const string WS_MESSAGE_KEY_PROJECT_VERSION_ID = "projectversionid"; + private const string WS_MESSAGE_KEY_RESULT = "result"; private const string WS_MESSAGE_KEY_SCENE_ID = "sceneID"; private const string WS_MESSAGE_KEY_SCENES = "scenes"; private const string WS_MESSAGE_KEY_SCHEME = "scheme"; private const string WS_MESSAGE_KEY_SESSION_ID = "sessionID"; private const string WS_MESSAGE_KEY_PROJECT_SHARE_CODE = "sharecode"; - internal const string WS_MESSAGE_KEY_TEXT = "text"; + internal const string _WS_MESSAGE_KEY_TEXT = "text"; private const string WS_MESSAGE_KEY_TRANSACTION_ID = "transactionID"; private const string WS_MESSAGE_KEY_TYPE = "type"; private const string WS_MESSAGE_KEY_USER_ID = "userID"; @@ -3512,13 +3571,13 @@ private void SendJsonString(string jsonString) private const string WS_MESSAGE_KEY_Y = "y"; // Values - internal const string WS_MESSAGE_VALUE_CONTROL_TYPE_BUTTON = "button"; - internal const string WS_MESSAGE_VALUE_DISABLED = "disabled"; - internal const string WS_MESSAGE_VALUE_DEFAULT_GROUP_ID = "default"; - internal const string WS_MESSAGE_VALUE_DEFAULT_SCENE_ID = "default"; - internal const string WS_MESSAGE_VALUE_CONTROL_TYPE_JOYSTICK = "joystick"; - internal const string WS_MESSAGE_VALUE_CONTROL_TYPE_LABEL = "label"; - internal const string WS_MESSAGE_VALUE_CONTROL_TYPE_TEXTBOX = "textbox"; + internal const string _WS_MESSAGE_VALUE_CONTROL_TYPE_BUTTON = "button"; + internal const string _WS_MESSAGE_VALUE_DISABLED = "disabled"; + internal const string _WS_MESSAGE_VALUE_DEFAULT_GROUP_ID = "default"; + internal const string _WS_MESSAGE_VALUE_DEFAULT_SCENE_ID = "default"; + internal const string _WS_MESSAGE_VALUE_CONTROL_TYPE_JOYSTICK = "joystick"; + internal const string _WS_MESSAGE_VALUE_CONTROL_TYPE_LABEL = "label"; + internal const string _WS_MESSAGE_VALUE_CONTROL_TYPE_TEXTBOX = "textbox"; private const bool WS_MESSAGE_VALUE_TRUE = true; // Message types @@ -3559,11 +3618,11 @@ private void SendJsonString(string jsonString) private const string WS_MESSAGE_ERROR = "error"; // Input - internal const string CONTROL_TYPE_BUTTON = "button"; - internal const string CONTROL_TYPE_JOYSTICK = "joystick"; - internal const string CONTROL_KIND_LABEL = "label"; - internal const string CONTROL_KIND_TEXTBOX = "textbox"; - internal const string CONTROL_KIND_SCREEN = "screen"; + internal const string _CONTROL_TYPE_BUTTON = "button"; + internal const string _CONTROL_TYPE_JOYSTICK = "joystick"; + internal const string _CONTROL_KIND_LABEL = "label"; + internal const string _CONTROL_KIND_TEXTBOX = "textbox"; + internal const string _CONTROL_KIND_SCREEN = "screen"; // Event names private const string EVENT_NAME_MOUSE_DOWN = "mousedown"; @@ -3585,20 +3644,20 @@ private void SendJsonString(string jsonString) private const string PROTOCOL_VERSION = "2.0"; // Control-specific data structures - internal static Dictionary _buttonStates; - internal static Dictionary> _buttonStatesByParticipant; - internal static Dictionary _joystickStates; - internal static Dictionary> _joystickStatesByParticipant; + internal static Dictionary _buttonStates; + internal static Dictionary> _buttonStatesByParticipant; + internal static Dictionary _joystickStates; + internal static Dictionary> _joystickStatesByParticipant; internal static Dictionary> _textboxValuesByParticipant; - internal static Dictionary _mouseButtonStateByParticipant; + internal static Dictionary _mouseButtonStateByParticipant; internal static Dictionary _mousePositionsByParticipant; // Generic data structures for storing any control data internal static Dictionary>> _giveInputControlDataByParticipant; internal static Dictionary> _giveInputControlData; internal static Dictionary _giveInputKeyValues; - internal static Dictionary _participantsWhoTriggeredGiveInput; - private static Dictionary> _queuedControlPropertyUpdates; + internal static Dictionary _participantsWhoTriggeredGiveInput; + private static Dictionary> _queuedControlPropertyUpdates; internal static Dictionary _transactionIDsState; // For MockData @@ -3625,8 +3684,8 @@ private void InitializeInternal() _scenes = new List(); _websocketHosts = new List(); - _buttonStates = new Dictionary(); - _buttonStatesByParticipant = new Dictionary>(); + _buttonStates = new Dictionary(); + _buttonStatesByParticipant = new Dictionary>(); if (Application.isEditor) { @@ -3654,13 +3713,13 @@ private void InitializeInternal() LoggingLevel = LoggingLevel.None; } - _joystickStates = new Dictionary(); - _joystickStatesByParticipant = new Dictionary>(); - _mouseButtonStateByParticipant = new Dictionary(); + _joystickStates = new Dictionary(); + _joystickStatesByParticipant = new Dictionary>(); + _mouseButtonStateByParticipant = new Dictionary(); _mousePositionsByParticipant = new Dictionary(); - _participantsWhoTriggeredGiveInput = new Dictionary(); - _queuedControlPropertyUpdates = new Dictionary>(); + _participantsWhoTriggeredGiveInput = new Dictionary(); + _queuedControlPropertyUpdates = new Dictionary>(); _transactionIDsState = new Dictionary(); _giveInputControlDataByParticipant = new Dictionary>>(); @@ -3677,7 +3736,7 @@ private void InitializeInternal() _messageWriter = new DataWriter(_websocket.OutputStream); #endif - mixerInteractiveHelper = MixerInteractiveHelper.SingletonInstance; + mixerInteractiveHelper = MixerInteractiveHelper._SingletonInstance; } private void OnInternalRefreshShortCodeTimerCallback(object sender, MixerInteractiveHelper.InternalTimerCallbackEventArgs e) @@ -3692,18 +3751,18 @@ private void OnInternalReconnectTimerCallback(object sender, MixerInteractiveHel VerifyAuthToken(); } - internal void LogError(string message) + internal void _LogError(string message) { - LogError(message, ERROR_FAIL); + _LogError(message, ERROR_FAIL); } - internal void LogError(string message, int code) + internal void _LogError(string message, int code) { _queuedEvents.Add(new InteractiveEventArgs(InteractiveEventType.Error, code, message)); - Log(message, LoggingLevel.Minimal); + _Log(message, LoggingLevel.Minimal); } - internal void Log(string message, LoggingLevel level = LoggingLevel.Verbose) + internal void _Log(string message, LoggingLevel level = LoggingLevel.Verbose) { if (LoggingLevel == LoggingLevel.None || (LoggingLevel == LoggingLevel.Minimal && level == LoggingLevel.Verbose)) @@ -3723,8 +3782,8 @@ private void ClearPreviousControlState() List _buttonStatesKeys = new List(_buttonStates.Keys); foreach (string key in _buttonStatesKeys) { - InternalButtonCountState oldButtonState = _buttonStates[key]; - InternalButtonCountState newButtonState = new InternalButtonCountState(); + _InternalButtonCountState oldButtonState = _buttonStates[key]; + _InternalButtonCountState newButtonState = new _InternalButtonCountState(); newButtonState.PreviousCountOfButtonDownEvents = oldButtonState.CountOfButtonDownEvents; newButtonState.CountOfButtonDownEvents = oldButtonState.NextCountOfButtonDownEvents; newButtonState.NextCountOfButtonDownEvents = 0; @@ -3750,9 +3809,9 @@ private void ClearPreviousControlState() List _buttonStatesByParticipantButtonStateKeys = new List(_buttonStatesByParticipant[key].Keys); foreach (string controlKey in _buttonStatesByParticipantButtonStateKeys) { - InternalButtonState oldButtonState = _buttonStatesByParticipant[key][controlKey]; - InternalButtonState newButtonState = new InternalButtonState(); - InternalButtonCountState buttonCountState = new InternalButtonCountState(); + _InternalButtonState oldButtonState = _buttonStatesByParticipant[key][controlKey]; + _InternalButtonState newButtonState = new _InternalButtonState(); + _InternalButtonCountState buttonCountState = new _InternalButtonCountState(); buttonCountState.PreviousCountOfButtonDownEvents = oldButtonState.ButtonCountState.CountOfButtonDownEvents; buttonCountState.CountOfButtonDownEvents = oldButtonState.ButtonCountState.NextCountOfButtonDownEvents; buttonCountState.NextCountOfButtonDownEvents = 0; @@ -3774,8 +3833,8 @@ private void ClearPreviousControlState() List _mouseButtonStateByParticipantKeys = new List(_mouseButtonStateByParticipant.Keys); foreach (uint _mouseButtonStateByParticipantKey in _mouseButtonStateByParticipantKeys) { - InternalMouseButtonState oldMouseButtonState = _mouseButtonStateByParticipant[_mouseButtonStateByParticipantKey]; - InternalMouseButtonState newMouseButtonState = new InternalMouseButtonState(); + _InternalMouseButtonState oldMouseButtonState = _mouseButtonStateByParticipant[_mouseButtonStateByParticipantKey]; + _InternalMouseButtonState newMouseButtonState = new _InternalMouseButtonState(); // If we just recieved a mouse down, but not an up, then the state is pressed if (oldMouseButtonState.NextIsDown) { @@ -3823,8 +3882,8 @@ private void ClearPreviousControlState() var controlIDKeys = new List(_participantsWhoTriggeredGiveInput.Keys); foreach (string controlIDKey in controlIDKeys) { - InternalParticipantTrackingState oldParticipantTrackingState = _participantsWhoTriggeredGiveInput[controlIDKey]; - InternalParticipantTrackingState newParticipantTrackingState = new InternalParticipantTrackingState(); + _InternalParticipantTrackingState oldParticipantTrackingState = _participantsWhoTriggeredGiveInput[controlIDKey]; + _InternalParticipantTrackingState newParticipantTrackingState = new _InternalParticipantTrackingState(); newParticipantTrackingState.previousParticpant = oldParticipantTrackingState.particpant; newParticipantTrackingState.particpant = oldParticipantTrackingState.nextParticpant; @@ -3853,12 +3912,12 @@ private void UpdateInternalButtonState(InteractiveButtonEventArgs e) // Make sure the entry exists uint participantId = e.Participant.UserID; string controlID = e.ControlID; - Dictionary buttonState; + Dictionary buttonState; bool participantEntryExists = _buttonStatesByParticipant.TryGetValue(participantId, out buttonState); if (!participantEntryExists) { - buttonState = new Dictionary(); - InternalButtonState newControlButtonState = new InternalButtonState(); + buttonState = new Dictionary(); + _InternalButtonState newControlButtonState = new _InternalButtonState(); newControlButtonState.IsDown = e.IsPressed; newControlButtonState.IsPressed = e.IsPressed; newControlButtonState.IsUp = !e.IsPressed; @@ -3867,12 +3926,12 @@ private void UpdateInternalButtonState(InteractiveButtonEventArgs e) } else { - InternalButtonState controlButtonState; + _InternalButtonState controlButtonState; bool previousStateControlEntryExists = buttonState.TryGetValue(controlID, out controlButtonState); if (!previousStateControlEntryExists) { - controlButtonState = new InternalButtonState(); - InternalButtonState newControlButtonState = new InternalButtonState(); + controlButtonState = new _InternalButtonState(); + _InternalButtonState newControlButtonState = new _InternalButtonState(); newControlButtonState.IsDown = e.IsPressed; newControlButtonState.IsPressed = e.IsPressed; newControlButtonState.IsUp = !e.IsPressed; @@ -3883,7 +3942,7 @@ private void UpdateInternalButtonState(InteractiveButtonEventArgs e) // Populate the structure that's by participant bool wasPreviouslyPressed = _buttonStatesByParticipant[participantId][controlID].ButtonCountState.NextCountOfButtonPressEvents > 0; bool isCurrentlyPressed = e.IsPressed; - InternalButtonState newState = _buttonStatesByParticipant[participantId][controlID]; + _InternalButtonState newState = _buttonStatesByParticipant[participantId][controlID]; if (isCurrentlyPressed) { if (!wasPreviouslyPressed) @@ -3908,7 +3967,7 @@ private void UpdateInternalButtonState(InteractiveButtonEventArgs e) } // Fill in the button counts - InternalButtonCountState ButtonCountState = newState.ButtonCountState; + _InternalButtonCountState ButtonCountState = newState.ButtonCountState; if (newState.IsDown) { ButtonCountState.NextCountOfButtonDownEvents++; @@ -3930,7 +3989,7 @@ private void UpdateInternalButtonState(InteractiveButtonEventArgs e) _buttonStatesByParticipant[participantId][controlID] = newState; // Populate button count state - InternalButtonCountState existingButtonCountState; + _InternalButtonCountState existingButtonCountState; bool buttonStateExists = _buttonStates.TryGetValue(controlID, out existingButtonCountState); if (buttonStateExists) { @@ -3947,13 +4006,13 @@ private void UpdateInternalJoystickState(InteractiveJoystickEventArgs e) // Make sure the entry exists uint participantId = e.Participant.UserID; string controlID = e.ControlID; - Dictionary joystickByParticipant; - InternalJoystickState newJoystickStateByParticipant; + Dictionary joystickByParticipant; + _InternalJoystickState newJoystickStateByParticipant; bool participantEntryExists = _joystickStatesByParticipant.TryGetValue(participantId, out joystickByParticipant); if (!participantEntryExists) { - joystickByParticipant = new Dictionary(); - newJoystickStateByParticipant = new InternalJoystickState(); + joystickByParticipant = new Dictionary(); + newJoystickStateByParticipant = new _InternalJoystickState(); newJoystickStateByParticipant.X = e.X; newJoystickStateByParticipant.Y = e.Y; newJoystickStateByParticipant.countOfUniqueJoystickInputs = 1; @@ -3961,7 +4020,7 @@ private void UpdateInternalJoystickState(InteractiveJoystickEventArgs e) } else { - newJoystickStateByParticipant = new InternalJoystickState(); + newJoystickStateByParticipant = new _InternalJoystickState(); bool joystickByParticipantEntryExists = joystickByParticipant.TryGetValue(controlID, out newJoystickStateByParticipant); if (!joystickByParticipantEntryExists) { @@ -3982,7 +4041,7 @@ private void UpdateInternalJoystickState(InteractiveJoystickEventArgs e) _joystickStatesByParticipant[e.Participant.UserID][e.ControlID] = newJoystickStateByParticipant; // Update the joystick state - InternalJoystickState newJoystickState; + _InternalJoystickState newJoystickState; bool joystickEntryExists = joystickByParticipant.TryGetValue(controlID, out newJoystickState); if (!joystickEntryExists) { @@ -4034,11 +4093,11 @@ private void UpdateInternalMouseButtonState(InteractiveMouseButtonEventArgs e) // Make sure the entry exists uint participantId = e.Participant.UserID; bool isPressed = e.IsPressed; - InternalMouseButtonState buttonState; + _InternalMouseButtonState buttonState; bool participantEntryExists = _mouseButtonStateByParticipant.TryGetValue(participantId, out buttonState); if (!participantEntryExists) { - buttonState = new InternalMouseButtonState(); + buttonState = new _InternalMouseButtonState(); buttonState.IsDown = false; buttonState.IsPressed = false; buttonState.IsUp = false; @@ -4047,7 +4106,7 @@ private void UpdateInternalMouseButtonState(InteractiveMouseButtonEventArgs e) buttonState.NextIsUp = !e.IsPressed; _mouseButtonStateByParticipant.Add(participantId, buttonState); } - InternalMouseButtonState newState = _mouseButtonStateByParticipant[participantId]; + _InternalMouseButtonState newState = _mouseButtonStateByParticipant[participantId]; newState.NextIsDown = isPressed; newState.NextIsPressed = isPressed; newState.NextIsUp = !isPressed; @@ -4056,55 +4115,55 @@ private void UpdateInternalMouseButtonState(InteractiveMouseButtonEventArgs e) internal void _QueuePropertyUpdate(string sceneID, string controlID, string name, bool value) { - KnownControlPropertyPrimitiveTypes type = KnownControlPropertyPrimitiveTypes.Boolean; + _KnownControlPropertyPrimitiveTypes type = _KnownControlPropertyPrimitiveTypes.Boolean; _QueuePropertyUpdateImpl(sceneID, controlID, name, type, value); } internal void _QueuePropertyUpdate(string sceneID, string controlID, string name, double value) { - KnownControlPropertyPrimitiveTypes type = KnownControlPropertyPrimitiveTypes.Number; + _KnownControlPropertyPrimitiveTypes type = _KnownControlPropertyPrimitiveTypes.Number; _QueuePropertyUpdateImpl(sceneID, controlID, name, type, value); } internal void _QueuePropertyUpdate(string sceneID, string controlID, string name, string value) { - KnownControlPropertyPrimitiveTypes type = KnownControlPropertyPrimitiveTypes.String; + _KnownControlPropertyPrimitiveTypes type = _KnownControlPropertyPrimitiveTypes.String; _QueuePropertyUpdateImpl(sceneID, controlID, name, type, value); } internal void _QueuePropertyUpdate(string sceneID, string controlID, string name, object value) { - KnownControlPropertyPrimitiveTypes type = KnownControlPropertyPrimitiveTypes.Unknown; + _KnownControlPropertyPrimitiveTypes type = _KnownControlPropertyPrimitiveTypes.Unknown; _QueuePropertyUpdateImpl(sceneID, controlID, name, type, value); } - internal void _QueuePropertyUpdateImpl(string sceneID, string controlID, string name, KnownControlPropertyPrimitiveTypes type, object value) + internal void _QueuePropertyUpdateImpl(string sceneID, string controlID, string name, _KnownControlPropertyPrimitiveTypes type, object value) { // If a scene entry doesn't exist, add one. if (!_queuedControlPropertyUpdates.ContainsKey(sceneID)) { - InternalControlPropertyUpdateData controlPropertyData = new InternalControlPropertyUpdateData(name, type, value); - Dictionary controlData = new Dictionary(); + _InternalControlPropertyUpdateData controlPropertyData = new _InternalControlPropertyUpdateData(name, type, value); + Dictionary controlData = new Dictionary(); controlData.Add(controlID, controlPropertyData); _queuedControlPropertyUpdates.Add(sceneID, controlData); } else { // Scene exists, but if control entry doesn't exist, create one. - Dictionary controlData = _queuedControlPropertyUpdates[sceneID]; + Dictionary controlData = _queuedControlPropertyUpdates[sceneID]; if (!controlData.ContainsKey(controlID)) { - InternalControlPropertyUpdateData controlPropertyData = new InternalControlPropertyUpdateData(name, type, value); + _InternalControlPropertyUpdateData controlPropertyData = new _InternalControlPropertyUpdateData(name, type, value); _queuedControlPropertyUpdates[sceneID].Add(controlID, controlPropertyData); } else { // Control entry exists, but does property entry exist? - InternalControlPropertyUpdateData controlPropertyData = controlData[controlID]; - InternalControlPropertyMetaData controlPropertyMetaData = new InternalControlPropertyMetaData(); + _InternalControlPropertyUpdateData controlPropertyData = controlData[controlID]; + _InternalControlPropertyMetaData controlPropertyMetaData = new _InternalControlPropertyMetaData(); controlPropertyMetaData.type = type; - if (type == KnownControlPropertyPrimitiveTypes.Boolean) + if (type == _KnownControlPropertyPrimitiveTypes.Boolean) { controlPropertyMetaData.boolValue = (bool)value; } - else if (type == KnownControlPropertyPrimitiveTypes.Number) + else if (type == _KnownControlPropertyPrimitiveTypes.Number) { controlPropertyMetaData.numberValue = (double)value; } @@ -4124,7 +4183,7 @@ internal void _QueuePropertyUpdateImpl(string sceneID, string controlID, string } } - internal void RegisterControlForValueUpdates(string controlTypeName, List valuesToTrack) + internal void _RegisterControlForValueUpdates(string controlTypeName, List valuesToTrack) { if (!_giveInputControlData.ContainsKey(controlTypeName)) { @@ -4140,7 +4199,7 @@ internal void RegisterControlForValueUpdates(string controlTypeName, List properties; - public InternalControlPropertyUpdateData(string name, KnownControlPropertyPrimitiveTypes type, object value) + internal Dictionary properties; + public _InternalControlPropertyUpdateData(string name, _KnownControlPropertyPrimitiveTypes type, object value) { - properties = new Dictionary(); - InternalControlPropertyMetaData typeData = new InternalControlPropertyMetaData(); + properties = new Dictionary(); + _InternalControlPropertyMetaData typeData = new _InternalControlPropertyMetaData(); typeData.type = type; // This should never fail, but just in case. try { - if (type == KnownControlPropertyPrimitiveTypes.Boolean) + if (type == _KnownControlPropertyPrimitiveTypes.Boolean) { typeData.boolValue = (bool)value; } - else if (type == KnownControlPropertyPrimitiveTypes.Number) + else if (type == _KnownControlPropertyPrimitiveTypes.Number) { typeData.numberValue = (double)value; } @@ -4230,22 +4289,22 @@ public InternalControlPropertyUpdateData(string name, KnownControlPropertyPrimit } catch (Exception ex) { - InteractivityManager.SingletonInstance.LogError("Failed to cast the value to a known type. Exception: " + ex.Message); + InteractivityManager.SingletonInstance._LogError("Failed to cast the value to a known type. Exception: " + ex.Message); } properties.Add(name, typeData); } } - internal struct InternalControlPropertyMetaData + internal struct _InternalControlPropertyMetaData { public object objectValue; public bool boolValue; public double numberValue; public string stringValue; - public KnownControlPropertyPrimitiveTypes type; + public _KnownControlPropertyPrimitiveTypes type; } - internal enum KnownControlPropertyPrimitiveTypes + internal enum _KnownControlPropertyPrimitiveTypes { Unknown, Boolean, @@ -4253,14 +4312,14 @@ internal enum KnownControlPropertyPrimitiveTypes String } - internal struct InternalJoystickState + internal struct _InternalJoystickState { internal double X; internal double Y; internal int countOfUniqueJoystickInputs; } - internal struct InternalMouseButtonState + internal struct _InternalMouseButtonState { internal bool IsDown; internal bool IsPressed; @@ -4270,12 +4329,12 @@ internal struct InternalMouseButtonState internal bool NextIsUp; } - internal struct InternalParticipantTrackingState + internal struct _InternalParticipantTrackingState { internal InteractiveParticipant previousParticpant; internal InteractiveParticipant particpant; internal InteractiveParticipant nextParticpant; - public InternalParticipantTrackingState(InteractiveParticipant newParticipant) + public _InternalParticipantTrackingState(InteractiveParticipant newParticipant) { nextParticpant = newParticipant; particpant = null; diff --git a/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/MixerInteractive.cs b/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/MixerInteractive.cs index 3e4e1e2..181b5c6 100644 --- a/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/MixerInteractive.cs +++ b/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/MixerInteractive.cs @@ -78,6 +78,12 @@ public class MixerInteractive : MonoBehaviour public delegate void OnInteractiveJoystickControlEventHandler(object sender, InteractiveJoystickEventArgs e); public static event OnInteractiveJoystickControlEventHandler OnInteractiveJoystickControlEvent; + public delegate void OnInteractiveMouseButtonEventHandler(object sender, InteractiveMouseButtonEventArgs e); + public static event OnInteractiveMouseButtonEventHandler OnInteractiveMouseButtonEvent; + + public delegate void OnInteractiveCoordinatesChangedHandler(object sender, InteractiveCoordinatesChangedEventArgs e); + public static event OnInteractiveCoordinatesChangedHandler OnInteractiveCoordinatesChangedEvent; + public delegate void OnInteractiveTextControlEventHandler(object sender, InteractiveTextEventArgs e); public static event OnInteractiveTextControlEventHandler OnInteractiveTextControlEvent; @@ -105,7 +111,7 @@ public class MixerInteractive : MonoBehaviour public List rpcMethodNames; private static List outboundMessages; - internal static Websocket websocket; + internal static Websocket _websocket; #if !UNITY_WSA || UNITY_EDITOR private static BackgroundWorker backgroundWorker; @@ -113,7 +119,7 @@ public class MixerInteractive : MonoBehaviour private const string DEFAULT_GROUP_ID = "default"; private const float CHECK_FOR_OUTSTANDING_REQUESTS_INTERVAL = 1f; - internal const float DEFAULT_MIXER_SYNCVAR_UPDATE_INTERVAL = 1f; + internal const float _DEFAULT_MIXER_SYNCVAR_UPDATE_INTERVAL = 1f; void Awake() { @@ -150,6 +156,8 @@ private void Initialize() interactivityManager.OnParticipantStateChanged -= HandleParticipantStateChanged; interactivityManager.OnInteractiveButtonEvent -= HandleInteractiveButtonEvent; interactivityManager.OnInteractiveJoystickControlEvent -= HandleInteractiveJoystickControlEvent; + interactivityManager.OnInteractiveMouseButtonEvent -= HandleInteractiveMouseButtonEvent; + interactivityManager.OnInteractiveCoordinatesChangedEvent -= HandleInteractiveCoordinatesChangedHandler; interactivityManager.OnInteractiveTextControlEvent -= HandleInteractiveTextControlEvent; interactivityManager.OnInteractiveMessageEvent -= HandleInteractiveMessageEvent; @@ -157,6 +165,8 @@ private void Initialize() interactivityManager.OnInteractivityStateChanged += HandleInteractivityStateChanged; interactivityManager.OnParticipantStateChanged += HandleParticipantStateChanged; interactivityManager.OnInteractiveButtonEvent += HandleInteractiveButtonEvent; + interactivityManager.OnInteractiveMouseButtonEvent += HandleInteractiveMouseButtonEvent; + interactivityManager.OnInteractiveCoordinatesChangedEvent += HandleInteractiveCoordinatesChangedHandler; interactivityManager.OnInteractiveJoystickControlEvent += HandleInteractiveJoystickControlEvent; interactivityManager.OnInteractiveTextControlEvent += HandleInteractiveTextControlEvent; interactivityManager.OnInteractiveMessageEvent += HandleInteractiveMessageEvent; @@ -165,16 +175,16 @@ private void Initialize() { interactivityManagerAlreadyInitialized = true; } - MixerInteractiveHelper helper = MixerInteractiveHelper.SingletonInstance; - helper.runInBackgroundIfInteractive = runInBackground; - helper.defaultSceneID = defaultSceneID; + MixerInteractiveHelper helper = MixerInteractiveHelper._SingletonInstance; + helper._runInBackgroundIfInteractive = runInBackground; + helper._defaultSceneID = defaultSceneID; for (int i = 0; i < groupIDs.Count; i++) { string groupID = groupIDs[i]; if (groupID != string.Empty && - !helper.groupSceneMapping.ContainsKey(groupID)) + !helper._groupSceneMapping.ContainsKey(groupID)) { - helper.groupSceneMapping.Add(groupID, sceneIDs[i]); + helper._groupSceneMapping.Add(groupID, sceneIDs[i]); } } @@ -196,8 +206,8 @@ private void Initialize() { ProcessSerializedProperties(); } - websocket = gameObject.AddComponent(); - InteractivityManager.SingletonInstance.SetWebsocketInstance(websocket); + _websocket = gameObject.AddComponent(); + InteractivityManager.SingletonInstance.SetWebsocketInstance(_websocket); } private static void HandleInteractiveJoystickControlEvent(object sender, InteractiveJoystickEventArgs e) @@ -205,6 +215,16 @@ private static void HandleInteractiveJoystickControlEvent(object sender, Interac queuedEvents.Add(e); } + private static void HandleInteractiveMouseButtonEvent(object sender, InteractiveMouseButtonEventArgs e) + { + queuedEvents.Add(e); + } + + private static void HandleInteractiveCoordinatesChangedHandler(object sender, InteractiveCoordinatesChangedEventArgs e) + { + queuedEvents.Add(e); + } + private static void HandleInteractiveButtonEvent(object sender, InteractiveButtonEventArgs e) { queuedEvents.Add(e); @@ -251,7 +271,7 @@ private static bool FindAndInvokeRpcMethod(string methodName, List(); foreach (string rpcMethodName in rpcMethodNames) { @@ -321,7 +340,7 @@ internal static string TrimMethodName(string unTrimmedMethodName) private static void RefreshRPCMethods(bool includeMethodsFromTheInspector = false) { // Add all methods with the "MixerRpcMethod" to our method cache. - var helper = MixerInteractiveHelper.SingletonInstance; + var helper = MixerInteractiveHelper._SingletonInstance; MonoBehaviour[] activeBehaviors = FindObjectsOfType(); foreach (MonoBehaviour monoBehavior in activeBehaviors) { @@ -382,8 +401,6 @@ internal static void SendOutboundMessages() private static void SerializeSyncVars() { // Get all syncvars - // TODO: We need an editor version of this so devs can set properties on the - // syncvars like how often they get sent. MonoBehaviour[] activeBehaviors = GameObject.FindObjectsOfType(); foreach (MonoBehaviour monoBehavior in activeBehaviors) { @@ -533,18 +550,21 @@ public static Vector3 MousePosition get { Vector3 mousePosition = Vector3.zero; - Dictionary mousePositionsByParticipant = InteractivityManager._mousePositionsByParticipant; - var mousePositionByParticipantKeys = mousePositionsByParticipant.Keys; - float totalX = 0; - float totalY = 0; - foreach (var mousePositionByParticipantKey in mousePositionByParticipantKeys) + if (InteractivityManager._mousePositionsByParticipant.Count > 0) { - totalX += mousePositionsByParticipant[mousePositionByParticipantKey].x; - totalY += mousePositionsByParticipant[mousePositionByParticipantKey].y; + Dictionary mousePositionsByParticipant = InteractivityManager._mousePositionsByParticipant; + var mousePositionByParticipantKeys = mousePositionsByParticipant.Keys; + float totalX = 0; + float totalY = 0; + foreach (var mousePositionByParticipantKey in mousePositionByParticipantKeys) + { + totalX += mousePositionsByParticipant[mousePositionByParticipantKey].x; + totalY += mousePositionsByParticipant[mousePositionByParticipantKey].y; + } + // We average all the mouse positions. Z in always zero. + mousePosition.x = totalX / mousePositionByParticipantKeys.Count; + mousePosition.y = totalY / mousePositionByParticipantKeys.Count; } - // We average all the mouse positions. Z in always zero. - mousePosition.x = totalX / mousePositionByParticipantKeys.Count; - mousePosition.y = totalY / mousePositionByParticipantKeys.Count; return mousePosition; } @@ -573,7 +593,7 @@ public static InteractiveParticipant GetParticipantWhoGaveInputForControl(string { // Find which participant send the input for the given control. InteractiveParticipant participant = null; - InternalParticipantTrackingState participantTrackingState = new InternalParticipantTrackingState(); + _InternalParticipantTrackingState participantTrackingState = new _InternalParticipantTrackingState(); bool participantTrackingStateEntryExists = InteractivityManager._participantsWhoTriggeredGiveInput.TryGetValue(controlID, out participantTrackingState); if (participantTrackingStateEntryExists) { @@ -646,7 +666,7 @@ public static void StopInteractive() { InteractivityManager.SingletonInstance.StopInteractive(); pendingGoInteractive = false; - if (MixerInteractiveHelper.SingletonInstance.runInBackgroundIfInteractive) + if (MixerInteractiveHelper._SingletonInstance._runInBackgroundIfInteractive) { Application.runInBackground = previousRunInBackgroundValue; } @@ -779,6 +799,20 @@ void Update() } processedEvents.Add(interactiveEvent); break; + case InteractiveEventType.MouseButton: + if (OnInteractiveMouseButtonEvent != null) + { + OnInteractiveMouseButtonEvent(this, interactiveEvent as InteractiveMouseButtonEventArgs); + } + processedEvents.Add(interactiveEvent); + break; + case InteractiveEventType.Coordinates: + if (OnInteractiveCoordinatesChangedEvent != null) + { + OnInteractiveCoordinatesChangedEvent(this, interactiveEvent as InteractiveCoordinatesChangedEventArgs); + } + processedEvents.Add(interactiveEvent); + break; case InteractiveEventType.TextInput: if (OnInteractiveTextControlEvent != null) { @@ -929,7 +963,7 @@ public static float GetJoystickY(string controlID) public static bool GetMouseButtonDown(int buttonIndex = 0) { bool getButtonDownResult = false; - Dictionary mouseButtonStateByParticipant = InteractivityManager._mouseButtonStateByParticipant; + Dictionary mouseButtonStateByParticipant = InteractivityManager._mouseButtonStateByParticipant; var mouseButtonStateByParticipantKeys = mouseButtonStateByParticipant.Keys; foreach (uint mouseButtonStateByParticipantKey in mouseButtonStateByParticipantKeys) { @@ -952,7 +986,7 @@ public static bool GetMouseButtonDown(int buttonIndex = 0) public static bool GetMouseButton(int buttonIndex = 0) { bool getButtonDownResult = false; - Dictionary mouseButtonStateByParticipant = InteractivityManager._mouseButtonStateByParticipant; + Dictionary mouseButtonStateByParticipant = InteractivityManager._mouseButtonStateByParticipant; var mouseButtonStateByParticipantKeys = mouseButtonStateByParticipant.Keys; foreach (uint mouseButtonStateByParticipantKey in mouseButtonStateByParticipantKeys) { @@ -975,7 +1009,7 @@ public static bool GetMouseButton(int buttonIndex = 0) public static bool GetMouseButtonUp(int buttonIndex = 0) { bool getButtonDownResult = false; - Dictionary mouseButtonStateByParticipant = InteractivityManager._mouseButtonStateByParticipant; + Dictionary mouseButtonStateByParticipant = InteractivityManager._mouseButtonStateByParticipant; var mouseButtonStateByParticipantKeys = mouseButtonStateByParticipant.Keys; foreach (uint mouseButtonStateByParticipantKey in mouseButtonStateByParticipantKeys) { @@ -1090,7 +1124,7 @@ private IEnumerator InitializeCoRoutine() /// Returns the interactive control matching the given ID. public static InteractiveControl GetControl(string controlID) { - return InteractivityManager.SingletonInstance.GetControl(controlID); + return InteractivityManager.SingletonInstance._GetControl(controlID); } /// @@ -1100,7 +1134,7 @@ public static InteractiveControl GetControl(string controlID) /// Returns a list of InteractiveTextResult objects. Returns an empty list if there was no input. public static IList GetText(string controlID) { - return InteractivityManager.SingletonInstance.GetText(controlID); + return InteractivityManager.SingletonInstance._GetText(controlID); } /// @@ -1138,7 +1172,7 @@ public static void GoInteractive() backgroundWorker.RunWorkerAsync(); #endif - if (MixerInteractiveHelper.SingletonInstance.runInBackgroundIfInteractive) + if (MixerInteractiveHelper._SingletonInstance._runInBackgroundIfInteractive) { previousRunInBackgroundValue = Application.runInBackground; Application.runInBackground = true; @@ -1189,17 +1223,17 @@ private static void HandleInteractivityStateChangedInternal(object sender, Inter private static void ProcessSerializedProperties() { - MixerInteractiveHelper helper = MixerInteractiveHelper.SingletonInstance; + MixerInteractiveHelper helper = MixerInteractiveHelper._SingletonInstance; InteractivityManager interactivityManager = InteractivityManager.SingletonInstance; - string defaultSceneID = helper.defaultSceneID; - if (helper.groupSceneMapping.Count > 0 || + string defaultSceneID = helper._defaultSceneID; + if (helper._groupSceneMapping.Count > 0 || defaultSceneID != string.Empty) { shouldCheckForOutstandingRequests = true; } - if (helper.groupSceneMapping.Count > 0) + if (helper._groupSceneMapping.Count > 0) { - var groupIDs = helper.groupSceneMapping.Keys; + var groupIDs = helper._groupSceneMapping.Keys; foreach (var groupID in groupIDs) { if (groupID == string.Empty) @@ -1211,7 +1245,7 @@ private static void ProcessSerializedProperties() #pragma warning disable 0219 InteractiveGroup group; #pragma warning restore 0219 - string sceneID = helper.groupSceneMapping[groupID]; + string sceneID = helper._groupSceneMapping[groupID]; if (sceneID != string.Empty) { group = new InteractiveGroup(groupID, sceneID); @@ -1427,7 +1461,7 @@ public struct MixerHelperParameterInfo public class MixerSyncVar : Attribute { public float updateInterval; - public MixerSyncVar(double newUpdateInterval = MixerInteractive.DEFAULT_MIXER_SYNCVAR_UPDATE_INTERVAL) + public MixerSyncVar(double newUpdateInterval = MixerInteractive._DEFAULT_MIXER_SYNCVAR_UPDATE_INTERVAL) { updateInterval = (float)newUpdateInterval; } diff --git a/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/MixerInteractiveHelper.cs b/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/MixerInteractiveHelper.cs index 3ac83f5..b0cfdb3 100644 --- a/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/MixerInteractiveHelper.cs +++ b/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/MixerInteractiveHelper.cs @@ -31,14 +31,14 @@ internal class MixerInteractiveHelper: MonoBehaviour { - internal bool runInBackgroundIfInteractive = true; - internal string defaultSceneID; - internal Dictionary groupSceneMapping = new Dictionary(); + internal bool _runInBackgroundIfInteractive = true; + internal string _defaultSceneID; + internal Dictionary _groupSceneMapping = new Dictionary(); internal List rpcOwningMonoBehaviorNames = new List(); internal List rpcMethodNames = new List(); internal Dictionary cachedRPCMethods = new Dictionary(); - public delegate void OnInternalWebRequestStateChangedEventHandler(object sender, InternalWebRequestStateChangedEventArgs e); + public delegate void OnInternalWebRequestStateChangedEventHandler(object sender, _InternalWebRequestStateChangedEventArgs e); public event OnInternalWebRequestStateChangedEventHandler OnInternalWebRequestStateChanged; public delegate void OnInternalCheckAuthStatusCallbackEventHandler(object sender, InternalTimerCallbackEventArgs e); @@ -53,7 +53,7 @@ internal class MixerInteractiveHelper: MonoBehaviour public delegate void OnTryGetAuthTokensFromCacheCallbackEventHandler(object sender, TryGetAuthTokensFromCacheEventArgs e); public event OnTryGetAuthTokensFromCacheCallbackEventHandler OnTryGetAuthTokensFromCacheCallback; - private List _queuedWebRequests; + private List<_InteractiveWebRequestData> _queuedWebRequests; private List _queuedStartTimerRequests; private List _queuedStopTimerRequests; private List _runningCoRoutines; @@ -63,7 +63,7 @@ internal class MixerInteractiveHelper: MonoBehaviour private string _refreshTokenValueToWriteToCache; private static MixerInteractiveHelper _singletonInstance; - internal static MixerInteractiveHelper SingletonInstance + internal static MixerInteractiveHelper _SingletonInstance { get { @@ -84,7 +84,7 @@ void Update() { if (_singletonInstance != null) { - foreach (InteractiveWebRequestData _queuedWebRequest in _queuedWebRequests) + foreach (_InteractiveWebRequestData _queuedWebRequest in _queuedWebRequests) { _runningCoRoutines.Add(new CoRoutineInfo( "MakeWebRequestCoRoutine", @@ -185,13 +185,13 @@ private void StopCoroutineByName(string name) private void Initialize() { - _queuedWebRequests = new List(); + _queuedWebRequests = new List<_InteractiveWebRequestData>(); _queuedStartTimerRequests = new List(); _queuedStopTimerRequests = new List(); _runningCoRoutines = new List(); } - internal void MakeWebRequest( + internal void _MakeWebRequest( string requestID, string requestUrl, Dictionary headers = null, @@ -199,7 +199,7 @@ internal void MakeWebRequest( string postData = "" ) { - _queuedWebRequests.Add(new InteractiveWebRequestData( + _queuedWebRequests.Add(new _InteractiveWebRequestData( requestID, requestUrl, headers, @@ -208,14 +208,14 @@ internal void MakeWebRequest( )); } - internal struct InteractiveWebRequestData + internal struct _InteractiveWebRequestData { public string requestID; public string requestUrl; public Dictionary headers; public string httpVerb; public string postData; - public InteractiveWebRequestData( + public _InteractiveWebRequestData( string newRequestID, string newRequestUrl, Dictionary newHeaders, @@ -231,7 +231,7 @@ string newPostData } } - internal class InternalWebRequestStateChangedEventArgs + internal class _InternalWebRequestStateChangedEventArgs { public string RequestID { @@ -259,7 +259,7 @@ public string ErrorMessage private set; } - internal InternalWebRequestStateChangedEventArgs( + internal _InternalWebRequestStateChangedEventArgs( string requestID, bool succeeded, long responseCode, @@ -371,7 +371,7 @@ private IEnumerator MakeWebRequestCoRoutine( BackgroundWorker backgroundWorker = new BackgroundWorker(); backgroundWorker.DoWork -= WebRequestBackgroundWorkerDoWork; backgroundWorker.DoWork += WebRequestBackgroundWorkerDoWork; - backgroundWorker.RunWorkerAsync(new InternalWebRequestStateChangedEventArgs( + backgroundWorker.RunWorkerAsync(new _InternalWebRequestStateChangedEventArgs( requestID, !request.isNetworkError, request.responseCode, @@ -387,7 +387,7 @@ private void WebRequestBackgroundWorkerDoWork(object sender, DoWorkEventArgs e) if (backgroundWorker != null) { backgroundWorker.DoWork -= WebRequestBackgroundWorkerDoWork; - InternalWebRequestStateChangedEventArgs eventArgs = e.Argument as InternalWebRequestStateChangedEventArgs; + _InternalWebRequestStateChangedEventArgs eventArgs = e.Argument as _InternalWebRequestStateChangedEventArgs; if (eventArgs != null && OnInternalWebRequestStateChanged != null) { From 818eed7190e2a01fa7b04b5c5b4f7efa7fe5b9c6 Mon Sep 17 00:00:00 2001 From: Gersh Payzer Date: Mon, 30 Apr 2018 08:42:18 -0700 Subject: [PATCH 3/3] Minor fixes for UWP --- .../Source/Scripts/InteractivityManager.cs | 2 +- .../Source/Scripts/MixerInteractive.cs | 2 ++ .../ProjectSettings/ProjectSettings.asset | Bin 57415 -> 57415 bytes 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/InteractivityManager.cs b/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/InteractivityManager.cs index 931fcce..45e78f1 100644 --- a/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/InteractivityManager.cs +++ b/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/InteractivityManager.cs @@ -850,7 +850,7 @@ private void ConnectToWebsocket() } catch (Exception ex) { - LogError("Error: " + ex.Message); + _LogError("Error: " + ex.Message); } #elif UNITY_XBOXONE && !UNITY_EDITOR Dictionary headers = new Dictionary(); diff --git a/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/MixerInteractive.cs b/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/MixerInteractive.cs index 181b5c6..533a5df 100644 --- a/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/MixerInteractive.cs +++ b/Source/InteractiveSDK/Assets/MixerInteractive/Source/Scripts/MixerInteractive.cs @@ -400,6 +400,7 @@ internal static void SendOutboundMessages() private static void SerializeSyncVars() { +#if !UNITY_WSA // Get all syncvars MonoBehaviour[] activeBehaviors = GameObject.FindObjectsOfType(); foreach (MonoBehaviour monoBehavior in activeBehaviors) @@ -423,6 +424,7 @@ private static void SerializeSyncVars() } } } +#endif } private static void ParseAndSendCustomMessage(string name, string value) diff --git a/Source/InteractiveSDK/ProjectSettings/ProjectSettings.asset b/Source/InteractiveSDK/ProjectSettings/ProjectSettings.asset index 20b6dedb34538da93f3c5cf5912a9b9da8986f8d..effaf505e0ac204361c479d93380e1aa8b2b49d7 100644 GIT binary patch delta 16 YcmX?pfcf|V<_$VG8JRZg-jreo06}I3rvLx| delta 16 YcmX?pfcf|V<_$VG85uY0-jreo06|~|rT_o{