コード例 #1
0
        public void InputTemplateToAbstractConfigurationNodeXmlSerializer_Test()
        {
            var mapcol = new ControllerElementMappingProfile("Keyboard",
                                                             "TEST_CONTROLLER",
                                                             InputDriver.Keyboard,
                                                             IDeviceEnumerator.VirtualVendorID,
                                                             new XInputDeviceInstance(0).DefaultLayout);
            IDeviceInputMapping mapping = new TestInputMapping();
            var input =
                new InputTemplate <IRetroArchInput>(mapcol).Template;


            var fs   = new PhysicalFileSystem();
            var temp = Path.GetTempPath();
            var pfs  = fs.GetOrCreateSubFileSystem(fs.ConvertPathFromInternal(temp));
            var dir  = new FS.Directory("test", pfs, pfs.GetDirectoryEntry("/"));

            var context = new ConfigurationTraversalContext();

            var list = context.TraverseInputTemplate(input, mapping, 0);

            var xmlSerializer = new SimpleXmlConfigurationSerializer("Config");

            string    outputXml = xmlSerializer.Transform(list);
            XDocument doc       = XDocument.Parse(outputXml);

            Assert.NotEmpty(doc.Nodes());
        }
コード例 #2
0
        public void InputTemplateToAbstractConfigurationNodeXmlSerializer_Test()
        {
            var testmappings = new StoneProvider().Controllers["XBOX_CONTROLLER"];
            var realmapping  =
                JsonConvert.DeserializeObject <ControllerLayout>(
                    TestUtilities.GetStringResource("InputMappings.xinput_device.json"));
            var           mapcol   = ControllerElementMappings.GetDefaultMappings(realmapping, testmappings);
            string        _mapping = TestUtilities.GetStringResource("InputMappings.DirectInput.XINPUT_DEVICE.json");
            IInputMapping mapping  = JsonConvert.DeserializeObject <InputMapping>(_mapping);
            var           input    =
                new InputTemplate <IRetroArchInput>(mapcol).Template;


            var fs   = new PhysicalFileSystem();
            var temp = Path.GetTempPath();
            var pfs  = fs.GetOrCreateSubFileSystem(fs.ConvertPathFromInternal(temp));
            var dir  = new FS.Directory("test", pfs, pfs.GetDirectoryEntry("/"));

            var context = new ConfigurationTraversalContext();

            var list = context.TraverseInputTemplate(input, mapping, 0);

            var xmlSerializer = new SimpleXmlConfigurationSerializer("Config");

            string    outputXml = xmlSerializer.Transform(list);
            XDocument doc       = XDocument.Parse(outputXml);

            Assert.NotEmpty(doc.Nodes());
        }
コード例 #3
0
        public async override Task CompileConfiguration()
        {
            var serializer = new SimpleCfgConfigurationSerializer();
            var tokenizer  = new ConfigurationTraversalContext();

            var           node           = tokenizer.TraverseCollection(this.ConfigurationProfile);
            var           retroArchNode  = node["#retroarch"];
            StringBuilder configContents = new StringBuilder();

            configContents.Append(serializer.Transform(retroArchNode));

            var configFile = this.Scratch.OpenDirectory("config")
                             .OpenFile("retroarch.cfg");

            foreach (var port in this.ControllerPorts)
            {
                var mappings = this.InputMappings[port.PhysicalDeviceInstance.Driver];

                var template = new InputTemplate <RetroPadTemplate>(port.LayoutMapping, port.PortIndex);

                template.Template.Configuration.InputJoypadIndex = port.PhysicalDeviceInstance.EnumerationIndex;

                var inputNode = tokenizer.TraverseInputTemplate(template, mappings, port.PortIndex);
                configContents.Append(serializer.Transform(retroArchNode));
            }
            await configFile.WriteAllTextAsync(configContents.ToString());
        }
コード例 #4
0
        private static string ParseImpl(PageInfo pageInfo, ContextInfo contextInfo, string inputName, bool isLoadValues, string inputTemplateString, string successTemplateString, string failureTemplateString)
        {
            var publishmentSystemId = pageInfo.PublishmentSystemId;
            var inputId             = DataProvider.InputDao.GetInputIdAsPossible(inputName, publishmentSystemId);

            if (inputId <= 0)
            {
                return(string.Empty);
            }

            var inputInfo     = DataProvider.InputDao.GetInputInfo(inputId);
            var inputTemplate = new InputTemplate(pageInfo.PublishmentSystemInfo, inputInfo);
            var parsedContent = inputTemplate.GetTemplate(isLoadValues, inputTemplateString, successTemplateString, failureTemplateString);

            var innerBuilder = new StringBuilder(parsedContent);

            StlParserManager.ParseInnerContent(innerBuilder, pageInfo, contextInfo);
            parsedContent = innerBuilder.ToString();

            if (isLoadValues)
            {
                pageInfo.AddPageScriptsIfNotExists(ElementName, $@"
<script language=""vbscript""> 
Function str2asc(strstr) 
 str2asc = hex(asc(strstr)) 
End Function 
Function asc2str(ascasc) 
 asc2str = chr(ascasc) 
End Function 
</script>
<script type=""text/javascript"" src=""{SiteFilesAssets.Input.GetScriptUrl(pageInfo.ApiUrl)}""></script>");
            }

            return(parsedContent);
        }
コード例 #5
0
        private static void ScanTemplate(InputTemplate template)
        {
            foreach (var control in template.controls)
            {
                // Collect unique usages and the templates used with them.
                foreach (var usage in control.usages)
                {
                    var internedUsage           = new InternedString(usage);
                    var internedControlTemplate = new InternedString(control.template);

                    List <InternedString> templateList;
                    if (!s_Usages.TryGetValue(internedUsage, out templateList))
                    {
                        templateList = new List <InternedString> {
                            internedControlTemplate
                        };
                        s_Usages[internedUsage] = templateList;
                    }
                    else
                    {
                        var templateAlreadyInList =
                            templateList.Any(x => x == internedControlTemplate);
                        if (!templateAlreadyInList)
                        {
                            templateList.Add(internedControlTemplate);
                        }
                    }
                }
            }
        }
コード例 #6
0
        ////TODO: move this out into a general routine that can take a path and construct a display name
        private GUIContent GetContentForPath(string path, string modifiers, InputBinding.Flags flags)
        {
            if (s_UsageRegex == null)
            {
                s_UsageRegex = new Regex("\\*/{([A-Za-z0-9]+)}");
            }
            if (s_ControlRegex == null)
            {
                s_ControlRegex = new Regex("<([A-Za-z0-9]+)>/([A-Za-z0-9]+(/[A-Za-z0-9]+)*)");
            }

            var text = path;

            ////TODO: make this less GC heavy
            ////TODO: prettify control names (e.g. "rightTrigger" should read "Right Trigger"); have explicit display names?

            ////REVIEW: This stuff here should really be based on general display functionality for controls
            ////        which should be available to game code in just the same way for on-screen display
            ////        purposes

            var usageMatch = s_UsageRegex.Match(path);

            if (usageMatch.Success)
            {
                text = usageMatch.Groups[1].Value;
            }
            else
            {
                var controlMatch = s_ControlRegex.Match(path);
                if (controlMatch.Success)
                {
                    var device  = controlMatch.Groups[1].Value;
                    var control = controlMatch.Groups[2].Value;

                    ////TODO: would be nice to include template name to print something like "Gamepad A Button" instead of "Gamepad A" (or whatever)

                    text = string.Format("{0} {1}", device, control);
                }
            }

            ////REVIEW: would be nice to have icons for these

            // Show modifiers.
            if (!string.IsNullOrEmpty(modifiers))
            {
                var modifierList   = InputTemplate.ParseNameAndParameterList(modifiers);
                var modifierString = string.Join(" OR ", modifierList.Select(x => x.name).ToArray());
                text = string.Format("{0} {1}", modifierString, text);
            }

            ////TODO: this looks ugly and not very obvious; find a better way
            // Show if linked with previous binding.
            if ((flags & InputBinding.Flags.ThisAndPreviousCombine) == InputBinding.Flags.ThisAndPreviousCombine)
            {
                text = "AND " + text;
            }

            return(new GUIContent(text));
        }
コード例 #7
0
        public override (IInputTemplate <IRetroArchInput> template, IInputMapping mapping) GetInputMappings(
            IEmulatedController emulatedDevice)
        {
            var template = new InputTemplate <IRetroArchInput>(emulatedDevice.LayoutMapping, emulatedDevice.PortIndex);
            var mapping  = (from inputMappings in this.InputMappings
                            where inputMappings.InputApi == InputApi.DirectInput
                            where inputMappings.DeviceLayouts.Contains(emulatedDevice.PhysicalDevice.DeviceLayout.LayoutId.ToString())
                            select inputMappings).FirstOrDefault();

            return(template, mapping);
        }
コード例 #8
0
        public void NestedSetter_Test()
        {
            var mapcol = new ControllerElementMappingProfile("Keyboard",
                                                             "TEST_CONTROLLER",
                                                             InputDriver.Keyboard,
                                                             IDeviceEnumerator.VirtualVendorID,
                                                             new XInputDeviceInstance(0).DefaultLayout);
            var x = new InputTemplate <IRetroArchInput>(mapcol);

            x[ControllerElement.ButtonA] = DeviceCapability.Hat0S;
            Assert.Equal(DeviceCapability.Hat0S, x.Template.Configuration.InputPlayerABtn);
        }
コード例 #9
0
        private static string FindControlTemplateRecursive(ref PathParser parser, InputTemplate template)
        {
            string currentResult = null;

            var controlCount = template.controls.Count;

            for (var i = 0; i < controlCount; ++i)
            {
                if (template.m_Controls[i].isModifyingChildControlByPath)
                {
                    throw new NotImplementedException();
                }

                ////TODO: shortcut the search if we have a match and there's no wildcards to consider

                // Skip control template if it doesn't match.
                if (!ControlTemplateMatchesPathComponent(ref template.m_Controls[i], ref parser))
                {
                    continue;
                }

                var controlTemplateName = template.m_Controls[i].template;

                // If there's more in the path, try to dive into children by jumping to the
                // control's template.
                if (!parser.isAtEnd)
                {
                    var childPathParser = parser;
                    if (childPathParser.MoveToNextComponent())
                    {
                        var childControlTemplateName = FindControlTemplateRecursive(ref childPathParser, controlTemplateName);
                        if (childControlTemplateName != null)
                        {
                            if (currentResult != null && childControlTemplateName != currentResult)
                            {
                                return(null);
                            }
                            currentResult = childControlTemplateName;
                        }
                    }
                }
                else if (currentResult != null && controlTemplateName != currentResult)
                {
                    return(null);
                }
                else
                {
                    currentResult = controlTemplateName.ToString();
                }
            }

            return(currentResult);
        }
コード例 #10
0
        public void NestedSetter_Test()
        {
            var stoneProvider = new StoneProvider();
            var testmappings  = stoneProvider.Controllers.First().Value;
            var realmapping   =
                JsonConvert.DeserializeObject <ControllerLayout>(
                    TestUtilities.GetStringResource("InputMappings.keyboard_device.json"));
            var mapcol = ControllerElementMappings.GetDefaultMappings(realmapping, testmappings);
            var x      = new InputTemplate <IRetroArchInput>(mapcol);

            x[ControllerElement.ButtonA] = ControllerElement.DirectionalS;
            Assert.Equal(ControllerElement.DirectionalS, x.Template.Configuration.InputPlayerABtn);
        }
コード例 #11
0
            private TreeViewItem BuildTreeForDevice(InputTemplate template, ref int id)
            {
                var deviceRoot = new Item
                {
                    displayName = template.name,
                    id          = id++,
                    depth       = 0,
                    device      = template.name
                };

                BuildControlsRecursive(deviceRoot, template, string.Empty, ref id);

                return(deviceRoot);
            }
コード例 #12
0
        private InputControl InsertChildControl(InputTemplate template, InternedString variant, InputControl parent,
                                                ref bool haveChildrenUsingStateFromOtherControls,
                                                ref InputTemplate.ControlTemplate controlTemplate)
        {
            var path = controlTemplate.name.ToString();

            // First we need to find the immediate parent from the given path.
            var indexOfSlash = path.LastIndexOf('/');

            if (indexOfSlash == -1)
            {
                throw new ArgumentException("InsertChildControl has to be called with a slash-separated path", "path");
            }
            Debug.Assert(indexOfSlash != 0);
            var immediateParentPath = path.Substring(0, indexOfSlash);
            var immediateParent     = InputControlPath.TryFindChild(parent, immediateParentPath);

            if (immediateParent == null)
            {
                throw new Exception(
                          string.Format("Cannot find parent '{0}' of control '{1}' in template '{2}'", immediateParentPath,
                                        controlTemplate.name, template.name));
            }

            var controlName = path.Substring(indexOfSlash + 1);

            if (controlName.Length == 0)
            {
                throw new Exception(
                          string.Format("Path cannot end in '/' (control '{0}' in template '{1}')", controlTemplate.name,
                                        template.name));
            }

            // Make room in the device's child array.
            var childStartIndex = immediateParent.m_ChildrenReadOnly.m_StartIndex;
            var childIndex      = childStartIndex + immediateParent.m_ChildrenReadOnly.m_Length;

            ArrayHelpers.InsertAt(ref m_Device.m_ChildrenForEachControl, childIndex, null);
            ++immediateParent.m_ChildrenReadOnly.m_Length;

            // Insert the child.
            var control = AddChildControl(template, variant, immediateParent, null,
                                          ref haveChildrenUsingStateFromOtherControls, ref controlTemplate, ref childIndex, controlName);

            // Adjust indices of control's that have been shifted around by our insertion.
            ShiftChildIndicesInHierarchyOneUp(parent, childIndex);

            return(control);
        }
コード例 #13
0
        private static int ResolveModifiers(string modifierString, ref List <ModifierState> modifiers)
        {
            ////REVIEW: We're piggybacking off the processor parsing here as the two syntaxes are identical. Might consider
            ////        moving the logic to a shared place.
            ////        Alternatively, may split the paths. May help in getting rid of unnecessary allocations.

            var firstModifierIndex = modifiers != null ? modifiers.Count : 0;

            ////TODO: get rid of the extra array allocations here
            var list = InputTemplate.ParseNameAndParameterList(modifierString);

            for (var i = 0; i < list.Length; ++i)
            {
                // Look up modifier.
                var type = InputSystem.TryGetModifier(list[i].name);
                if (type == null)
                {
                    throw new Exception(string.Format(
                                            "No modifier with name '{0}' (mentioned in '{1}') has been registered", list[i].name,
                                            modifierString));
                }

                // Instantiate it.
                var modifier = Activator.CreateInstance(type) as IInputActionModifier;
                if (modifier == null)
                {
                    throw new Exception(string.Format("Modifier '{0}' is not an IInputActionModifier", list[i].name));
                }

                // Pass parameters to it.
                InputControlSetup.SetParameters(modifier, list[i].parameters);

                // Add to list.
                if (modifiers == null)
                {
                    modifiers = new List <ModifierState>();
                }
                modifiers.Add(new ModifierState
                {
                    modifier = modifier,
                    phase    = InputAction.Phase.Waiting
                });
            }

            return(firstModifierIndex);
        }
コード例 #14
0
        public void InputTemplateGetterSetter_Test()
        {
            var realLayout =
                JsonConvert.DeserializeObject <ControllerLayout>(
                    TestUtilities.GetStringResource("InputMappings.keyboard_device.json"));

            var targetLayout =
                JsonConvert.DeserializeObject <ControllerLayout>(
                    TestUtilities.GetStringResource("InputMappings.xinput_device.json"));

            var            mapcol   = ControllerElementMappings.GetDefaultMappings(realLayout, targetLayout);
            IInputTemplate template = new InputTemplate <IRetroArchInput>(mapcol, 0);

            Assert.Equal(ControllerElement.KeyZ, template[ControllerElement.ButtonA]);
            template[ControllerElement.ButtonA] = ControllerElement.KeyX;
            Assert.Equal(ControllerElement.KeyX, template[ControllerElement.ButtonA]);
        }
コード例 #15
0
        public void InputTemplateToAbstractConfigurationNode_Test()
        {
            var mapcol = new ControllerElementMappingProfile("Keyboard",
                                                             "TEST_CONTROLLER",
                                                             InputDriver.Keyboard,
                                                             IDeviceEnumerator.VirtualVendorID,
                                                             new XInputDeviceInstance(0).DefaultLayout);
            IDeviceInputMapping mapping = new TestInputMapping();
            var input =
                new InputTemplate <IRetroArchInput>(mapcol).Template;

            var fs   = new PhysicalFileSystem();
            var temp = Path.GetTempPath();
            var pfs  = fs.GetOrCreateSubFileSystem(fs.ConvertPathFromInternal(temp));
            var dir  = new FS.Directory("test", pfs, pfs.GetDirectoryEntry("/"));

            var context = new ConfigurationTraversalContext(("game", dir));
            var node    = context.TraverseInputTemplate(input, mapping, 0);
        }
コード例 #16
0
        public void InputTemplateGetterSetter_Test()
        {
            var mapcol = new ControllerElementMappingProfile("Keyboard",
                                                             "TEST_CONTROLLER",
                                                             InputDriver.Keyboard,
                                                             IDeviceEnumerator.VirtualVendorID,
                                                             new XInputDeviceInstance(0).DefaultLayout);

            var template = new InputTemplate <IRetroArchInput>(mapcol, 0);

            Assert.Equal(DeviceCapability.Button0, template.Template.InputPlayerABtn);
            template[ControllerElement.ButtonA] = DeviceCapability.Button1;
            template[ControllerElement.ButtonA] = DeviceCapability.Key2;
            template[ControllerElement.ButtonA] = DeviceCapability.Axis0Negative;

            Assert.Equal(DeviceCapability.Button1, template.Template.InputPlayerABtn);
            Assert.Equal(DeviceCapability.Key2, template.Template.InputPlayerA);
            Assert.Equal(DeviceCapability.Axis0Negative, template.Template.InputPlayerAAxis);
        }
コード例 #17
0
        public void IniSerialize_Test()
        {
            var           serializer   = new IniConfigurationSerializer(new BooleanMapping("true", "false"), "nul");
            string        _mapping     = TestUtilities.GetStringResource("InputMappings.DirectInput.XINPUT_DEVICE.json");
            IInputMapping mapping      = JsonConvert.DeserializeObject <InputMapping>(_mapping);
            var           testmappings = new StoneProvider().Controllers.First().Value;
            var           realmapping  =
                JsonConvert.DeserializeObject <ControllerLayout>(
                    TestUtilities.GetStringResource("InputMappings.xinput_device.json"));
            var    mapcol          = ControllerElementMappings.GetDefaultMappings(realmapping, testmappings);
            var    template        = new InputTemplate <IRetroArchInput>(mapcol, 0);
            string serializedValue = new InputSerializer(serializer).Serialize(template, mapping)
                                     .Replace(Environment.NewLine, string.Empty);

            Assert.Equal(
                TestUtilities.GetStringResource("Configurations.ExampleInput.ini")
                .Replace(Environment.NewLine, string.Empty),
                serializedValue);
        }
コード例 #18
0
            private void BuildControlsRecursive(Item parent, InputTemplate template, string prefix, ref int id)
            {
                ////TODO: filter out output controls
                foreach (var control in template.controls)
                {
                    if (control.isModifyingChildControlByPath)
                    {
                        continue;
                    }

                    // Skip variants.
                    if (!string.IsNullOrEmpty(control.variant) && control.variant.ToLower() != "default")
                    {
                        continue;
                    }

                    var controlPath = prefix + control.name;
                    var child       = new Item
                    {
                        id          = id++,
                        depth       = 1,
                        displayName = controlPath,
                        device      = parent.template.name,
                        controlPath = controlPath,
                        template    = template
                    };

                    var childTemplate = EditorInputTemplateCache.TryGetTemplate(control.template);
                    if (childTemplate != null)
                    {
                        BuildControlsRecursive(parent, childTemplate, controlPath + "/", ref id);
                    }

                    parent.AddChild(child);
                }

                if (parent.children != null)
                {
                    parent.children.Sort((a, b) =>
                                         string.Compare(a.displayName, b.displayName, StringComparison.Ordinal));
                }
            }
コード例 #19
0
        public void InputTemplateToAbstractConfigurationNode_Test()
        {
            var testmappings = new StoneProvider().Controllers["XBOX_CONTROLLER"];
            var realmapping  =
                JsonConvert.DeserializeObject <ControllerLayout>(
                    TestUtilities.GetStringResource("InputMappings.xinput_device.json"));
            var           mapcol   = ControllerElementMappings.GetDefaultMappings(realmapping, testmappings);
            string        _mapping = TestUtilities.GetStringResource("InputMappings.DirectInput.XINPUT_DEVICE.json");
            IInputMapping mapping  = JsonConvert.DeserializeObject <InputMapping>(_mapping);
            var           input    =
                new InputTemplate <IRetroArchInput>(mapcol).Template;

            var fs   = new PhysicalFileSystem();
            var temp = Path.GetTempPath();
            var pfs  = fs.GetOrCreateSubFileSystem(fs.ConvertPathFromInternal(temp));
            var dir  = new FS.Directory("test", pfs, pfs.GetDirectoryEntry("/"));

            var context = new ConfigurationTraversalContext(("game", dir));
            var node    = context.TraverseInputTemplate(input, mapping, 0);
        }
コード例 #20
0
        public void Page_Load(object sender, EventArgs e)
        {
            if (IsForbidden)
            {
                return;
            }

            PageUtils.CheckRequestParameter("InputID");

            var inputId = Body.GetQueryInt("InputID");

            _inputInfo = DataProvider.InputDao.GetInputInfo(inputId);

            if (!IsPostBack)
            {
                BreadCrumb(AppManager.Cms.LeftMenu.IdFunction, AppManager.Cms.LeftMenu.Function.IdInput, "预览提交表单", AppManager.Cms.Permission.WebSite.Input);

                LtlInputName.Text = _inputInfo.InputName;

                var inputTemplate = new InputTemplate(PublishmentSystemInfo, _inputInfo);

                string stlElement = $@"<stl:input inputName=""{_inputInfo.InputName}"">{inputTemplate.GetContent()}</stl:input>";

                LtlInputCode.Text = StringUtils.HtmlEncode(stlElement);

                LtlForm.Text = StlParserManager.ParsePreviewContent(PublishmentSystemInfo, stlElement);

                InfoMessage("预览提交表单无法提交信息,如需提交信息请到提交表单管理中进行操作");

                //if (string.IsNullOrEmpty(this.inputInfo.Template))
                //{
                //    InputTemplate inputTemplate = new InputTemplate(base.PublishmentSystemID, this.inputInfo);
                //    this.ltlForm.Text = inputTemplate.GetTemplate();
                //}
                //else
                //{
                //    this.ltlForm.Text = this.inputInfo.Template;
                //}
            }
        }
コード例 #21
0
            public ModifyPopupWindow(SerializedProperty bindingProperty)
            {
                m_FlagsProperty     = bindingProperty.FindPropertyRelative("flags");
                m_ModifiersProperty = bindingProperty.FindPropertyRelative("modifiers");
                m_Flags             = (InputBinding.Flags)m_FlagsProperty.intValue;

                var modifiers = InputSystem.ListModifiers().ToList();

                modifiers.Sort();
                m_ModifierChoices = modifiers.Select(x => new GUIContent(x)).ToArray();

                var modifierString = m_ModifiersProperty.stringValue;

                if (!string.IsNullOrEmpty(modifierString))
                {
                    m_Modifiers = InputTemplate.ParseNameAndParameterList(modifierString);
                }
                else
                {
                    m_Modifiers = new InputTemplate.NameAndParameters[0]; //Array.Empty<InputTemplate.NameAndParameters>();
                }
                InitializeModifierListView();
            }
コード例 #22
0
        public void Main(int publishmentSystemId, int inputId)
        {
            var body = new RequestBody();

            var       publishmentSystemInfo = PublishmentSystemManager.GetPublishmentSystemInfo(publishmentSystemId);
            InputInfo inputInfo             = null;

            if (inputId > 0)
            {
                inputInfo = DataProvider.InputDao.GetInputInfo(inputId);
            }
            if (inputInfo != null)
            {
                var relatedIdentities = RelatedIdentities.GetRelatedIdentities(ETableStyle.InputContent, publishmentSystemId, inputInfo.InputId);

                var ipAddress = PageUtils.GetIpAddress();

                var contentInfo = new InputContentInfo(0, inputInfo.InputId, 0, inputInfo.IsChecked, body.UserName, ipAddress, DateTime.Now, string.Empty);

                try
                {
                    if (!inputInfo.Additional.IsAnomynous && !body.IsUserLoggin)
                    {
                        throw new Exception("请先登录系统!");
                    }

                    InputTypeParser.AddValuesToAttributes(ETableStyle.InputContent, DataProvider.InputContentDao.TableName, publishmentSystemInfo, relatedIdentities, HttpContext.Current.Request.Form, contentInfo.Attributes, false);

                    if (HttpContext.Current.Request.Files.Count > 0)
                    {
                        foreach (var attributeName in HttpContext.Current.Request.Files.AllKeys)
                        {
                            var myFile = HttpContext.Current.Request.Files[attributeName];
                            if (myFile == null || "" == myFile.FileName)
                            {
                                continue;
                            }

                            var fileUrl = UploadFile(publishmentSystemInfo, myFile);
                            contentInfo.SetExtendedAttribute(attributeName, fileUrl);
                        }
                    }

                    DataProvider.InputContentDao.Insert(contentInfo);

                    string message;
                    if (string.IsNullOrEmpty(HttpContext.Current.Request.Form["successTemplateString"]))
                    {
                        if (string.IsNullOrEmpty(inputInfo.Additional.MessageSuccess))
                        {
                            message = "表单提交成功,正在审核。";
                            if (contentInfo.IsChecked)
                            {
                                message = "表单提交成功。";
                            }
                        }
                        else
                        {
                            message = inputInfo.Additional.MessageSuccess;
                        }
                    }
                    else
                    {
                        message = TranslateUtils.DecryptStringBySecretKey(HttpContext.Current.Request.Form["successTemplateString"]);
                    }

                    HttpContext.Current.Response.Write(InputTemplate.GetInputCallbackScript(publishmentSystemInfo, inputId, true, message));
                    HttpContext.Current.Response.End();

                    //if (contentInfo.IsChecked == EBoolean.True)
                    //{
                    //    FileSystemObject FSO = new FileSystemObject(base.PublishmentSystemID);
                    //    FSO.CreateImmediately(EChangedType.Add, ETemplateTypeUtils.GetEnumType(templateType), channelID, contentID, fileTemplateID);
                    //}
                }
                catch (Exception ex)
                {
                    string message;
                    if (string.IsNullOrEmpty(HttpContext.Current.Request.Form["failureTemplateString"]))
                    {
                        if (string.IsNullOrEmpty(inputInfo.Additional.MessageFailure))
                        {
                            message = "表单提交失败," + ex.Message;
                        }
                        else
                        {
                            message = inputInfo.Additional.MessageFailure;
                        }
                    }
                    else
                    {
                        message = TranslateUtils.DecryptStringBySecretKey(HttpContext.Current.Request.Form["failureTemplateString"]);
                    }

                    HttpContext.Current.Response.Write(InputTemplate.GetInputCallbackScript(publishmentSystemInfo, inputId, false, message));
                    HttpContext.Current.Response.End();
                }
            }
        }
コード例 #23
0
        private void ModifyChildControl(InputTemplate template, InternedString variant, InputControl parent,
                                        ref bool haveChildrenUsingStateFromOtherControls,
                                        ref InputTemplate.ControlTemplate controlTemplate)
        {
            // Controls layout themselves as we come back up the hierarchy. However, when we
            // apply layout modifications reaching *into* the hierarchy, we need to retrigger
            // layouting on their parents.
            var haveChangedLayoutOfParent = false;

            // Find the child control.
            var child = TryGetControl(parent, controlTemplate.name);

            if (child == null)
            {
                // We're adding a child somewhere in the existing hierarchy. This is a tricky
                // case as we have to potentially shift indices around in the hierarchy to make
                // room for the new control.

                ////TODO: this path does not support recovering existing controls? does it matter?

                child = InsertChildControl(template, variant, parent,
                                           ref haveChildrenUsingStateFromOtherControls, ref controlTemplate);
                haveChangedLayoutOfParent = true;
            }
            else
            {
                // Apply modifications.
                if (controlTemplate.sizeInBits != 0 &&
                    child.m_StateBlock.sizeInBits != controlTemplate.sizeInBits)
                {
                    child.m_StateBlock.sizeInBits = controlTemplate.sizeInBits;
                }
                if (controlTemplate.format != 0 && child.m_StateBlock.format != controlTemplate.format)
                {
                    SetFormat(child, controlTemplate);
                    haveChangedLayoutOfParent = true;
                }
                ////REVIEW: ATM, when you move a child with a fixed offset, we only move the child
                ////        and don't move the parent or siblings. What this means is that if you move
                ////        leftStick/x, for example, leftStick stays put. ATM you have to move *all*
                ////        controls that are part of a chain manually. Not sure what the best behavior
                ////        is. If we opt to move parents along with children, we have to make sure we
                ////        are not colliding with any other relocations of children (e.g. if you move
                ////        both leftStick/x and leftStick/y, leftStick itself should move only once and
                ////        not at all if there indeed is a leftStick control template with an offset;
                ////        so, it'd get quite complicated)
                if (controlTemplate.offset != InputStateBlock.kInvalidOffset)
                {
                    child.m_StateBlock.byteOffset = controlTemplate.offset;
                }
                if (controlTemplate.bit != InputStateBlock.kInvalidOffset)
                {
                    child.m_StateBlock.bitOffset = controlTemplate.bit;
                }
                if (controlTemplate.processors.Count > 0)
                {
                    AddProcessors(child, ref controlTemplate, template.name);
                }
                if (controlTemplate.parameters.Count > 0)
                {
                    SetParameters(child, controlTemplate.parameters);
                }
                if (!string.IsNullOrEmpty(controlTemplate.displayName))
                {
                    child.m_DisplayNameFromTemplate = controlTemplate.displayName;
                }

                ////TODO: other modifications
            }

            // Apply layout change.
            ////REVIEW: not sure what's better here; trigger this immediately means we may trigger
            ////        it a number of times on the same parent but doing it as a final pass would
            ////        require either collecting the necessary parents or doing another pass through
            ////        the list of control templates
            if (haveChangedLayoutOfParent && !ReferenceEquals(child.parent, parent))
            {
                ComputeStateLayout(child.parent);
            }
        }
コード例 #24
0
        private void AddChildControls(InputTemplate template, InternedString variant, InputControl parent, ReadOnlyArray <InputControl>?existingChildren, ref bool haveChildrenUsingStateFromOtherControls)
        {
            var controlTemplates = template.m_Controls;

            if (controlTemplates == null)
            {
                return;
            }

            // Find out how many direct children we will add.
            var childCount = 0;
            var haveControlTemplateWithPath = false;

            for (var i = 0; i < controlTemplates.Length; ++i)
            {
                // Not a new child if it's a template reaching in to the hierarchy to modify
                // an existing child.
                if (controlTemplates[i].isModifyingChildControlByPath)
                {
                    haveControlTemplateWithPath = true;
                    continue;
                }

                // Skip if variant doesn't match.
                if (!controlTemplates[i].variant.IsEmpty() &&
                    controlTemplates[i].variant != variant)
                {
                    continue;
                }

                ++childCount;
            }

            // Add room for us in the device's child array.
            var firstChildIndex = ArrayHelpers.GrowBy(ref m_Device.m_ChildrenForEachControl, childCount);

            // Add controls from all control templates except the ones that have
            // paths in them.
            var childIndex = firstChildIndex;

            for (var i = 0; i < controlTemplates.Length; ++i)
            {
                var controlTemplate = controlTemplates[i];

                // Skip control templates that don't add controls but rather modify child
                // controls of other controls added by the template. We do a second pass
                // to apply their settings.
                if (controlTemplate.isModifyingChildControlByPath)
                {
                    continue;
                }

                // If the control is part of a variant, skip it if it isn't the variant we're
                // looking for.
                if (!controlTemplate.variant.IsEmpty() && controlTemplate.variant != variant)
                {
                    continue;
                }

                AddChildControl(template, variant, parent, existingChildren, ref haveChildrenUsingStateFromOtherControls,
                                ref controlTemplate, ref childIndex);
            }

            // Install child array on parent. We will later patch up the array
            // reference again as we finalize the hierarchy. However, the reference
            // will point to a valid child array all the same even while we are
            // constructing the hierarchy.
            //
            // NOTE: It's important to do this *after* the loop above where we call AddControl for each child
            //       as each child may end up moving the m_ChildrenForEachControl array around.
            parent.m_ChildrenReadOnly = new ReadOnlyArray <InputControl>(m_Device.m_ChildrenForEachControl, firstChildIndex, childCount);

            // Apply control modifications from control templates with paths.
            if (haveControlTemplateWithPath)
            {
                for (var i = 0; i < controlTemplates.Length; ++i)
                {
                    var controlTemplate = controlTemplates[i];
                    if (!controlTemplate.isModifyingChildControlByPath)
                    {
                        continue;
                    }

                    // If the control is part of a variant, skip it if it isn't the variant we're
                    // looking for.
                    if (!controlTemplate.variant.IsEmpty() && controlTemplate.variant != variant)
                    {
                        continue;
                    }

                    ModifyChildControl(template, variant, parent, ref haveChildrenUsingStateFromOtherControls,
                                       ref controlTemplate);
                }
            }
        }
コード例 #25
0
        private InputControl AddControlRecursive(InputTemplate template, 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.template == template.name && existingControl.GetType() == template.type)
            {
                control = existingControl;
            }
            else
            {
                Debug.Assert(template.type != null);

                // No, so create a new control.
                var controlObject = Activator.CreateInstance(template.type);
                control = controlObject as InputControl;
                if (control == null)
                {
                    throw new Exception(string.Format("Type '{0}' referenced by template '{1}' is not an InputControl",
                                                      template.type.Name, template.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 template '{0}' as child of '{1}'; devices must be added at root",
                                            template.name, parent.path));
                }

                m_Device = controlAsDevice;
                m_Device.m_StateBlock.byteOffset = 0;
                m_Device.m_StateBlock.format     = template.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 (template.m_UpdateBeforeRender == true)
                {
                    m_Device.m_Flags |= InputDevice.Flags.UpdateBeforeRender;
                }

                // Devices get their names from the topmost base templates.
                if (name.IsEmpty())
                {
                    name = InputTemplate.s_Templates.GetRootTemplateName(template.name);

                    // If there's a namespace in the template name, snip it out.
                    var indexOfLastColon = name.ToString().LastIndexOf(':');
                    if (indexOfLastColon != -1)
                    {
                        name = new InternedString(name.ToString().Substring(indexOfLastColon + 1));
                    }
                }
            }
            else if (parent == null)
            {
                // Someone did "new InputControlSetup(...)" with a control template.
                // We don't support creating control hierarchies without a device at the root.
                throw new InvalidOperationException(
                          string.Format(
                              "Toplevel template used with InputControlSetup must be a device template; '{0}' is a control template",
                              template.name));
            }

            // Set common properties.
            if (name.IsEmpty())
            {
                name = template.name;
            }

            control.m_Name = name;
            control.m_DisplayNameFromTemplate = template.m_DisplayName;
            control.m_Template = template.name;
            control.m_Variant  = variant;
            control.m_Parent   = parent;
            control.m_Device   = m_Device;

            // Create children and configure their settings from our
            // template 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(template, 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 controlTemplate in template.controls)
                {
                    if (string.IsNullOrEmpty(controlTemplate.useStateFrom))
                    {
                        continue;
                    }

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

                    // Find the referenced control.
                    var referencedControl = TryGetControl(control, controlTemplate.useStateFrom);
                    if (referencedControl == null)
                    {
                        throw new Exception(
                                  string.Format(
                                      "Cannot find control '{0}' referenced in 'useStateFrom' of control '{1}' in template '{2}'",
                                      controlTemplate.useStateFrom, controlTemplate.name, template.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);
        }
コード例 #26
0
        /// <summary>
        /// Adds the default MVC templates.
        /// </summary>
        /// <param name="services">The services.</param>
        public static IServiceCollection AddDefaultMvcTemplates(this IServiceCollection services)
        {
            Guard.NotNull(services, nameof(services));

            // Reusable HTML attributes
            var multiple     = new { multiple = null as object };
            var noAttributes = null as object;
            var singleLine   = new Dictionary <string, object> {
                { Keys.HtmlClass, "text-box single-line" }
            };
            var multiLine = new Dictionary <string, object> {
                { Keys.HtmlClass, "text-box multi-line" }
            };
            var biState = new Dictionary <string, object> {
                { Keys.HtmlClass, "check-box" }
            };
            var triState = new Dictionary <string, object> {
                { Keys.HtmlClass, "list-box tri-state" }
            };
            var biStateDisabled = new Dictionary <string, object>(biState)
            {
                { Keys.HtmlDisabled, null }
            };
            var triStateDisabled = new Dictionary <string, object>(triState)
            {
                { Keys.HtmlDisabled, null }
            };

            // Reusable templates
            var numberInput = new InputTemplate("number", singleLine);
            var uriInput    = new InputTemplate("url", singleLine);
            var uriDisplay  = new AnchorTemplate("{0}", noAttributes);

            return(services

                   // By type name

                   .AddMvcTemplate(Purpose.Edit, nameof(String), new InputTemplate(null, singleLine))
                   .AddMvcTemplate(Purpose.Display, nameof(String), new StringTemplate())
                   .AddMvcTemplate(Purpose.Edit, nameof(Boolean), new BooleanTemplate(biState, triState))
                   .AddMvcTemplate(Purpose.Display, nameof(Boolean), new BooleanTemplate(biStateDisabled, triStateDisabled))
                   .AddMvcTemplate(Purpose.Edit, nameof(Byte), numberInput)
                   .AddMvcTemplate(Purpose.Edit, nameof(SByte), numberInput)
                   .AddMvcTemplate(Purpose.Edit, nameof(Int16), numberInput)
                   .AddMvcTemplate(Purpose.Edit, nameof(UInt16), numberInput)
                   .AddMvcTemplate(Purpose.Edit, nameof(Int32), numberInput)
                   .AddMvcTemplate(Purpose.Edit, nameof(UInt32), numberInput)
                   .AddMvcTemplate(Purpose.Edit, nameof(Int64), numberInput)
                   .AddMvcTemplate(Purpose.Edit, nameof(UInt64), numberInput)
                   .AddMvcTemplate(Purpose.Edit, nameof(BigInteger), numberInput)
                   .AddMvcTemplate(Purpose.Edit, nameof(Decimal), new InputTemplate("number", Formats.FormatAsDecimal, singleLine))
                   .AddMvcTemplate(Purpose.Display, nameof(Decimal), new StringTemplate(Formats.FormatAsDecimal))
                   .AddMvcTemplate(Purpose.Edit, nameof(Uri), uriInput)
                   .AddMvcTemplate(Purpose.Display, nameof(Uri), uriDisplay)
                   .AddMvcTemplate(Purpose.Edit, nameof(IFormFile), new InputTemplate("file", singleLine))
                   .AddMvcTemplate(Purpose.Edit, nameof(DateTime), new DateTimeTemplate("datetime-local", Formats.FormatAsLocal, singleLine))
                   .AddMvcTemplate(Purpose.Edit, nameof(DateTimeOffset), new DateTimeTemplate("text", Formats.FormatAsUTC, singleLine))
                   .AddMvcTemplate(Purpose.Edit, nameof(IEnumerable), new CollectionTemplate(Purpose.Edit))
                   .AddMvcTemplate(Purpose.Display, nameof(IEnumerable), new CollectionTemplate(Purpose.Display))
                   .AddMvcTemplate(Purpose.Edit, nameof(Object), new ObjectEditorTemplate())
                   .AddMvcTemplate(Purpose.Display, nameof(Object), new ObjectDisplayTemplate())

                   // By const name

                   .AddMvcTemplate(Purpose.Display, Names.Html, new HtmlTemplate())
                   .AddMvcTemplate(Purpose.Edit, Names.MultilineText, new TextAreaTemplate(0, 0, multiLine))
                   .AddMvcTemplate(Purpose.Edit, Names.EmailAddress, new InputTemplate("email", singleLine))
                   .AddMvcTemplate(Purpose.Display, Names.EmailAddress, new AnchorTemplate("mailto:{0}", noAttributes))
                   .AddMvcTemplate(Purpose.Edit, Names.Password, new InputTemplate("password", singleLine))
                   .AddMvcTemplate(Purpose.Edit, Names.PhoneNumber, new InputTemplate("tel", singleLine))
                   .AddMvcTemplate(Purpose.Edit, Names.Url, uriInput)
                   .AddMvcTemplate(Purpose.Display, Names.Url, uriDisplay)
                   .AddMvcTemplate(Purpose.Edit, Names.IFormFiles, new InputTemplate("file", multiple))
                   .AddMvcTemplate(Purpose.Edit, Names.IFormFilesLegacy, new InputTemplate("file", multiple))
                   .AddMvcTemplate(Purpose.Edit, Names.HiddenInput, new HiddenTemplate(renderInput: true))
                   .AddMvcTemplate(Purpose.Display, Names.HiddenInput, new HiddenTemplate(renderInput: false))
                   .AddMvcTemplate(Purpose.Edit, Names.Collection, new CollectionTemplate(Purpose.Edit))
                   .AddMvcTemplate(Purpose.Display, Names.Collection, new CollectionTemplate(Purpose.Display))
                   .AddMvcTemplate(Purpose.Edit, Names.Date, new DateTimeTemplate("date", Formats.FormatAsDate, singleLine))
                   .AddMvcTemplate(Purpose.Edit, Names.DateTimeLocal, new DateTimeTemplate("datetime-local", Formats.FormatAsLocal, singleLine))
                   .AddMvcTemplate(Purpose.Edit, Names.Time, new DateTimeTemplate("time", Formats.FormatAsTime, singleLine))
                   .AddMvcTemplate(Purpose.Edit, Names.Month, new DateTimeTemplate("month", Formats.FormatAsMonth, singleLine))
                   .AddMvcTemplate(Purpose.Edit, Names.Week, new DateTimeTemplate("week", Formats.FormatAsWeek, singleLine)
            {
                ForceRFC3339Rendering = true
            }));
        }
コード例 #27
0
            private TreeViewItem BuildItem(InputTemplate template, ref int id)
            {
                var item = new TreeViewItem
                {
                    id          = id++,
                    depth       = 1,
                    displayName = template.name
                };

                // Header.
                AddChild(item, "Type: " + template.type.Name, ref id);
                if (!string.IsNullOrEmpty(template.extendsTemplate))
                {
                    AddChild(item, "Extends: " + template.extendsTemplate, ref id);
                }
                if (template.stateFormat != 0)
                {
                    AddChild(item, "Format: " + template.stateFormat, ref id);
                }
                if (template.m_UpdateBeforeRender != null)
                {
                    var value = template.m_UpdateBeforeRender.Value ? "Update" : "Disabled";
                    AddChild(item, "Before Render: " + value, ref id);
                }
                if (template.commonUsages.Count > 0)
                {
                    AddChild(item,
                             "Common Usages: " +
                             string.Join(", ", template.commonUsages.Select(x => x.ToString()).ToArray()), ref id);
                }
                if (!template.deviceDescription.empty)
                {
                    var deviceDescription = AddChild(item, "Device Description", ref id);
                    if (!string.IsNullOrEmpty(template.deviceDescription.deviceClass))
                    {
                        AddChild(deviceDescription,
                                 "Device Class: " + template.deviceDescription.deviceClass, ref id);
                    }
                    if (!string.IsNullOrEmpty(template.deviceDescription.interfaceName))
                    {
                        AddChild(deviceDescription,
                                 "Interface: " + template.deviceDescription.interfaceName, ref id);
                    }
                    if (!string.IsNullOrEmpty(template.deviceDescription.product))
                    {
                        AddChild(deviceDescription, "Product: " + template.deviceDescription.product, ref id);
                    }
                    if (!string.IsNullOrEmpty(template.deviceDescription.manufacturer))
                    {
                        AddChild(deviceDescription,
                                 "Manufacturer: " + template.deviceDescription.manufacturer, ref id);
                    }
                }

                // Controls.
                if (template.controls.Count > 0)
                {
                    var controls = AddChild(item, "Controls", ref id);
                    foreach (var control in template.controls)
                    {
                        BuildItem(control, controls, ref id);
                    }

                    controls.children.Sort((a, b) => string.Compare(a.displayName, b.displayName));
                }

                return(item);
            }
コード例 #28
0
        private InputControl AddChildControl(InputTemplate template, InternedString variant, InputControl parent,
                                             ReadOnlyArray <InputControl>?existingChildren, ref bool haveChildrenUsingStateFromOtherControls,
                                             ref InputTemplate.ControlTemplate controlTemplate, ref int childIndex, string nameOverride = null)
        {
            var name          = nameOverride ?? controlTemplate.name;
            var nameLowerCase = nameOverride != null?nameOverride.ToLower() : controlTemplate.name.ToLower();

            var nameInterned = nameOverride != null ? new InternedString(nameOverride) : controlTemplate.name;

            ////REVIEW: can we check this in InputTemplate instead?
            if (string.IsNullOrEmpty(controlTemplate.template))
            {
                throw new Exception(string.Format("Template has not been set on control '{0}' in '{1}'",
                                                  controlTemplate.name, template.name));
            }

            // See if we have an existing control that we might be able to re-use.
            InputControl existingControl = null;

            if (existingChildren != null)
            {
                var existingChildCount = existingChildren.Value.Count;
                for (var n = 0; n < existingChildCount; ++n)
                {
                    var existingChild = existingChildren.Value[n];
                    if (existingChild.template == controlTemplate.template &&
                        existingChild.name.ToLower() == nameLowerCase)
                    {
                        existingControl = existingChild;
                        break;
                    }
                }
            }

            // Create control.
            InputControl control;

            try
            {
                control = AddControl(controlTemplate.template, variant, nameInterned, parent, existingControl);
            }
            catch (InputTemplate.TemplateNotFoundException exception)
            {
                // Throw better exception that gives more info.
                throw new Exception(
                          string.Format("Cannot find template '{0}' used in control '{1}' of template '{2}'",
                                        exception.template, controlTemplate.name, template.name),
                          exception);
            }

            // Add to array.
            m_Device.m_ChildrenForEachControl[childIndex] = control;
            ++childIndex;

            // Set display name.
            control.m_DisplayNameFromTemplate = controlTemplate.displayName;

            // Pass state block config on to control.
            var usesStateFromOtherControl = !string.IsNullOrEmpty(controlTemplate.useStateFrom);

            if (!usesStateFromOtherControl)
            {
                control.m_StateBlock.byteOffset = controlTemplate.offset;
                if (controlTemplate.bit != InputStateBlock.kInvalidOffset)
                {
                    control.m_StateBlock.bitOffset = controlTemplate.bit;
                }
                if (controlTemplate.sizeInBits != 0)
                {
                    control.m_StateBlock.sizeInBits = controlTemplate.sizeInBits;
                }
                if (controlTemplate.format != 0)
                {
                    SetFormat(control, controlTemplate);
                }
            }
            else
            {
                // Mark controls that don't have state blocks of their own but rather get their
                // blocks from other controls by setting their state size to kInvalidOffset.
                control.m_StateBlock.sizeInBits         = kSizeForControlUsingStateFromOtherControl;
                haveChildrenUsingStateFromOtherControls = true;
            }

            ////REVIEW: the constant appending to m_UsagesForEachControl and m_AliasesForEachControl may lead to a lot
            ////        of successive re-allocations

            // Add usages.
            if (controlTemplate.usages.Count > 0)
            {
                var usageCount = controlTemplate.usages.Count;
                var usageIndex =
                    ArrayHelpers.AppendToImmutable(ref m_Device.m_UsagesForEachControl, controlTemplate.usages.m_Array);
                control.m_UsagesReadOnly =
                    new ReadOnlyArray <InternedString>(m_Device.m_UsagesForEachControl, usageIndex, usageCount);

                ArrayHelpers.GrowBy(ref m_Device.m_UsageToControl, usageCount);
                for (var n = 0; n < usageCount; ++n)
                {
                    m_Device.m_UsageToControl[usageIndex + n] = control;
                }
            }

            // Add aliases.
            if (controlTemplate.aliases.Count > 0)
            {
                var aliasCount = controlTemplate.aliases.Count;
                var aliasIndex =
                    ArrayHelpers.AppendToImmutable(ref m_Device.m_AliasesForEachControl, controlTemplate.aliases.m_Array);
                control.m_AliasesReadOnly =
                    new ReadOnlyArray <InternedString>(m_Device.m_AliasesForEachControl, aliasIndex, aliasCount);
            }

            // Set parameters.
            if (controlTemplate.parameters.Count > 0)
            {
                SetParameters(control, controlTemplate.parameters);
            }

            // Add processors.
            if (controlTemplate.processors.Count > 0)
            {
                AddProcessors(control, ref controlTemplate, template.name);
            }

            return(control);
        }