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)); }
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)); }
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)); }
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)); }
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); }