static int Run(RunOptions options) { CheckFileList(options.files, ALLOWED_EXTENSIONS); // Create the object that handles callbacks var impl = new ConsoleRunnerImplementation(waitForLines: options.waitForInput); // load the default variables we got on the command line foreach (var variable in options.variables) { var entry = variable.Split(new char[] { '=' }, StringSplitOptions.RemoveEmptyEntries); float value; // If there aren't two parts to this or the second part isn't a float, fail if (entry.Length != 2 || float.TryParse(entry[1], out value) == false) { Warn(string.Format(CultureInfo.CurrentCulture, "Skipping invalid variable {0}", variable)); continue; } var name = entry[0]; impl.SetNumber(name, value); } if (options.automaticallySelectFirstOption == true) { impl.autoSelectFirstOption = true; } Dialogue dialogue = CreateDialogue(options, impl); // Run the conversation for (int run = 0; run < options.runTimes; run++) { foreach (var step in dialogue.Run(options.startNode)) { // It can be one of three types: a line to show, options // to present to the user, or an internal command to run if (step is Dialogue.LineResult) { var lineResult = step as Dialogue.LineResult; impl.RunLine(lineResult.line); } else if (step is Dialogue.OptionSetResult) { var optionsResult = step as Dialogue.OptionSetResult; impl.RunOptions(optionsResult.options, optionsResult.setSelectedOptionDelegate); } else if (step is Dialogue.CommandResult) { var commandResult = step as Dialogue.CommandResult; impl.RunCommand(commandResult.command.text); } } impl.DialogueComplete(); } return(0); }
public static void Main(string[] args) { if (args.Length == 0) { ShowHelpAndExit(); } bool showTokens = false; bool showParseTree = false; bool waitForLines = false; string onlyConsiderNode = null; bool showDebugging = false; int runTimes = 1; bool compileToBytecodeOnly = false; var inputFiles = new List <string> (); string startNode = Dialogue.DEFAULT_START; string[] allowedExtensions = { ".node", ".json" }; var defaultVariables = new Dictionary <string, float> (); foreach (var arg in args) { // Handle 'start' parameter if (arg.IndexOf("-s=") != -1) { var startArray = arg.Split(new char[] { '=' }); if (startArray.Length != 2) { ShowHelpAndExit(); } else { startNode = startArray [1]; continue; } } // Handle variable input if (arg.IndexOf("-v") != -1) { var variable = arg.Substring(2); var variableArray = variable.Split(new char[] { '=' }); if (variableArray.Length != 2) { ShowHelpAndExit(); } else { var varName = "$" + variableArray [0]; var varValue = float.Parse(variableArray [1]); defaultVariables [varName] = varValue; continue; } } // Handle 'only this node' parameter if (arg.IndexOf("-o=") != -1) { var startArray = arg.Split(new char[] { '=' }); if (startArray.Length != 2) { ShowHelpAndExit(); } else { onlyConsiderNode = startArray [1]; continue; } } // Handle 'run times' parameter if (arg.IndexOf("-r=") != -1) { var argArray = arg.Split('='); if (argArray.Length != 2) { ShowHelpAndExit(); } else { runTimes = int.Parse(argArray [1]); continue; } } switch (arg) { case "-t": showTokens = true; showDebugging = true; break; case "-p": showParseTree = true; showDebugging = true; break; case "-w": waitForLines = true; break; case "-d": showDebugging = true; break; case "-c": compileToBytecodeOnly = true; break; case "-h": ShowHelpAndExit(); break; default: // only allow one file if (inputFiles.Count > 0) { Console.Error.WriteLine("Error: Too many files specified."); Environment.Exit(1); } var extension = System.IO.Path.GetExtension(arg); if (Array.IndexOf(allowedExtensions, extension) != -1) { inputFiles.Add(arg); } break; } } if (inputFiles.Count == 0) { Console.Error.WriteLine("Error: No files specified."); Environment.Exit(1); } // Create the object that handles callbacks var impl = new ConsoleRunnerImplementation(waitForLines: waitForLines); // load the default variables we got on the command line foreach (var variable in defaultVariables) { impl.SetNumber(variable.Key, variable.Value); } // Load nodes var dialogue = new Dialogue(impl); // Add some methods for testing dialogue.library.RegisterFunction("add_three_operands", 3, delegate(Value[] parameters) { var f1 = parameters[0].AsNumber; var f2 = parameters[1].AsNumber; var f3 = parameters[2].AsNumber; return(f1 + f2 + f3); }); dialogue.library.RegisterFunction("last_value", -1, delegate(Value[] parameters) { // return the last value return(parameters[parameters.Length - 1]); }); dialogue.library.RegisterFunction("is_even", 1, delegate(Value[] parameters) { return((int)parameters[0].AsNumber % 2 == 0); }); // Register the "assert" function, which stops execution if its parameter evaluates to false dialogue.library.RegisterFunction("assert", 1, delegate(Value[] parameters) { if (parameters[0].AsBool == false) { // TODO: Include file, node and line number dialogue.LogErrorMessage("ASSERTION FAILED"); Environment.Exit(1); } }); // Register a function to let test scripts register how many // options they expect to send dialogue.library.RegisterFunction("prepare_for_options", 2, delegate(Value[] parameters) { impl.numberOfExpectedOptions = (int)parameters [0].AsNumber; impl.autoSelectOptionNumber = (int)parameters[1].AsNumber; }); dialogue.library.RegisterFunction("expect_line", 1, delegate(Value[] parameters) { impl.expectedNextLine = parameters[0].AsString; }); dialogue.library.RegisterFunction("expect_command", 1, delegate(Value[] parameters) { impl.expectedNextCommand = parameters[0].AsString; }); // If debugging is enabled, log debug messages; otherwise, ignore them if (showDebugging) { dialogue.LogDebugMessage = delegate(string message) { Console.WriteLine("Debug: " + message); }; } else { dialogue.LogDebugMessage = delegate(string message) {}; } dialogue.LogErrorMessage = delegate(string message) { Console.WriteLine("ERROR: " + message); }; dialogue.LoadFile(inputFiles [0], showTokens, showParseTree, onlyConsiderNode); if (compileToBytecodeOnly) { var result = dialogue.Compile(); Console.WriteLine(result); } // Only run the program when we're not emitting debug output of some kind var runProgram = showTokens == false && showParseTree == false && compileToBytecodeOnly == false; if (runProgram) { // Run the conversation for (int run = 0; run < runTimes; run++) { foreach (var step in dialogue.Run(startNode)) { // It can be one of three types: a line to show, options // to present to the user, or an internal command to run if (step is Dialogue.LineResult) { var lineResult = step as Dialogue.LineResult; impl.RunLine(lineResult.line); } else if (step is Dialogue.OptionSetResult) { var optionsResult = step as Dialogue.OptionSetResult; impl.RunOptions(optionsResult.options, optionsResult.setSelectedOptionDelegate); } else if (step is Dialogue.CommandResult) { var commandResult = step as Dialogue.CommandResult; impl.RunCommand(commandResult.command.text); } } impl.DialogueComplete(); } } }
public static void Main(string[] args) { if (args.Length == 0) { ShowHelpAndExit (); } bool showTokens = false; bool showParseTree = false; bool waitForLines = false; string onlyConsiderNode = null; bool showDebugging = false; int runTimes = 1; var inputFiles = new List<string> (); string startNode = Dialogue.DEFAULT_START; string[] allowedExtensions = {".node", ".json" }; var defaultVariables = new Dictionary<string,float> (); foreach (var arg in args) { // Handle 'start' parameter if (arg.IndexOf("-s=") != -1) { var startArray = arg.Split (new char[]{ '=' }); if (startArray.Length != 2) { ShowHelpAndExit (); } else { startNode = startArray [1]; continue; } } // Handle variable input if (arg.IndexOf("-v") != -1) { var variable = arg.Substring (2); var variableArray = variable.Split (new char[]{ '=' }); if (variableArray.Length != 2) { ShowHelpAndExit (); } else { var varName = "$" + variableArray [0]; var varValue = float.Parse (variableArray [1]); defaultVariables [varName] = varValue; continue; } } // Handle 'only this node' parameter if (arg.IndexOf("-o=") != -1) { var startArray = arg.Split (new char[]{ '=' }); if (startArray.Length != 2) { ShowHelpAndExit (); } else { onlyConsiderNode = startArray [1]; continue; } } // Handle 'run times' parameter if (arg.IndexOf("-r=") != -1) { var argArray = arg.Split ('='); if (argArray.Length != 2) { ShowHelpAndExit (); } else { runTimes = int.Parse (argArray [1]); continue; } } switch (arg) { case "-t": showTokens = true; showDebugging = true; break; case "-p": showParseTree = true; showDebugging = true; break; case "-w": waitForLines = true; break; case "-d": showDebugging = true; break; case "-h": ShowHelpAndExit (); break; default: // only allow one file if (inputFiles.Count > 0) { Console.Error.WriteLine ("Error: Too many files specified."); Environment.Exit (1); } var extension = System.IO.Path.GetExtension (arg); if (Array.IndexOf(allowedExtensions, extension) != -1) { inputFiles.Add (arg); } break; } } if (inputFiles.Count == 0) { Console.Error.WriteLine ("Error: No files specified."); Environment.Exit (1); } // Create the object that handles callbacks var impl = new ConsoleRunnerImplementation (waitForLines:waitForLines); // load the default variables we got on the command line foreach (var variable in defaultVariables) { impl.SetNumber (variable.Key, variable.Value); } // Load nodes var dialogue = new Dialogue(impl); // Add some methods for testing dialogue.library.RegisterFunction ("add_three_operands", 3, delegate(Value[] parameters) { var f1 = parameters[0].AsNumber; var f2 = parameters[1].AsNumber; var f3 = parameters[2].AsNumber; return f1+f2+f3; }); dialogue.library.RegisterFunction ("last_value", -1, delegate(Value[] parameters) { // return the last value return parameters[parameters.Length-1]; }); dialogue.library.RegisterFunction ("is_even", 1, delegate(Value[] parameters) { return (int)parameters[0].AsNumber % 2 == 0; }); // If debugging is enabled, log debug messages; otherwise, ignore them if (showDebugging) { dialogue.LogDebugMessage = delegate(string message) { Console.WriteLine ("Debug: " + message); }; } else { dialogue.LogDebugMessage = delegate(string message) {}; } dialogue.LogErrorMessage = delegate(string message) { Console.WriteLine ("ERROR: " + message); }; dialogue.LoadFile (inputFiles [0],showTokens, showParseTree, onlyConsiderNode); if (showTokens == false && showParseTree == false) { // Run the conversation for (int run = 0; run < runTimes; run++) { foreach (var step in dialogue.Run (startNode)) { // It can be one of three types: a line to show, options // to present to the user, or an internal command to run if (step is Dialogue.LineResult) { var lineResult = step as Dialogue.LineResult; impl.RunLine (lineResult.line); } else if (step is Dialogue.OptionSetResult) { var optionsResult = step as Dialogue.OptionSetResult; impl.RunOptions (optionsResult.options, optionsResult.setSelectedOptionDelegate); } else if (step is Dialogue.CommandResult) { var commandResult = step as Dialogue.CommandResult; impl.RunCommand (commandResult.command.text); } } impl.DialogueComplete (); } } }
public static void Main(string[] args) { if (args.Length == 0) { ShowHelpAndExit (); } bool showTokens = false; bool showParseTree = false; bool waitForLines = false; string onlyConsiderNode = null; bool showDebugging = false; int runTimes = 1; bool compileToBytecodeOnly = false; bool verifyOnly = false; bool autoSelectFirstOption = false; bool analyseOnly = false; var inputFiles = new List<string> (); string startNode = Dialogue.DEFAULT_START; string[] allowedExtensions = {".node", ".json" }; var defaultVariables = new Dictionary<string,float> (); foreach (var arg in args) { // Handle 'start' parameter if (arg.IndexOf("-s=") != -1) { var startArray = arg.Split (new char[]{ '=' }); if (startArray.Length != 2) { ShowHelpAndExit (); } else { startNode = startArray [1]; continue; } } // Handle variable input if (arg.IndexOf("-v") != -1) { var variable = arg.Substring (2); var variableArray = variable.Split (new char[]{ '=' }); if (variableArray.Length != 2) { ShowHelpAndExit (); } else { var varName = "$" + variableArray [0]; var varValue = float.Parse (variableArray [1]); defaultVariables [varName] = varValue; continue; } } // Handle 'only this node' parameter if (arg.IndexOf("-o=") != -1) { var startArray = arg.Split (new char[]{ '=' }); if (startArray.Length != 2) { ShowHelpAndExit (); } else { onlyConsiderNode = startArray [1]; continue; } } // Handle 'run times' parameter if (arg.IndexOf("-r=") != -1) { var argArray = arg.Split ('='); if (argArray.Length != 2) { ShowHelpAndExit (); } else { runTimes = int.Parse (argArray [1]); continue; } } switch (arg) { case "-V": verifyOnly = true; break; case "-t": showTokens = true; showDebugging = true; break; case "-p": showParseTree = true; showDebugging = true; break; case "-w": waitForLines = true; break; case "-d": showDebugging = true; break; case "-c": compileToBytecodeOnly = true; break; case "-1": autoSelectFirstOption = true; break; case "-h": ShowHelpAndExit (); break; case "-a": analyseOnly = true; break; default: // only allow one file if (inputFiles.Count > 0) { Console.Error.WriteLine ("Error: Too many files specified."); Environment.Exit (1); } var extension = System.IO.Path.GetExtension (arg); if (Array.IndexOf(allowedExtensions, extension) != -1) { inputFiles.Add (arg); } break; } } if (inputFiles.Count == 0) { Console.Error.WriteLine ("Error: No files specified."); Environment.Exit (1); } // Create the object that handles callbacks var impl = new ConsoleRunnerImplementation (waitForLines:waitForLines); // load the default variables we got on the command line foreach (var variable in defaultVariables) { impl.SetNumber (variable.Key, variable.Value); } // Load nodes var dialogue = new Dialogue(impl); // Add some methods for testing dialogue.library.RegisterFunction ("add_three_operands", 3, delegate(Value[] parameters) { return parameters[0]+parameters[1]+parameters[2]; }); dialogue.library.RegisterFunction ("last_value", -1, delegate(Value[] parameters) { // return the last value return parameters[parameters.Length-1]; }); dialogue.library.RegisterFunction ("is_even", 1, delegate(Value[] parameters) { return (int)parameters[0].AsNumber % 2 == 0; }); // Register the "assert" function, which stops execution if its parameter evaluates to false dialogue.library.RegisterFunction ("assert", -1, delegate(Value[] parameters) { if (parameters[0].AsBool == false) { // TODO: Include file, node and line number if( parameters.Length > 1 && parameters[1].AsBool ) { dialogue.LogErrorMessage ("ASSERTION FAILED: " + parameters[1].AsString); } else { dialogue.LogErrorMessage ("ASSERTION FAILED"); } Environment.Exit(1); } }); // Register a function to let test scripts register how many // options they expect to send dialogue.library.RegisterFunction ("prepare_for_options", 2, delegate(Value[] parameters) { impl.numberOfExpectedOptions = (int)parameters [0].AsNumber; impl.autoSelectOptionNumber = (int)parameters[1].AsNumber; }); dialogue.library.RegisterFunction ("expect_line", 1, delegate(Value[] parameters) { impl.expectedNextLine = parameters[0].AsString; }); dialogue.library.RegisterFunction ("expect_command", 1, delegate(Value[] parameters) { impl.expectedNextCommand = parameters[0].AsString; }); if (autoSelectFirstOption == true) { impl.autoSelectFirstOption = true; } // If debugging is enabled, log debug messages; otherwise, ignore them if (showDebugging) { dialogue.LogDebugMessage = delegate(string message) { Console.WriteLine ("Debug: " + message); }; } else { dialogue.LogDebugMessage = delegate(string message) {}; } dialogue.LogErrorMessage = delegate(string message) { Console.WriteLine ("ERROR: " + message); }; if (verifyOnly) { try { dialogue.LoadFile (inputFiles [0],showTokens, showParseTree, onlyConsiderNode); } catch (Exception e) { Console.WriteLine ("Error: " + e.Message); } return; } dialogue.LoadFile (inputFiles [0],showTokens, showParseTree, onlyConsiderNode); if (compileToBytecodeOnly) { var result = dialogue.GetByteCode (); Console.WriteLine (result); return; } if (analyseOnly) { var context = new Yarn.Analysis.Context (); dialogue.Analyse (context); foreach (var diagnosis in context.FinishAnalysis()) { Console.WriteLine (diagnosis.ToString(showSeverity:true)); } return; } // Only run the program when we're not emitting debug output of some kind var runProgram = showTokens == false && showParseTree == false && compileToBytecodeOnly == false && analyseOnly == false; if (runProgram) { // Run the conversation for (int run = 0; run < runTimes; run++) { foreach (var step in dialogue.Run (startNode)) { // It can be one of three types: a line to show, options // to present to the user, or an internal command to run if (step is Dialogue.LineResult) { var lineResult = step as Dialogue.LineResult; impl.RunLine (lineResult.line); } else if (step is Dialogue.OptionSetResult) { var optionsResult = step as Dialogue.OptionSetResult; impl.RunOptions (optionsResult.options, optionsResult.setSelectedOptionDelegate); } else if (step is Dialogue.CommandResult) { var commandResult = step as Dialogue.CommandResult; impl.RunCommand (commandResult.command.text); } } impl.DialogueComplete (); } } }