/// <summary>
        /// Add Touch state with event listeners.
        /// </summary>
        public void AddTouchState()
        {
            interactiveElement.AddNewState("Touch");

            TouchEvents touchEvents = interactiveElement.GetStateEvents <TouchEvents>("Touch");

            touchEvents.OnTouchStarted.AddListener((touchData) =>
            {
                Debug.Log($"{gameObject.name} Touch Started");
            });
        }
        public IEnumerator TestClickedEventConfiguration()
        {
            // Create an interactive cube
            InteractiveElement interactiveElement = CreateInteractiveCube();

            yield return(null);

            // Add the clicked state
            InteractionState clicked = interactiveElement.AddNewState(clickedStateName);

            yield return(null);

            // Get the event configuration for the Clicked state
            var eventConfiguration = interactiveElement.GetStateEvents <ClickedEvents>(clickedStateName);

            bool onClicked = false;

            eventConfiguration.OnClicked.AddListener(() => { onClicked = true; });

            // Create a new hand and initialize it with an object in focus
            var leftHand = new TestHand(Handedness.Left);

            // Show hand at starting position
            yield return(ShowHandWithObjectInFocus(leftHand));

            // Click the hand to trigger far select events
            yield return(leftHand.Click());

            Assert.True(onClicked);
        }
        public IEnumerator TestTouchEventConfiguration()
        {
            // Create an interactive cube
            InteractiveElement interactiveElement = CreateInteractiveCube();

            yield return(null);

            // Add the touch state
            InteractionState touchState = interactiveElement.AddNewState(touchStateName);

            yield return(null);

            // Get the event configuration for the touch state
            var eventConfiguration = interactiveElement.GetStateEvents <TouchEvents>(touchStateName);

            bool onTouchStarted   = false;
            bool onTouchCompleted = false;
            bool onTouchUpdated   = false;

            eventConfiguration.OnTouchStarted.AddListener((eventData) =>
            {
                onTouchStarted = true;
            });

            eventConfiguration.OnTouchCompleted.AddListener((eventData) =>
            {
                onTouchCompleted = true;
            });

            eventConfiguration.OnTouchUpdated.AddListener((eventData) =>
            {
                onTouchUpdated = true;
            });

            // Create a new hand and initialize it with an object in focus
            var leftHand = new TestHand(Handedness.Left);

            // Show hand at starting position
            yield return(ShowHandWithObjectInFocus(leftHand));

            // Move hand to Touch the object
            yield return(MoveHandTouchObject(leftHand));

            Assert.True(onTouchStarted);
            yield return(null);

            Assert.True(onTouchUpdated);
            yield return(null);

            yield return(MoveHandOutOfFocus(leftHand));

            // Make sure the touch has completed when the hand moves off the object
            Assert.True(onTouchCompleted);
            yield return(null);
        }
        public IEnumerator TestToggleEvents()
        {
            // Create an interactive cube
            InteractiveElement interactiveElement = CreateInteractiveCube();

            yield return(null);

            interactiveElement.AddToggleStates();
            yield return(null);

            // Get the event configuration for the ToggleOn state
            var eventConfigurationToggleOn = interactiveElement.GetStateEvents <ToggleOnEvents>(toggleOnStateName);

            // Get the event configuration for the ToggleOn state
            var eventConfigurationToggleOff = interactiveElement.GetStateEvents <ToggleOffEvents>(toggleOffStateName);

            bool onToggleOn  = false;
            bool onToggleOff = false;

            eventConfigurationToggleOn.OnToggleOn.AddListener(() => { onToggleOn = true; });
            eventConfigurationToggleOff.OnToggleOff.AddListener(() => { onToggleOff = true; });

            interactiveElement.SetToggleStates();
            yield return(null);

            // Make sure the toggle is on at the start
            Assert.True(onToggleOn);

            // Create a new hand and initialize it with an object in focus
            var leftHand = new TestHand(Handedness.Left);

            // Show hand at starting position
            yield return(ShowHandWithObjectInFocus(leftHand));

            // Click the hand
            yield return(leftHand.Click());

            Assert.True(onToggleOff);
        }
        public IEnumerator TestAddingAndSettingNewState()
        {
            // Create an interactive cube
            InteractiveElement interactiveElement = CreateInteractiveCube();

            yield return(null);

            // Create a new state and add it to Tracked States
            interactiveElement.AddNewState(newStateName);

            // Change the value of my new state by using the focus state events to set the new state
            InteractionState focusState = interactiveElement.GetState(CoreInteractionState.Focus.ToString());

            var focusEventConfiguration = interactiveElement.GetStateEvents <FocusEvents>(focusStateName);

            yield return(null);

            focusEventConfiguration.OnFocusOn.AddListener((focusEventData) =>
            {
                // When the object comes into focus, set my new state to on
                interactiveElement.SetStateOn(newStateName);
            });

            focusEventConfiguration.OnFocusOff.AddListener((focusEventData) =>
            {
                // When the object comes out of  focus, set my new state to off
                interactiveElement.SetStateOff(newStateName);
            });

            // Make sure MyNewState is being tracked
            InteractionState myNewState = interactiveElement.GetState(newStateName);

            Assert.IsNotNull(myNewState);

            // Make sure the value is 0/off initially
            Assert.AreEqual(0, myNewState.Value);

            // Create a new hand and initialize it with an object in focus
            var leftHand = new TestHand(Handedness.Left);

            yield return(ShowHandWithObjectInFocus(leftHand));

            // Make sure the value of MyNewState was changed when the object is in focus
            Assert.AreEqual(1, myNewState.Value);

            // Move hand away from object to remove focus
            yield return(MoveHandOutOfFocus(leftHand));

            // Make sure the value of MyNewState was changed when the object is no longer in focus
            Assert.AreEqual(0, myNewState.Value);
        }
        public IEnumerator TestSelectFarEventConfiguration()
        {
            // Create an interactive cube
            InteractiveElement interactiveElement = CreateInteractiveCube();

            yield return(null);

            // Add the selectFar state
            InteractionState selectFar = interactiveElement.AddNewState(selectFarStateName);

            yield return(null);

            // Get the event configuration for the SelectFar state
            var eventConfiguration = interactiveElement.GetStateEvents <SelectFarEvents>(selectFarStateName);

            // Set global to true, this registers the IMixedRealityPointerHandler
            eventConfiguration.Global = true;

            bool onSelectDown    = false;
            bool onSelectHold    = false;
            bool onSelectClicked = false;
            bool onSelectUp      = false;

            eventConfiguration.OnSelectDown.AddListener((eventData) => { onSelectDown = true; });
            eventConfiguration.OnSelectHold.AddListener((eventData) => { onSelectHold = true; });
            eventConfiguration.OnSelectClicked.AddListener((eventData) => { onSelectClicked = true; });
            eventConfiguration.OnSelectUp.AddListener((eventData) => { onSelectUp = true; });

            // Create a new hand and initialize it with an object in focus
            var leftHand = new TestHand(Handedness.Left);

            // Show hand at starting position
            yield return(ShowHandWithObjectInFocus(leftHand));

            yield return(MoveHandOutOfFocus(leftHand));

            // Click the hand to trigger far select events
            yield return(leftHand.Click());

            Assert.True(onSelectDown);
            Assert.True(onSelectHold);
            Assert.True(onSelectClicked);
            Assert.True(onSelectUp);

            eventConfiguration.Global = false;

            yield return(leftHand.SetGesture(ArticulatedHandPose.GestureId.Pinch));

            // Make sure the SelectFar state is not active after setting global to false without an object in focus
            Assert.AreEqual(0, selectFar.Value);
        }
        public IEnumerator TestFocusEventConfiguration()
        {
            // Create an interactive cube
            InteractiveElement interactiveElement = CreateInteractiveCube();

            yield return(null);

            // The focus state is a state that is added by default
            InteractionState focusState = interactiveElement.GetState(focusStateName);

            yield return(null);

            // Get the event configuration for the focus state
            var eventConfiguration = interactiveElement.GetStateEvents <FocusEvents>(focusStateName);

            bool onFocusOn  = false;
            bool onFocusOff = false;

            eventConfiguration.OnFocusOn.AddListener((eventData) =>
            {
                onFocusOn = true;
            });

            eventConfiguration.OnFocusOff.AddListener((eventData) =>
            {
                onFocusOff = true;
            });

            // Create a new hand and initialize it with an object in focus
            var leftHand = new TestHand(Handedness.Left);

            yield return(ShowHandWithObjectInFocus(leftHand));

            // Check if OnFocusOn has fired
            Assert.True(onFocusOn);

            // Move the Hand out of focus
            yield return(MoveHandOutOfFocus(leftHand));

            // Check if OnFocusOn has fired
            Assert.True(onFocusOff);

            yield return(null);
        }
        public IEnumerator TestEventConfigOfNewState()
        {
            // Create an interactive cube
            InteractiveElement interactiveElement = CreateInteractiveCube();

            yield return(null);

            // Create a new state
            interactiveElement.AddNewState(newStateName);

            // Get the event configuration
            var eventConfiguration = interactiveElement.GetStateEvents <StateEvents>(newStateName);

            bool onStateOn  = false;
            bool onStateOff = false;

            eventConfiguration.OnStateOn.AddListener(() =>
            {
                onStateOn = true;
            });

            eventConfiguration.OnStateOff.AddListener(() =>
            {
                onStateOff = true;
            });

            interactiveElement.SetStateOn(newStateName);
            yield return(null);

            // Check if OnFocusOn has fired
            Assert.True(onStateOn);

            interactiveElement.SetStateOff(newStateName);
            yield return(null);

            // Check if OnFocusOn has fired
            Assert.True(onStateOff);

            yield return(null);
        }
        public IEnumerator TestFocusNearFarEventConfiguration()
        {
            // Create an interactive cube
            InteractiveElement interactiveElement = CreateInteractiveCube();

            yield return(null);

            // The focus state is a state that is added by default
            InteractionState focusState = interactiveElement.GetState(focusStateName);

            yield return(null);

            // Add FocusNear state
            InteractionState focusNearState = interactiveElement.AddNewState(focusNearStateName);

            yield return(null);

            // Add FocusFar state
            InteractionState focusFarState = interactiveElement.AddNewState(focusFarStateName);

            yield return(null);

            // Get event configuration for the states
            var eventConfigurationFocusNear = interactiveElement.GetStateEvents <FocusEvents>(focusNearStateName);
            var eventConfigurationFocusFar  = interactiveElement.GetStateEvents <FocusEvents>(focusFarStateName);

            // Define flags for events
            bool onFocusNearOn  = false;
            bool onFocusNearOff = false;
            bool onFocusFarOn   = false;
            bool onFocusFarOff  = false;

            // Add Focus Near event listeners
            eventConfigurationFocusNear.OnFocusOn.AddListener((eventData) => { onFocusNearOn = true; });
            eventConfigurationFocusNear.OnFocusOff.AddListener((eventData) => { onFocusNearOff = true; });

            // Add Focus Far event listeners
            eventConfigurationFocusFar.OnFocusOn.AddListener((eventData) => { onFocusFarOn = true; });
            eventConfigurationFocusFar.OnFocusOff.AddListener((eventData) => { onFocusFarOff = true; });

            // Create a new hand and initialize it with an object in focus
            var leftHand = new TestHand(Handedness.Left);

            yield return(ShowHandWithObjectInFocus(leftHand));

            // Make sure the Focus state and Focus Far state are on
            Assert.AreEqual(1, focusState.Value);
            Assert.AreEqual(1, focusFarState.Value);
            Assert.True(onFocusFarOn);

            // Move the Hand out of focus
            yield return(MoveHandOutOfFocus(leftHand));

            // Make sure the Focus state and Focus Far state are off
            Assert.AreEqual(0, focusState.Value);
            Assert.AreEqual(0, focusFarState.Value);
            Assert.True(onFocusFarOff);

            // Move hand to a near focus position
            yield return(leftHand.Move(new Vector3(0, 0.22f, 0.221f)));

            // Make sure the Focus state and Focus Near state are on
            Assert.AreEqual(1, focusState.Value);
            Assert.AreEqual(1, focusNearState.Value);
            Assert.True(onFocusNearOn);

            // Move the Hand out of focus
            yield return(leftHand.Hide());

            // Make sure the Focus state and Focus Near state are off
            Assert.AreEqual(0, focusState.Value);
            Assert.AreEqual(0, focusNearState.Value);
            Assert.True(onFocusNearOff);
        }