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 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 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 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 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);
        }