public IEnumerator TestOnStateActivatedNewState()
        {
            // Create an interactive cube
            InteractiveElement interactiveElement = CreateInteractiveCube();

            yield return(null);

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

            bool stateActivated = false;

            // Use the OnStateActivated event in the State Manager to set stateActivated
            interactiveElement.StateManager.OnStateActivated.AddListener((state) =>
            {
                if (state.Name == newStateName)
                {
                    stateActivated = true;
                }
            });

            // Set the state on
            interactiveElement.SetStateOn(newStateName);

            // Make sure the state was activated
            Assert.True(stateActivated);
        }
        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);
        }
        /// <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 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 TestActiveInactive()
        {
            // Create an interactive cube
            InteractiveElement interactiveElement = CreateInteractiveCube();

            yield return(null);

            // Get the focus state
            InteractionState focusState = interactiveElement.GetState(focusStateName);

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

            yield return(null);

            Assert.True(interactiveElement.Active);

            // Make sure the Focus and Touch state are not on
            Assert.AreEqual(0, touchState.Value);
            Assert.AreEqual(0, focusState.Value);

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

            yield return(ShowHandWithObjectInFocus(leftHand));

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

            // Make sure the values change when the hand is moved to touch the cube
            Assert.AreEqual(1, touchState.Value);
            Assert.AreEqual(1, focusState.Value);
            yield return(null);

            yield return(MoveHandOutOfFocus(leftHand));

            // Set Active to false to disable internal updates
            interactiveElement.Active = false;

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

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

            // Make sure the values do not change when the hand is moved to touch the cube
            Assert.AreEqual(0, touchState.Value);
            Assert.AreEqual(0, focusState.Value);
            yield return(null);
        }
        public IEnumerator TestAddAndRemoveAllStates()
        {
            // Create an interactive cube
            InteractiveElement interactiveElement = CreateInteractiveCube();

            yield return(null);

            string[] coreStates = Enum.GetNames(typeof(CoreInteractionState)).ToArray();

            foreach (string coreStateName in coreStates)
            {
                // The Default and Focus states are present by default
                if (coreStateName != defaultStateName && coreStateName != focusStateName)
                {
                    interactiveElement.AddNewState(coreStateName);
                    yield return(null);
                }
            }

            foreach (string coreStateName in coreStates)
            {
                Assert.IsNotNull(interactiveElement.GetState(coreStateName), $"The {coreStateName} state is null after it was added.");
                yield return(null);
            }

            foreach (string coreStateName in coreStates)
            {
                if (coreStateName != defaultStateName)
                {
                    interactiveElement.RemoveState(coreStateName);
                    yield return(null);
                }
            }

            foreach (string coreStateName in coreStates)
            {
                if (coreStateName != defaultStateName)
                {
                    Assert.IsNull(interactiveElement.GetState(coreStateName), $"The {coreStateName} state is not null after it was removed.");
                    yield return(null);
                }
            }

            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 TestDefaultStateSetting()
        {
            // Create an interactive cube
            InteractiveElement interactiveElement = CreateInteractiveCube();

            yield return(null);

            int newStateCount = 5;

            // Add new states
            for (int i = 0; i < newStateCount; i++)
            {
                interactiveElement.AddNewState("State" + i.ToString());
                yield return(null);
            }

            // The Default state should only be active if no other states are active
            Assert.True(interactiveElement.IsStateActive(defaultStateName));

            // Set each new states to active
            for (int i = 0; i < newStateCount; i++)
            {
                interactiveElement.SetStateOn("State" + i.ToString());

                // If any other state is active, the Default state should not be active
                Assert.False(interactiveElement.IsStateActive(defaultStateName));
            }

            // Set all states to not be active
            for (int i = 0; i < newStateCount; i++)
            {
                interactiveElement.SetStateOff("State" + i.ToString());
            }

            yield return(null);

            // After all the states are deactivated, the Default state should be active
            Assert.True(interactiveElement.IsStateActive(defaultStateName));
        }
        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);
        }