Esempio n. 1
0
    public unsafe void Utilities_CanCompareMemoryBitRegions()
    {
        using (var array1 = new NativeArray <byte>(6, Allocator.Temp))
            using (var array2 = new NativeArray <byte>(6, Allocator.Temp))
            {
                var array1Ptr = (byte *)array1.GetUnsafePtr();
                var array2Ptr = (byte *)array2.GetUnsafePtr();

                MemoryHelpers.SetBitsInBuffer(array1Ptr, 0, 2, 1, true);

                Assert.That(MemoryHelpers.MemCmpBitRegion(array1Ptr, array2Ptr, 2, 1), Is.False);

                MemoryHelpers.SetBitsInBuffer(array2Ptr, 0, 2, 1, true);

                Assert.That(MemoryHelpers.MemCmpBitRegion(array1Ptr, array2Ptr, 2, 1), Is.True);

                UnsafeUtility.MemClear(array1Ptr, 6);
                UnsafeUtility.MemClear(array2Ptr, 6);

                MemoryHelpers.SetBitsInBuffer(array1Ptr, 0, 5, 24, true);

                Assert.That(MemoryHelpers.MemCmpBitRegion(array1Ptr, array2Ptr, 5, 24), Is.False);

                MemoryHelpers.SetBitsInBuffer(array2Ptr, 0, 5, 24, true);

                Assert.That(MemoryHelpers.MemCmpBitRegion(array1Ptr, array2Ptr, 5, 24), Is.True);
            }
    }
Esempio n. 2
0
        /// <summary>
        /// Compare the control's stored state in <paramref name="firstStatePtr"/> to <paramref name="secondStatePtr"/>.
        /// </summary>
        /// <param name="firstStatePtr">Memory containing the control's <see cref="InputControl.stateBlock"/>.</param>
        /// <param name="secondStatePtr">Memory containing the control's <see cref="InputControl.stateBlock"/></param>
        /// <param name="maskPtr">Optional mask. If supplied, it will be used to mask the comparison between
        /// <paramref name="firstStatePtr"/> and <paramref name="secondStatePtr"/> such that any bit not set in the
        /// mask will be ignored even if different between the two states. This can be used, for example, to ignore
        /// noise in the state (<see cref="InputControl.noiseMaskPtr"/>).</param>
        /// <returns>True if the state is equivalent in both memory buffers.</returns>
        /// <remarks>
        /// Unlike <see cref="InputControl.CompareValue"/>, this method only compares raw memory state. If used on a stick, for example,
        /// it may mean that this method returns false for two stick values that would compare equal using <see cref="CompareValue"/>
        /// (e.g. if both stick values fall below the deadzone).
        /// </remarks>
        /// <seealso cref="InputControl.CompareValue"/>
        public static unsafe bool CompareState(this InputControl control, void *firstStatePtr, void *secondStatePtr, void *maskPtr = null)
        {
            ////REVIEW: for compound controls, do we want to go check leaves so as to not pick up on non-control noise in the state?
            ////        e.g. from HID input reports; or should we just leave that to maskPtr?

            var firstPtr  = (byte *)firstStatePtr + (int)control.m_StateBlock.byteOffset;
            var secondPtr = (byte *)secondStatePtr + (int)control.m_StateBlock.byteOffset;
            var mask      = maskPtr != null ? (byte *)maskPtr + (int)control.m_StateBlock.byteOffset : null;

            if (control.m_StateBlock.sizeInBits == 1)
            {
                // If we have a mask and the bit is set in the mask, the control is to be ignored
                // and thus we consider it at default value.
                if (mask != null && MemoryHelpers.ReadSingleBit(mask, control.m_StateBlock.bitOffset))
                {
                    return(true);
                }

                return(MemoryHelpers.ReadSingleBit(secondPtr, control.m_StateBlock.bitOffset) ==
                       MemoryHelpers.ReadSingleBit(firstPtr, control.m_StateBlock.bitOffset));
            }

            return(MemoryHelpers.MemCmpBitRegion(firstPtr, secondPtr,
                                                 control.m_StateBlock.bitOffset, control.m_StateBlock.sizeInBits, mask));
        }
Esempio n. 3
0
        ////TODO: expose the checks for default state

        /// <summary>
        /// Check if the given state corresponds to the default state of the control/device.
        /// </summary>
        /// <param name="statePtr">Pointer to a state buffer or null to use <see cref="currentStatePtr"/>.</param>
        /// <param name="maskPtr">If not null, any bits set to true in the buffer will be ignored. This can be used
        /// to mask out noise.</param>
        /// <returns>True if the control/device is in its default state.</returns>
        /// <remarks>
        /// Note that default does not equate all zeroes. Stick axes, for example, that are stored as unsigned byte
        /// values will have their resting position at 127 and not at 0. This is why we explicitly store default
        /// state in a memory buffer instead of assuming zeroes.
        /// </remarks>
        /// <seealso cref="InputStateBuffers.defaultStateBuffer"/>
        internal unsafe bool CheckStateIsAtDefault(void *statePtr = null, void *maskPtr = null)
        {
            ////REVIEW: for compound controls, do we want to go check leaves so as to not pick up on non-control noise in the state?
            ////        e.g. from HID input reports

            if (statePtr == null)
            {
                statePtr = currentStatePtr;
            }

            var defaultValuePtr = (byte *)defaultStatePtr + (int)m_StateBlock.byteOffset;
            var valuePtr        = (byte *)statePtr + (int)m_StateBlock.byteOffset;

            if (m_StateBlock.sizeInBits == 1)
            {
                // If we have a mask and the bit is set in the mask, the control is to be ignored
                // and thus we consider it at default value.
                if (maskPtr != null && MemoryHelpers.ReadSingleBit(maskPtr, m_StateBlock.bitOffset))
                {
                    return(true);
                }

                return(MemoryHelpers.ReadSingleBit(valuePtr, m_StateBlock.bitOffset) ==
                       MemoryHelpers.ReadSingleBit(defaultValuePtr, m_StateBlock.bitOffset));
            }

            return(MemoryHelpers.MemCmpBitRegion(defaultValuePtr, valuePtr,
                                                 m_StateBlock.bitOffset, m_StateBlock.sizeInBits));
        }
    public unsafe void Utilities_CanCompareMemoryBitRegions_AndIgnoreBitsUsingMask()
    {
        using (var array1 = new NativeArray <byte>(8, Allocator.Temp))
            using (var array2 = new NativeArray <byte>(8, Allocator.Temp))
                using (var mask = new NativeArray <byte>(8, Allocator.Temp))
                {
                    var array1Ptr = (byte *)array1.GetUnsafePtr();
                    var array2Ptr = (byte *)array2.GetUnsafePtr();
                    var maskPtr   = (byte *)mask.GetUnsafePtr();

                    // Set bit #2 in array1.
                    MemoryHelpers.SetBitsInBuffer(array1Ptr, 0, 2, 1, true);

                    Assert.That(MemoryHelpers.MemCmpBitRegion(array1Ptr, array2Ptr, 2, 1, maskPtr), Is.True);

                    // Set bit #2 in mask.
                    MemoryHelpers.SetBitsInBuffer(maskPtr, 0, 2, 1, true);

                    Assert.That(MemoryHelpers.MemCmpBitRegion(array1Ptr, array2Ptr, 2, 1, maskPtr), Is.False);

                    UnsafeUtility.MemClear(array1Ptr, 8);
                    UnsafeUtility.MemClear(array2Ptr, 8);
                    UnsafeUtility.MemClear(maskPtr, 8);

                    // Set 24 bits in array1 starting at bit #5.
                    MemoryHelpers.SetBitsInBuffer(array1Ptr, 0, 5, 24, true);

                    Assert.That(MemoryHelpers.MemCmpBitRegion(array1Ptr, array2Ptr, 5, 24, maskPtr), Is.True);

                    // Set 20 bits in mask starting at bit #5.
                    MemoryHelpers.SetBitsInBuffer(maskPtr, 0, 5, 20, true);
                    // Set 24 bits in array2 starting at bit #5.
                    MemoryHelpers.SetBitsInBuffer(array2Ptr, 0, 5, 24, true);

                    Assert.That(MemoryHelpers.MemCmpBitRegion(array1Ptr, array2Ptr, 5, 24, maskPtr), Is.True);

                    // Set 21 bits in mask starting at bit #7.
                    MemoryHelpers.SetBitsInBuffer(maskPtr, 0, 7, 21, true);

                    Assert.That(MemoryHelpers.MemCmpBitRegion(array1Ptr, array2Ptr, 5, 24, maskPtr), Is.True);
                }
    }
Esempio n. 5
0
        ////TODO: pass state ptr *NOT* value ptr (it's confusing)
        // NOTE: The given argument should point directly to the value *not* to the
        //       base state to which the state block offset has to be added.
        internal unsafe bool CheckStateIsAtDefault(IntPtr valuePtr = new IntPtr())
        {
            ////REVIEW: for compound controls, do we want to go check leaves so as to not pick up on non-control noise in the state?
            ////        e.g. from HID input reports

            var defaultPtr = new IntPtr((byte *)defaultStatePtr.ToPointer() + (int)m_StateBlock.byteOffset);

            if (valuePtr == IntPtr.Zero)
            {
                valuePtr = new IntPtr(currentStatePtr.ToInt64() + (int)m_StateBlock.byteOffset);
            }

            if (m_StateBlock.sizeInBits == 1)
            {
                return(MemoryHelpers.ReadSingleBit(valuePtr, m_StateBlock.bitOffset) ==
                       MemoryHelpers.ReadSingleBit(defaultPtr, m_StateBlock.bitOffset));
            }

            return(MemoryHelpers.MemCmpBitRegion(defaultPtr.ToPointer(), valuePtr.ToPointer(),
                                                 m_StateBlock.bitOffset, m_StateBlock.sizeInBits));
        }