Пример #1
0
 public InputControl AddControl(SupportedControl supportedControl, InputControl control)
 {
     if (!control.GetType().IsAssignableFrom(supportedControl.controlType.value))
     {
         throw new Exception("Control type does not match type of SupportedControl.");
     }
     return(AddControl(supportedControl, control, m_DefaultAdditionsAsStandardized));
 }
        public static unsafe void WriteValueIntoState <TValue>(this InputControl control, TValue value, void *statePtr)
            where TValue : struct
        {
            if (control == null)
            {
                throw new ArgumentNullException("control");
            }

            var controlOfType = control as InputControl <TValue>;

            if (controlOfType == null)
            {
                throw new ArgumentException(string.Format("Expecting control of type '{0}' but got '{1}'",
                                                          typeof(TValue).Name, control.GetType().Name));
            }

            controlOfType.WriteValueIntoState(value, statePtr);
        }
        private GenericControlEvent GetControlResetEventForControl(InputControl control)
        {
            Type genericType = control.GetType();

            while (genericType.BaseType != typeof(InputControl))
            {
                genericType = genericType.BaseType;
            }
            if (genericType.GetGenericTypeDefinition() != typeof(InputControl <>))
            {
                return(null);
            }
            Type genericArgumentType = genericType.GetGenericArguments()[0];
            Type eventType           = typeof(GenericControlEvent <>).MakeGenericType(new System.Type[] { genericArgumentType });
            GenericControlEvent evt  = (GenericControlEvent)Activator.CreateInstance(eventType);

            evt.controlIndex = control.index;
            evt.CopyDefaultValueFromControl(control);
            evt.time = Time.time;
            return(evt);
        }
        public static void WriteValueIntoEvent <TValue>(this InputControl control, TValue value, InputEventPtr eventPtr)
            where TValue : struct
        {
            if (control == null)
            {
                throw new ArgumentNullException("control");
            }
            if (!eventPtr.valid)
            {
                throw new ArgumentNullException("eventPtr");
            }

            var controlOfType = control as InputControl <TValue>;

            if (controlOfType == null)
            {
                throw new ArgumentException(string.Format("Expecting control of type '{0}' but got '{1}'",
                                                          typeof(TValue).Name, control.GetType().Name));
            }

            controlOfType.WriteValueIntoEvent(value, eventPtr);
        }
        public static void WriteValueIntoEvent <TValue>(this InputControl control, TValue value, InputEventPtr eventPtr)
            where TValue : struct
        {
            if (control == null)
            {
                throw new ArgumentNullException(nameof(control));
            }
            if (!eventPtr.valid)
            {
                throw new ArgumentNullException(nameof(eventPtr));
            }

            if (!(control is InputControl <TValue> controlOfType))
            {
                throw new ArgumentException(
                          $"Expecting control of type '{typeof(TValue).Name}' but got '{control.GetType().Name}'");
            }

            controlOfType.WriteValueIntoEvent(value, eventPtr);
        }
        public static unsafe void WriteValueIntoState <TValue>(this InputControl control, TValue value, void *statePtr)
            where TValue : struct
        {
            if (control == null)
            {
                throw new ArgumentNullException(nameof(control));
            }

            if (!(control is InputControl <TValue> controlOfType))
            {
                throw new ArgumentException(
                          $"Expecting control of type '{typeof(TValue).Name}' but got '{control.GetType().Name}'");
            }

            controlOfType.WriteValueIntoState(value, statePtr);
        }
Пример #7
0
        private InputControl InstantiateLayout(InputControlLayout layout, InternedString variant, InternedString name, InputControl parent, InputControl existingControl)
        {
            InputControl control;

            // If we have an existing control, see whether it's usable.
            if (existingControl != null && existingControl.layout == layout.name && existingControl.GetType() == layout.type)
            {
                control = existingControl;

                ////FIXME: the re-use path probably has some data that could stick around when it shouldn't
                control.m_UsagesReadOnly = new ReadOnlyArray <InternedString>();
                control.ClearProcessors();
            }
            else
            {
                Debug.Assert(layout.type != null);

                // No, so create a new control.
                var controlObject = Activator.CreateInstance(layout.type);
                control = controlObject as InputControl;
                if (control == null)
                {
                    throw new Exception(string.Format("Type '{0}' referenced by layout '{1}' is not an InputControl",
                                                      layout.type.Name, layout.name));
                }
            }

            // If it's a device, perform some extra work specific to the control
            // hierarchy root.
            var controlAsDevice = control as InputDevice;

            if (controlAsDevice != null)
            {
                if (parent != null)
                {
                    throw new Exception(string.Format(
                                            "Cannot instantiate device layout '{0}' as child of '{1}'; devices must be added at root",
                                            layout.name, parent.path));
                }

                m_Device = controlAsDevice;
                m_Device.m_StateBlock.byteOffset = 0;
                m_Device.m_StateBlock.format     = layout.stateFormat;

                // If we have an existing device, we'll start the various control arrays
                // from scratch. Note that all the controls still refer to the existing
                // arrays and so we can iterate children, for example, just fine while
                // we are rebuilding the control hierarchy.
                m_Device.m_AliasesForEachControl  = null;
                m_Device.m_ChildrenForEachControl = null;
                m_Device.m_UsagesForEachControl   = null;
                m_Device.m_UsageToControl         = null;

                // But we preserve IDs and descriptions of existing devices.
                if (existingControl != null)
                {
                    var existingDevice = (InputDevice)existingControl;
                    m_Device.m_Id          = existingDevice.m_Id;
                    m_Device.m_Description = existingDevice.m_Description;
                }

                if (layout.m_UpdateBeforeRender == true)
                {
                    m_Device.m_Flags |= InputDevice.Flags.UpdateBeforeRender;
                }
            }
            else if (parent == null)
            {
                // Someone did "new InputDeviceBuilder(...)" with a control layout.
                // We don't support creating control hierarchies without a device at the root.
                throw new InvalidOperationException(
                          string.Format(
                              "Toplevel layout used with InputDeviceBuilder must be a device layout; '{0}' is a control layout",
                              layout.name));
            }

            // Name defaults to name of layout.
            if (name.IsEmpty())
            {
                name = layout.name;

                // If there's a namespace in the layout name, snip it out.
                var indexOfLastColon = name.ToString().LastIndexOf(':');
                if (indexOfLastColon != -1)
                {
                    name = new InternedString(name.ToString().Substring(indexOfLastColon + 1));
                }
            }

            // Variant defaults to variant of layout.
            if (variant.IsEmpty())
            {
                variant = layout.variant;

                if (variant.IsEmpty())
                {
                    variant = InputControlLayout.DefaultVariant;
                }
            }

            control.m_Name = name;
            control.m_DisplayNameFromLayout = layout.m_DisplayName;
            control.m_Layout  = layout.name;
            control.m_Variant = variant;
            control.m_Parent  = parent;
            control.m_Device  = m_Device;

            // Create children and configure their settings from our
            // layout values.
            var haveChildrenUsingStateFromOtherControl = false;

            try
            {
                // Pass list of existing control on to function as we may have decided to not
                // actually reuse the existing control (and thus control.m_ChildrenReadOnly will
                // now be blank) but still want crawling down the hierarchy to preserve existing
                // controls where possible.
                AddChildControls(layout, variant, control,
                                 existingControl != null ? existingControl.m_ChildrenReadOnly : (ReadOnlyArray <InputControl>?)null,
                                 ref haveChildrenUsingStateFromOtherControl);
            }
            catch
            {
                ////TODO: remove control from collection and rethrow
                throw;
            }

            // Come up with a layout for our state.
            ComputeStateLayout(control);

            // Finally, if we have child controls that take their state blocks from other
            // controls, assign them their blocks now.
            if (haveChildrenUsingStateFromOtherControl)
            {
                foreach (var controlLayout in layout.controls)
                {
                    if (string.IsNullOrEmpty(controlLayout.useStateFrom))
                    {
                        continue;
                    }

                    var child = TryGetControl(control, controlLayout.name);
                    Debug.Assert(child != null);

                    // Find the referenced control.
                    var referencedControl = TryGetControl(control, controlLayout.useStateFrom);
                    if (referencedControl == null)
                    {
                        throw new Exception(
                                  string.Format(
                                      "Cannot find control '{0}' referenced in 'useStateFrom' of control '{1}' in layout '{2}'",
                                      controlLayout.useStateFrom, controlLayout.name, layout.name));
                    }

                    // Copy its state settings.
                    child.m_StateBlock = referencedControl.m_StateBlock;

                    // At this point, all byteOffsets are relative to parents so we need to
                    // walk up the referenced control's parent chain and add offsets until
                    // we are at the same level that we are at.
                    for (var parentInChain = referencedControl.parent; parentInChain != control; parentInChain = parentInChain.parent)
                    {
                        child.m_StateBlock.byteOffset += parentInChain.m_StateBlock.byteOffset;
                    }
                }
            }

            return(control);
        }