Пример #1
0
        private static int GetNumPropertiesIn(InputDeviceDescription description)
        {
            var count = 0;

            if (!string.IsNullOrEmpty(description.interfaceName))
            {
                count += 1;
            }
            if (!string.IsNullOrEmpty(description.deviceClass))
            {
                count += 1;
            }
            if (!string.IsNullOrEmpty(description.manufacturer))
            {
                count += 1;
            }
            if (!string.IsNullOrEmpty(description.product))
            {
                count += 1;
            }
            if (!string.IsNullOrEmpty(description.version))
            {
                count += 1;
            }
            if (!string.IsNullOrEmpty(description.capabilities))
            {
                count += 1;
            }
            return(count);
        }
Пример #2
0
        /// <summary>
        /// Produce a matcher that matches the given device description verbatim.
        /// </summary>
        /// <param name="deviceDescription">A device description.</param>
        /// <returns>A matcher that matches <paramref name="deviceDescription"/> exactly.</returns>
        /// <remarks>
        /// This method can be used to produce a matcher for an existing device description,
        /// e.g. when writing a layout <see cref="InputControlLayout.Builder"/> that produces
        /// layouts for devices on the fly.
        /// </remarks>
        public static InputDeviceMatcher FromDeviceDescription(InputDeviceDescription deviceDescription)
        {
            var matcher = new InputDeviceMatcher();

            if (!string.IsNullOrEmpty(deviceDescription.interfaceName))
            {
                matcher = matcher.WithInterface(deviceDescription.interfaceName, false);
            }
            if (!string.IsNullOrEmpty(deviceDescription.deviceClass))
            {
                matcher = matcher.WithDeviceClass(deviceDescription.deviceClass, false);
            }
            if (!string.IsNullOrEmpty(deviceDescription.manufacturer))
            {
                matcher = matcher.WithManufacturer(deviceDescription.manufacturer, false);
            }
            if (!string.IsNullOrEmpty(deviceDescription.product))
            {
                matcher = matcher.WithProduct(deviceDescription.product, false);
            }
            if (!string.IsNullOrEmpty(deviceDescription.version))
            {
                matcher = matcher.WithVersion(deviceDescription.version, false);
            }
            // We don't include capabilities in this conversion.
            return(matcher);
        }
Пример #3
0
        public void Setup(InternedString layout, InternedString variants,
                          InputDeviceDescription deviceDescription = default)
        {
            InstantiateLayout(layout, variants, new InternedString(), null);
            FinalizeControlHierarchy();

            m_Device.m_Description = deviceDescription;
            m_Device.CallFinishSetupRecursive();
        }
Пример #4
0
        public void Setup(InternedString layout, InternedString variants,
                          InputDeviceDescription deviceDescription = default)
        {
            m_LayoutCacheRef = InputControlLayout.CacheRef();

            InstantiateLayout(layout, variants, new InternedString(), null);
            FinalizeControlHierarchy();

            m_StateOffsetToControlMap.Sort();

            m_Device.m_Description             = deviceDescription;
            m_Device.m_StateOffsetToControlMap = m_StateOffsetToControlMap.ToArray();

            m_Device.CallFinishSetupRecursive();
        }
Пример #5
0
        /// <summary>
        /// Return the level of matching to the given <paramref name="deviceDescription"/>.
        /// </summary>
        /// <param name="deviceDescription">A device description.</param>
        /// <returns>A score usually in the range between 0 and 1.</returns>
        /// <remarks>
        /// The algorithm computes a score of how well the matcher matches the given description.
        /// Essentially, a matcher that matches every single property that is present (as in
        /// not <c>null</c> and not an empty string) in <paramref name="deviceDescription"/> receives
        /// a score of 1, a matcher that matches none a score of 0. Matches that match only a subset
        /// receive a score in-between.
        ///
        /// An exception to this are capabilities. Every single match of a capability is counted
        /// as one property match and added to the score. This means that matchers that match
        /// on multiple capabilities may actually achieve a score &gt;1.
        ///
        /// <example>
        /// <code>
        /// var description = new InputDeviceDescription
        /// {
        ///     interfaceName = "HID",
        ///     product = "MadeUpDevice",
        ///     capabilities = new HID.HIDDeviceDescriptor
        ///     {
        ///         vendorId = 0xABC,
        ///         productId = 0xDEF
        ///     }.ToJson()
        /// };
        ///
        /// // This matcher will achieve a score of 0.666 (2/3) as it
        /// // matches two out of three available properties.
        /// new InputDeviceMatcher()
        ///     .WithInterface("HID")
        ///     .WithProduct("MadeUpDevice");
        ///
        /// // This matcher will achieve a score of 1 despite not matching
        /// // 'product'. The reason is that it matches two keys in
        /// // 'capabilities'.
        /// new InputDeviceMatcher()
        ///     .WithInterface("HID")
        ///     .WithCapability("vendorId", 0xABC)
        ///     .WithCapability("productId", 0xDEF);
        /// </code>
        /// </example>
        /// </remarks>
        public float MatchPercentage(InputDeviceDescription deviceDescription)
        {
            if (empty)
            {
                return(0);
            }

            // Go through all patterns. Score is 0 if any of the patterns
            // doesn't match.
            var numPatterns = m_Patterns.Length;

            for (var i = 0; i < numPatterns; ++i)
            {
                var key     = m_Patterns[i].Key;
                var pattern = m_Patterns[i].Value;

                if (key == kInterfaceKey)
                {
                    if (string.IsNullOrEmpty(deviceDescription.interfaceName) ||
                        !MatchSingleProperty(pattern, deviceDescription.interfaceName))
                    {
                        return(0);
                    }
                }
                else if (key == kDeviceClassKey)
                {
                    if (string.IsNullOrEmpty(deviceDescription.deviceClass) ||
                        !MatchSingleProperty(pattern, deviceDescription.deviceClass))
                    {
                        return(0);
                    }
                }
                else if (key == kManufacturerKey)
                {
                    if (string.IsNullOrEmpty(deviceDescription.manufacturer) ||
                        !MatchSingleProperty(pattern, deviceDescription.manufacturer))
                    {
                        return(0);
                    }
                }
                else if (key == kProductKey)
                {
                    if (string.IsNullOrEmpty(deviceDescription.product) ||
                        !MatchSingleProperty(pattern, deviceDescription.product))
                    {
                        return(0);
                    }
                }
                else if (key == kVersionKey)
                {
                    if (string.IsNullOrEmpty(deviceDescription.version) ||
                        !MatchSingleProperty(pattern, deviceDescription.version))
                    {
                        return(0);
                    }
                }
                else
                {
                    // Capabilities match. Take the key as a path into the JSON
                    // object and match the value found at the given path.

                    if (string.IsNullOrEmpty(deviceDescription.capabilities))
                    {
                        return(0);
                    }

                    var graph = new JsonParser(deviceDescription.capabilities);
                    if (!graph.NavigateToProperty(key.ToString()) ||
                        !graph.CurrentPropertyHasValueEqualTo(new JsonParser.JsonValue {
                        type = JsonParser.JsonValueType.Any, anyValue = pattern
                    }))
                    {
                        return(0);
                    }
                }
            }

            // All patterns matched. Our score is determined by the number of properties
            // we matched against.
            var propertyCountInDescription = GetNumPropertiesIn(deviceDescription);
            var scorePerProperty           = 1.0f / propertyCountInDescription;

            return(numPatterns * scorePerProperty);
        }