Пример #1
0
        public static HelpConfiguration ParseHelp(ITokenStream stream, ILogger logger, string suffix = "")
        {
            var key = "help" + suffix;

            if (!stream.Starts(key))
            {
                return(null);
            }

            string text           = null;
            var    inputHelpTexts = new List <InputHelpText>();

            while (true)
            {
                if (stream.Ends(key, logger, out var row, out var token0))
                {
                    break;
                }

                if (row.Length < 3 || row[1].Value != "=")
                {
                    logger?.WriteLine($"Error: Malformed assignment at {stream.Path}:{stream.Line}.");
                    stream.Move();
                    continue;
                }

                var rest = string.Join(" ", row.Skip(2));
                if (token0 == "text")
                {
                    text = rest;
                }
                else if (Enum.TryParse(token0, true, out HelpKey helpKey))
                {
                    inputHelpTexts.Add(new InputHelpText(helpKey, rest));
                }
                else
                {
                    logger?.WriteLine($"Warning: Invalid symbol '{token0}' at {stream.Path}:{stream.Line}.");
                }

                stream.Move();
            }

            return(new HelpConfiguration(text, inputHelpTexts));
        }
Пример #2
0
        public static ProfileConfiguration ParseProfile(ITokenStream stream, ILogger logger)
        {
            if (!stream.Starts("profile", logger, out var name))
            {
                return(null);
            }

            var bindings = new List <InputBinding>();

            while (true)
            {
                if (stream.Ends("profile", logger, out var row, out var token0))
                {
                    break;
                }

                if (row.Length < 4 || row[1].Value != "=")
                {
                    logger?.WriteLine($"Error: Malformed key binding at {stream.Path}:{stream.Line}.");
                    stream.Move();
                    continue;
                }

                if (token0 == "ls" || token0 == "rs")
                {
                    if (!string.Equals(row[2].Value, "map"))
                    {
                        logger?.WriteLine($"Error: Unknown analog mapping at {stream.Path}:{stream.Line}.");
                        stream.Move();
                        continue;
                    }

                    var stick = token0 == "ls" ? ThumbStick.Left : ThumbStick.Right;
                    switch (row[3].Value.ToLower())
                    {
                    case "mouse":
                        bindings.Add(new MouseMapping(stick));
                        break;

                    case "scroll":
                        bindings.Add(new ScrollMapping(stick));
                        break;

                    case "radial_menu":
                        bindings.Add(new RadialMenuMapping(stick));
                        break;

                    default:
                        logger?.WriteLine($"Error: Unknown analog mapping at {stream.Path}:{stream.Line}.");
                        break;
                    }

                    stream.Move();
                    continue;
                }

                if (!Enum.TryParse(token0, true, out InputKey inputKey))
                {
                    logger?.WriteLine($"Error: Unknown key '{token0}' at {stream.Path}:{stream.Line}.");
                }

                int end;
                switch (row[2].Value.ToLower())
                {
                case "map":
                    if (string.Equals(row[3].Value, "mod", StringComparison.OrdinalIgnoreCase))
                    {
                        bindings.Add(new ModMapping(inputKey));
                        break;
                    }

                    var keys = ParseKeyCodes(row, 3, out end);
                    if (keys == null)
                    {
                        logger?.WriteLine($"Error: Invalid key code(s) at {stream.Path}:{stream.Line}.");
                    }
                    else
                    {
                        if (end < row.Length)
                        {
                            logger?.WriteLine($"Warning: Ignored unknown symbols at {stream.Path}:{stream.Line}.");
                        }

                        bindings.Add(new KeyMapping(inputKey, keys));
                    }

                    break;

                case "press":
                    var action = ParseAction(row, 3, out end);
                    if (action == null)
                    {
                        logger?.WriteLine($"Error: Invalid action at {stream.Path}:{stream.Line}.");
                        break;
                    }

                    if (end < row.Length)
                    {
                        var nextToken = row[end];
                        if (string.Equals(nextToken.Value, "repeat", StringComparison.OrdinalIgnoreCase))
                        {
                            bindings.Add(new PressBinding(inputKey, action, true));
                        }
                        else if (string.Equals(nextToken.Value, "hold", StringComparison.OrdinalIgnoreCase))
                        {
                            end++;
                            if (end >= row.Length)
                            {
                                logger?.WriteLine($"Error: Expected action after 'hold' at {stream.Path}:{stream.Line}.");
                                break;
                            }

                            var holdAction = ParseAction(row, end, out end);
                            if (holdAction == null)
                            {
                                logger?.WriteLine($"Error: Invalid action at {stream.Path}:{stream.Line}.");
                                break;
                            }

                            if (end < row.Length)
                            {
                                logger?.WriteLine($"Warning: Ignored unknown symbols at {stream.Path}:{stream.Line}.");
                            }

                            bindings.Add(new PressHoldBinding(inputKey, action, holdAction));
                        }
                        else
                        {
                            logger?.WriteLine($"Error: Invalid symbol '{nextToken}' at {stream.Path}:{stream.Line}.");
                        }
                    }
                    else
                    {
                        bindings.Add(new PressBinding(inputKey, action, false));
                    }

                    break;

                default:
                    logger?.WriteLine($"Error: Unknown symbol '{row[2].Value}' at {stream.Path}:{stream.Line}.");
                    break;
                }

                stream.Move();
            }

            if (name == null)
            {
                return(null);
            }

            return(new ProfileConfiguration(name, bindings));
        }
Пример #3
0
        public static PageConfiguration ParsePage(ITokenStream stream, ILogger logger)
        {
            if (!stream.Starts("page"))
            {
                return(null);
            }

            HelpConfiguration help  = null;
            HelpConfiguration help2 = null;
            var bindings            = new List <CommandBinding>();
            var items = new List <MenuItemConfiguration>();

            while (true)
            {
                if (stream.Ends("page", logger, out var row, out var token0))
                {
                    break;
                }

                switch (token0)
                {
                case "help":
                    var h = ParseHelp(stream, logger);
                    if (h != null)
                    {
                        help = h;
                    }

                    continue;

                case "bind":
                    var binding = ParseCommandBinding(stream, logger);
                    if (binding != null)
                    {
                        bindings.Add(binding);
                    }

                    stream.Move();
                    continue;

                case "help2":
                    var h2 = ParseHelp(stream, logger, "2");
                    if (h2 != null)
                    {
                        h2.Orientation = Orientation.Horizontal;
                        help2          = h2;
                    }

                    continue;

                case "item":
                    var item = ParseMenuItem(stream, logger);
                    if (item != null)
                    {
                        items.Add(item);
                    }

                    continue;

                default:
                    logger?.UnexpectedLine(stream);
                    stream.Move();
                    continue;
                }
            }

            return(new PageConfiguration(help, help2, bindings, items));
        }
Пример #4
0
        public static MenuItemConfiguration ParseMenuItem(ITokenStream stream, ILogger logger)
        {
            if (!stream.Starts("item"))
            {
                return(null);
            }

            HelpConfiguration help  = null;
            HelpConfiguration help2 = null;
            var          bindings   = new List <CommandBinding>();
            string       name       = null;
            string       text       = null;
            List <Token> icon       = null;

            while (true)
            {
                if (stream.Ends("item", logger, out var row, out var token0))
                {
                    break;
                }

                if (token0 == "help")
                {
                    var h = ParseHelp(stream, logger);
                    if (h != null)
                    {
                        help = h;
                    }

                    continue;
                }

                if (token0 == "help2")
                {
                    var h2 = ParseHelp(stream, logger, "2");
                    if (h2 != null)
                    {
                        h2.Orientation = Orientation.Horizontal;
                        help2          = h2;
                    }

                    continue;
                }

                if (token0 == "bind")
                {
                    var binding = ParseCommandBinding(stream, logger);
                    if (binding != null)
                    {
                        bindings.Add(binding);
                    }

                    stream.Move();
                    continue;
                }

                if (row.Length < 3 || row[1].Value != "=")
                {
                    logger?.WriteLine($"Error: Malformed assignment at {stream.Path}:{stream.Line}.");
                    stream.Move();
                    continue;
                }

                var rest = string.Join(" ", row.Skip(2));
                switch (token0)
                {
                case "text":
                    text = rest;
                    break;

                case "icon":
                    icon = row.Skip(2).ToList();
                    break;

                case "name":
                    name = rest;
                    break;

                default:
                    logger?.UnexpectedLine(stream);
                    break;
                }

                stream.Move();
            }

            return(new MenuItemConfiguration(name, icon, text, bindings, help, help2));
        }
Пример #5
0
        public static MenuConfiguration ParseMenuConfiguration(ITokenStream stream, ILogger logger)
        {
            if (!stream.Starts("menu", logger, out var name))
            {
                return(null);
            }

            HelpConfiguration help  = null;
            HelpConfiguration help2 = null;
            var bindings            = new List <CommandBinding>();
            var pages = new List <PageConfiguration>();

            while (true)
            {
                if (stream.Ends("menu", logger, out var row, out var token0))
                {
                    break;
                }

                switch (token0)
                {
                case "bind":
                    var binding = ParseCommandBinding(stream, logger);
                    if (binding != null)
                    {
                        bindings.Add(binding);
                    }

                    stream.Move();
                    continue;

                case "help":
                    var h = ParseHelp(stream, logger);
                    if (h != null)
                    {
                        help = h;
                    }

                    continue;

                case "help2":
                    var h2 = ParseHelp(stream, logger, "2");
                    if (h2 != null)
                    {
                        h2.Orientation = Orientation.Horizontal;
                        help2          = h2;
                    }

                    continue;

                case "page":
                    var page = ParsePage(stream, logger);
                    if (page != null)
                    {
                        pages.Add(page);
                    }

                    continue;

                default:
                    logger?.UnexpectedLine(stream);
                    stream.Move();
                    continue;
                }
            }

            return(name != null ? new MenuConfiguration(name, help, help2, bindings, pages) : null);
        }